Fix floating window screenshot selection
1fdf63d77e00705f25cc50e7cc2a211cf8a74197
1 parent
1d08f0a2
swm.c
+15 -7
| 4622 | 4622 | } |
|
| 4623 | 4623 | ||
| 4624 | 4624 | /* Publish visible window rectangles in slurp's predefined-region format. */ |
|
| 4625 | 4625 | void publish_windows(const char *runtime) { |
|
| 4626 | 4626 | client_t *c; |
|
| 4627 | + | bool floating; |
|
| 4627 | 4628 | FILE *file; |
|
| 4628 | 4629 | char path[MAX_STATE_PATH], tmppath[MAX_STATE_PATH], title[MAX_WINDOW_STATE_FIELD]; |
|
| 4629 | 4630 | ||
| 4630 | 4631 | if (!runtime || snprintf(path, sizeof(path), "%s/swm-windows", runtime) >= (int)sizeof(path) || |
|
| 4631 | 4632 | !(file = file_replace_begin(path, tmppath, sizeof(tmppath)))) |
|
| 4632 | 4633 | return; |
|
| 4633 | 4634 | ||
| 4634 | - | wl_list_for_each(c, &clients, link) { |
|
| 4635 | - | if (!c->mon || !client_surface(c)->mapped || !c->scene->node.enabled) |
|
| 4636 | - | continue; |
|
| 4637 | - | status_field(title, sizeof(title), client_get_title(c)); |
|
| 4638 | - | fprintf( |
|
| 4639 | - | file, "%d,%d %dx%d %s\n", c->geom.x, c->geom.y, c->geom.width, c->geom.height, title |
|
| 4640 | - | ); |
|
| 4635 | + | /* slurp resolves equal overlapping regions in input order. Publish the |
|
| 4636 | + | * floating layer last so its windows remain selectable above tiled windows. */ |
|
| 4637 | + | for (floating = false;; floating = true) { |
|
| 4638 | + | wl_list_for_each(c, &clients, link) { |
|
| 4639 | + | if (c->is_floating != floating || !c->mon || !client_surface(c)->mapped || |
|
| 4640 | + | !c->scene->node.enabled) |
|
| 4641 | + | continue; |
|
| 4642 | + | status_field(title, sizeof(title), client_get_title(c)); |
|
| 4643 | + | fprintf( |
|
| 4644 | + | file, "%d,%d %dx%d %s\n", c->geom.x, c->geom.y, c->geom.width, c->geom.height, title |
|
| 4645 | + | ); |
|
| 4646 | + | } |
|
| 4647 | + | if (floating) |
|
| 4648 | + | break; |
|
| 4641 | 4649 | } |
|
| 4642 | 4650 | file_replace_commit(file, tmppath, path); |
|
| 4643 | 4651 | } |
|
| 4644 | 4652 | ||
| 4645 | 4653 | /* Publish the status once the current batch of changes has settled. */ |
test/run.py
+10 -1
| 338 | 338 | ||
| 339 | 339 | one = start_client("one", "ff5588dd") |
|
| 340 | 340 | two = start_client("two", "ff55aa88") |
|
| 341 | 341 | ||
| 342 | 342 | def publication() -> None: |
|
| 343 | - | windows = (Path(os.environ["XDG_RUNTIME_DIR"]) / "swm-windows").read_text() |
|
| 343 | + | windows_path = Path(os.environ["XDG_RUNTIME_DIR"]) / "swm-windows" |
|
| 344 | + | windows = windows_path.read_text() |
|
| 344 | 345 | if not re.search(r"^\d+,\d+ \d+x\d+ one$", windows, re.MULTILINE): |
|
| 345 | 346 | raise Failure("missing published rectangle for one") |
|
| 346 | 347 | if not re.search(r"^\d+,\d+ \d+x\d+ two$", windows, re.MULTILINE): |
|
| 347 | 348 | raise Failure("missing published rectangle for two") |
|
| 349 | + | virtual_keyboard(36) |
|
| 350 | + | wait_title("one") |
|
| 351 | + | virtual_keyboard(20) |
|
| 352 | + | eventually( |
|
| 353 | + | "floating window publication order", |
|
| 354 | + | lambda: windows_path.read_text().index("two") < windows_path.read_text().index("one"), |
|
| 355 | + | ) |
|
| 356 | + | virtual_keyboard(20) |
|
| 348 | 357 | before = current_title() |
|
| 349 | 358 | virtual_keyboard(36) |
|
| 350 | 359 | wait_title("two" if before == "one" else "one") |
|
| 351 | 360 | ||
| 352 | 361 | test("window publication and focus", publication) |