GNOME Bugzilla – Bug 97635
sticky windows always keep focus when switching workspaces
Last modified: 2004-12-22 21:47:04 UTC
Problem: When using sticky windows, it's not possible to have a sane focusing of windows when changing workspaces How to reproduce: - Launch an application (X) on workspace 1, and set it to sticky state ("Put on all workspaces") - Launch another application (Y) on workspace 1 and give it the focus - Switch workspace 2 - Go back to workspace 1, X is focused... Should have been Y Explanation: The focus is set using the window stack, but the stack is global for all the workspaces. If a sticky window gets the focus in one workspace it will be considered as being focused on every workspace. Because of this it's impossible to have another window focused when switching workspaces. Effect: This bug causes a serious trouble when doing most of the operations using the keyboard only: if you change the workspace you have to manually cycle through all the windows in order to focus the one you were working on... Note: Only tested in click-to-focus mode, metacity 2.4.3 I hope this report is clear enough, and that it will soon be fixed... Cheers, Patrick
But Y should be stacked above sticky window X, right? Something is going wrong there I guess.
At step 2, Y is stacked above X... But when proceeding to step 3 the sticky window (X) gets the focus because it's the only non-dock application... So this one goes on top of the stack... The bad thing is that this change is also reflected on workspace 1, so when you go back to the first workspace the X application is focused because it was focused on workspace 2...
I see. So the two possible fixes are to track focused windows for each workspace separate from stacking, or to change what happens when raising a window so that it only raises the window above other windows on the same workspace.
*** Bug 104002 has been marked as a duplicate of this bug. ***
*** Bug 107459 has been marked as a duplicate of this bug. ***
Perhaps "track focused windows separate from stacking" means "use the mru_list in MetaDisplay to decide which window to focus next, instead of using the topmost window" For a single workspace, that won't change anything in theory for click to focus (stack order = mru order), but would fix this bug in click to focus. I'm not sure what kind of weirdness it would cause in mouse focus.
> "use the mru_list in MetaDisplay to decide which window to focus > next, instead of using the topmost window" The problem with that is the sticky window should get focus in workspace 2 and when it does, then it will be at the top of the MRU list, so it will get focus when you switch back to workspace 1. One solution is to maintain per workspace MRU lists. Having per workspace MRU lists may have other advantages, too. It seems pretty natural to base Alt-Tab on the current workspace's MRU list, for instance. At any rate, I'll attach a patch that seems to fix the bug using per workspace MRU lists. The patch has one issue I am worried about, and that is it assumes the workspace that a window is focused on will always be the active workspace. I'm not sure if that will always be true.
Created attachment 16932 [details] [review] Implement focusing of windows after workspace switching with MRU lists.
Created attachment 19129 [details] [review] Updated to apply to cvs HEAD
Does display->mru_list become cruft with this patch? My main question there is, in the functions that find the next window in the tab chain, when is the workspace NULL? In that case we may need display->mru_list. If there's no such case we should clean up display->mru_list
> Does display->mru_list become cruft with this patch? Not with the current patch, but I think that display->mru_list could be removed if the functions that find the next window in the tab chain were rewritten to use the new per workspace MRUs. I didn't do this in the original patch, but since display->mru_list isn't used for anything else now, I think it may be a good idea to do so (Like I said before, it seems sort of natural). > My main question there is, in the functions that find the > next window in the tab chain, when is the workspace NULL? I'm not entirely sure I understand your question. When you pass NULL for workspace in the function that gets the tab window list, it returns a list of all windows from every workspace (versus all the windows on the specified workspace, when workspace isn't NULL). If display->mru_list were removed then that behavior would be hard to maintain. Are you asking if that behavior is currently needed? I don't think so. From what I see, in the various tabbing related functions, workspace is always screen->active_workspace. > If there's no such case we should clean up display->mru_list I can write a patch to get rid of it this weekend if you want.
> Are you asking if that behavior is currently needed? Yes. If you could enhance the updated patch I attached to get rid of display->mru_list, that would be cool.
Created attachment 19246 [details] [review] Updated to removed global mru list
Thanks a lot. This looks good to commit with ChangeLog entry.
Okay, I've commited it: 2003-08-15 Ray Strode <halfline@hawaii.rr.com> Changed MRU list to be per workspace instead of per display, so sticky windows don't hijack the window focus after workspace switching (Bug #97635). * src/delete.c (meta_window_delete): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window. * src/display.c (meta_display_open): Stop using display->mru_list. (find_tab_forward): (find_tab_backward): (meta_display_get_tab_list): Use workspace->mru_list instead of display->mru_list and remove unneeded calls to meta_window_visible_on_workspace * src/display.h: Remove mru_list from MetaDisplay * src/keybindings.c (handle_toggle_desktop): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window. * src/screen.c (meta_screen_focus_top_window): (meta_screen_focus_default_window): Remove functions. (meta_screen_show_desktop): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window. * src/screen.h: Remove meta_screen_focus_top_window and meta_screen_focus_default_window declarations. * src/window.c (meta_window_new): Stop using display->mru_list. (meta_window_free): Use meta_workspace_focus_top_window instead of meta_screen_focus_top_window and stop using display->mru_list. (meta_window_stick): Add sticky window to all workspace MRU lists. (meta_window_unstick): Remove non-sticky window from the workspace MRU lists it doesn't belong in. (meta_window_notify_focus): Move newly focused window to the front of active workspace's MRU list. * src/workspace.c (meta_workspace_new): Initialize workspace->mru_list to NULL. (meta_workspace_add_window): Add window to workspace's MRU list. (meta_workspace_remove_window): Remove window from workspace's MRU list. (meta_workspace_activate_with_focus): Use meta_workspace_focus_default_window instead of meta_screen_focus_default_window. (meta_workspace_focus_default_window): (meta_workspace_focus_mru_window): (meta_workspace_focus_top_window): Add functions. * src/workspace.h: Add mru_list to MetaWorkspace and add function declarations for meta_workspace_focus_default_window, meta_workspace_focus_mru_window, meta_workspace_focus_top_window. 2003-08-14 Rob Adams <robadams@ucla.edu> Allow windows that are too tall for the workarea to break the onscreen constraints just enough so that their bottom edges can be made visible. Fix for #106740. Also, changes constraints to constrain the resize and then the move to avoid complexities in the code for the above fix. * src/constraints.c (get_outermost_onscreen_positions) Compute the "effective" height of the work area and the minimum size for the window to compute a value by which a window is allowed to violate the top constraint. (meta_window_constrain): convert to a resize then a move instead of a move then resize.
closing bug