Fix focus preservation after workspace switch
9f249ed5e7cc76f1b7f4b107f65b5828ee4c8eca
1 parent
4ce74dba
swm.c
+5 -3
| 5226 | 5226 | void view_workspace(workspace_t *ws, monitor_t *m) { |
|
| 5227 | 5227 | /* show workspace ws on output m; if ws is visible on another output, |
|
| 5228 | 5228 | * the two displays exchange workspaces. */ |
|
| 5229 | 5229 | monitor_t *other; |
|
| 5230 | 5230 | workspace_t *old; |
|
| 5231 | + | client_t *focus; |
|
| 5231 | 5232 | ||
| 5232 | 5233 | if (!m || !ws || ws == m->ws) |
|
| 5233 | 5234 | return; |
|
| 5234 | 5235 | old = m->ws; |
|
| 5235 | 5236 |
| 5243 | 5244 | assign_workspace(old, nullptr); |
|
| 5244 | 5245 | } |
|
| 5245 | 5246 | m->previous_workspace = old; |
|
| 5246 | 5247 | m->ws = ws; |
|
| 5247 | 5248 | assign_workspace(ws, m); |
|
| 5249 | + | focus = focus_top(m); |
|
| 5248 | 5250 | arrange(m); |
|
| 5249 | 5251 | ||
| 5250 | 5252 | if (other) |
|
| 5251 | 5253 | arrange(other); |
|
| 5252 | - | /* Arrange first, then transfer keyboard focus to the workspace's most |
|
| 5253 | - | * recently focused client. */ |
|
| 5254 | - | focus_client(focus_top(m), 1); |
|
| 5254 | + | /* Pointer focus can change during arrangement. Restore the workspace's |
|
| 5255 | + | * most recently focused client after its windows move. */ |
|
| 5256 | + | focus_client(focus, 1); |
|
| 5255 | 5257 | print_status(); |
|
| 5256 | 5258 | } |
|
| 5257 | 5259 | ||
| 5258 | 5260 | /* Send one workspace's ephemeral metadata to a control client. */ |
|
| 5259 | 5261 | static void workspace_metadata_send(struct wl_resource *resource, workspace_t *ws) { |
test/run.py
+20 -0
| 407 | 407 | eventually("third layout window removed", lambda: current_title() != "three-layout") |
|
| 408 | 408 | ||
| 409 | 409 | test("layouts and fullscreen", layouts) |
|
| 410 | 410 | ||
| 411 | 411 | def workspaces() -> None: |
|
| 412 | + | switcher = start_client("workspace-switcher", "8855ffdd") |
|
| 413 | + | virtual_keyboard(3, 1) |
|
| 414 | + | protocol("pointer", 100) |
|
| 415 | + | pointer_target = current_title() |
|
| 416 | + | virtual_keyboard(36) |
|
| 417 | + | active_target = current_title() |
|
| 418 | + | if active_target == pointer_target: |
|
| 419 | + | raise Failure("could not select the second workspace tile") |
|
| 420 | + | virtual_keyboard(3) |
|
| 421 | + | wait_title("workspace-switcher") |
|
| 422 | + | for _ in range(2): |
|
| 423 | + | virtual_keyboard(15) |
|
| 424 | + | wait_title(active_target) |
|
| 425 | + | virtual_keyboard(15) |
|
| 426 | + | wait_title("workspace-switcher") |
|
| 427 | + | virtual_keyboard(15) |
|
| 428 | + | wait_title(active_target) |
|
| 429 | + | terminate(switcher) |
|
| 430 | + | protocol("pointer", 100) |
|
| 431 | + | ||
| 412 | 432 | current = current_title() |
|
| 413 | 433 | virtual_keyboard(20) |
|
| 414 | 434 | virtual_keyboard(20) |
|
| 415 | 435 | virtual_keyboard(3, 1) |
|
| 416 | 436 | eventually("focus after moving client", lambda: current_title() not in {"", current}) |