GNOME Bugzilla – Bug 94682
Alt-F6 should cycle between windows in same application
Last modified: 2006-07-05 13:59:38 UTC
Now that we have the CUA-compliant window manager shortcuts for most things, it would be nice if we could have another one: [Shift-]Alt-F6 to cycle between windows in the same application/group. Hopefully this shouldn't be too hard as the top-level window grouping is already possible in the window list... presumably it shouldn't be any harder to include a group's child windows as well when cycling through them with Alt-F6? :)
Should be pretty easy, the only hard part is defining "group" - right now the task list grouping is based on process (in essence), i.e. windows in the same application instance are grouped. But this isn't what people seem to expect, so we were thinking of grouping by window class/name instead. My feeling is that Alt+F6 should be based on application instance, not window type. Though perhaps also my feeling is that in general these two things should coincide, although they don't always at the moment... There's a libwnck bug about the basis for grouping windows.
Discussion on mailing list is that "group" for Alt+F6 refers to a toplevel window plus its transients. The reason is that Alt+Tab moves through "groups" by this definition.
An additional keybinding which many people would like for this feature: Apple uses Apple-Tab for app switching and Apple-~ for window switching. They're close together, and very handy. On the topic of 'what to switch', in my experience, this means "switching between windows of a particular application" such as browser, document or terminal windows. HP says that "toplevel windows and their transients" doesn't cover this. :-)
Updating status_whiteboard field to reflect A11Y team's assessment of accessibility impact.
OK, so do we want this to cycle between: - all toplevel document windows - a toplevel document window and each of its dialogs/palettes/whatever - union of all toplevel document windows and all dialogs in the same "application" (= same process ID) Should Alt+Tab then be changed to move between the groups that this moves between, rather than between windows? That is, should we remember the last-focused window in each group and Alt+Tab goes between groups? Should the tasklist then do the same as Alt+Tab?
Apologies for spam... marking as GNOMEVER2.3 so it appears on the official GNOME bug list :)
This is from a draft of the model document I've been working on: Navigation between windows The mouse user can move to any window by clicking on it, unless the window has a related modal window showing. When a modal window is showing, attempts to focus any window for which it is modal will instead focus the modal window. The keyboard user can traverse: primary windows by pressing Alt+Tab or Alt+Esc, secondary windows by pressing Alt+F6 from a related window, and special features by pressing Ctrl+Alt+Tab or Ctrl+Alt+Esc. Holding Shift while using any of these combinations will reverse the traversal direction. The Tab combinations will show a small borderless window indicating the windows which may be traversed with the combination in order appropriate to the user's reading direction. The window to be focused on release will also be indicated by its outline. Only the finally focussed window will be raised during traversal. The Esc combinations will respond like the Tab combination, but they will not show the small borderless window, and they will raise windows during traversal. The Alt+F6 combinations will respond like the Esc combinations. The keyboard connections between windows are like interlocking rings. The windows in the window list (primary windows) form the central ring. From anywhere, pressing Alt+Tab will move along the central ring. Connected to the central ring at each window is a ring of secondary windows. Sometimes a window, such as a palette, will be on more than one ring because it is related to multiple windows. From any window on the central ring, pressing Alt+F6 will move to a window on the ring of secondary windows. From the secondary window ring, pressing Alt+F6 will move to another window on the ring or back to the connected window on the central ring. Pressing Alt+Tab while in a secondary ring window move first to the connected window, then pressing Tab with Alt still held down will move through the central ring as usual. Not included in this excerpt: - minimized and shaded windows keep their usual places in traversal order. Hidden windows (does GNOME use these?) are hidden from traversal order. - secondary windows are transients and transients are secondary windows. - "special features" are the desktop, docks (er, panels), and other non-transient, unlisted windows. (Maybe multihead screens too?) - keyboard traversal order is equivalent to last focus order within a ring. It's almost the same as stacking order. - the reasons: - for method: - previous user experience (Windows, OS/2) - Tab is a control traversal key - F6 is a pane (subwindow) traversal key - Alt+ combos are often toplevel parallels to in-window keys - for existence: clutter control. including secondaries and special features in one traversal ring would make keynav tediously difficult. - for not mentioning WM_HINTS.window_group: the interpretation still isn't set, afaict. - for not mentioning applications: I'm not describing the crappy crufty archaic models of Apple and Microsoft. - if a combo is really needed to move between primary windows of an application, then use Ctrl+F6 as a limited version of Alt+Tab. It's the combo used in Microsoft MDI to switch between subwindows. Adding this should change nothing from the description I gave above. Alt+Tab should still traverse all primary windows as if applications did not exist. Having three traversal rings is already complicated enough. Did I miss anything?
This can also be handled by applications, because the KeyPress/Release events provide timestamps which can be used for SetInputFocus. This is surely a simpler solution, but needs a way to make the keybinding standard for all apps. A property on the WM_Sn owner could let applications check this and other keybindings. This would also allow them to adjust their own keybindings to avoid those grabbed by the WM.
Apologies for spam-- ensuring Sun a11y team are cc'ed on all current a11y bugs. Filter on "SUN A11Y SPAM" to ignore.
This appears to be needed to allow keyboard navigation (see bug 309481), so the severity is not enhancement anymore...
Created attachment 60090 [details] [review] Patch to introduce cycling between windows of the same group on alt-f6 Here's a first draft of a possible solution. What do people think of this?
Created attachment 60091 [details] [review] Introduce cycling between windows of the same group on alt-f6 Hm, left in some old testing code. Try that again.
I think you're looking in all the right places, so it looks like a good start. I'd have to test and look closer to be sure, but I'll at least mention the things I did notice (besides the fact that I thought some other things were going to have to be fixed and your patch makes it look like that won't be necessary after all) : META_WINDOW_IN_NORMAL_TAB_CHAIN_AND_GROUP needs to be renamed and redefined; META_WINDOW_IN_TAB_CHAIN excludes windows with the skip taskbar hint (e.g. dialogs) and part of the point of Alt+F6 is to explicitly handle those so that they don't need to clutter the normal Alt+Tab choices. It's cool that you handled the rare GConf-compiled-out case in the prefs.c code you modified. To handle the GConf case, there are a couple example patches you could probably look at. [/me looks up a couple bug numbers...] See the prefs.c, prefs.h, and metacity.schemas.in portion of the patch from bug 326156 to see an example of handling gconf stuff. Bug 154232 and bug 308106 can also be looked at for examples. I'd rather use display->focus_window (or maybe display->expected_focus_window?) rather than the workspace mru_list in get_focused_group(). I find it odd that you have added a META_GRAB_OP_KEYBOARD_ESCAPING_GROUP but not an META_GRAB_OP_KEYBOARD_TABBING_GROUP; granted, I haven't looked closely at the code recently, but is there a reason the latter isn't needed? As always, thanks for working on this. :)
Thanks, I'll look into all that and make changes. I added the escaping but not tabbing group merely because the original request was for an escaping function: you're right, though, it would make sense to implement both (and maybe just leave the tabbing disabled by default).
I'm not sure I understand your second point, about the GConf case in prefs.c. I can see how to add new GConf prefs to prefs.c from the patches you supplied, but it seems to me that screen bindings like the ones we're adding only need to be added to the screen_bindings array to be put into screen_string_bindings by init_bindings(). Is there more to it than that? I've made the other changes you suggested, and when I get this fixed I'll attach a new patch.
screen_string_bindings doesn't exist if HAVE_GCONF is true (the default), thus modifying it doesn't do a anything except on those embedded systems for which gconf support has been compiled out. That string array is merely a way used to allow some kind of keybinding to be set at compile time for such very-low-resource-usage systems. Even if this mechanism were modified to be used when HAVE_GCONF is true, it wouldn't be acceptable because it's a mechanism that hardcodes the keybinding. It's probably lame that the mechanisms we have for registering new keybindings for non-gconf (most likely meaning "embedded") systems is totally different than for typical systems, which is my fault, but the screen_string_bindings stuff seemed like the simplest addition when I was trying to fix the no-gconf-means-no-keybindings thing a few months ago.
I see I was confused. Sorry about that. What I think I meant to say was: I can see from the bugs you mentioned that there's a certain way of handling GConf prefs within prefs.c. It seems to me that init_bindings appears to handle them for prefs which represent key bindings, by iterating over the window_bindings and screen_bindings arrays (not screen_string_bindings, which I was confused about) and calling update_binding with the results. Since all the prefs we're adding are key bindings, it seems reasonable to me that what needs to be done is to add them to screen_bindings and we'll have handled the GConf case.
Oh, right. It looks like all my examples for adding gconf prefs were kinda off-topic since I forgot about screen_bindings being pretty automated. Anyway, yeah, looks like you've got it figured out. :-)
Created attachment 61112 [details] [review] Introduce cycling between windows of the same group on alt-f6, version two (The Keybinding Strikes Back) Okay, great! Here's a version taking into account your comments earlier, then.
I tried your patch but it seems like nothing happens when you press Alt+F6. Am I doing something wrong?
Try setting /apps/metacity/global_keybindings/cycle_group or /apps/metacity/global_keybindings/switch_group to "<Alt>F6" in gconf-editor.
Silly me. With that option set it works like a charm, very cool. But I wonder why Alt+F6 only shows the "border feedback" effect. It's like Alt+Tab without the popup. Have you considered instanteous window cyckling like Alt+Esc? Maybe it would be more appropriate?
Well, the way it's designed to work (and the way it's actually working for me, here) is that cycle_group is supposed to do instantaneous window cycling like alt-Esc, and switch_group is supposed to only show the "border feedback" effect (and the popup), like alt-Tab. I can't replicate the behaviour you see, with only the border feedback, no window cycling, and no popup.
Sweet, it's looking pretty good. - You've broken your fix from bug 141425 now. ;-) Try Alt-tabbing a few times, don't let go of alt, then press Alt-F6. Instead of switching between windows in the group of the focused window, the Alt-F6 is treated just like another Alt-Tab. Same if Alt-Esc'ing was done. We may not want to actually cancel, though; if someone is trying to get to the dialog of some other window, it'd be handy to be able to Alt-tab to the parent window and then Alt-F6 to the transient. - You need to patch src/metacity.schemas.in too so that the gconf keys can be installed. - In the line of code return ((MetaWindow*)display->focus_window)->group; display->focus_window is already a MetaWindow; the typecast is unnecessary. Björn: Thanks for helping with the testing. :) I think the border feedback "without window cycling" and no popup could be explained by the fact that transients are always stacked above the window they are the parent of so it merely just doesn't look like there's window cycling when there really is. Could you verify?
True that Elijah, I forgot that transients are always stacked above the main window. cycle_group really is like Alt+Esc and switch_group like Alt+Tab. IMHO the switch_group function is strictly superior to cycle_group because you get BOTH border feedback and a popup. Instanteous cycling isn't so important in this case because the window you cycle to isn't raised anyway. But I think I have found some problems with the patch. Open gnome-terminal, then open the preferences window, then go to the colors tab and click on a color in the palette. Now you have three windows in the gnome-terminal group: The main "gnome-terminal" window, the "Edit profile" window and a color selector window. Using Alt+F6 you can switch between "Edit profile" and the main window, but you can neither switch to or from the color selector window. Another way to see the same problem is to click the help menu of a GNOME program, then select About and then click the Thanks button. The Thanks window seems to not be included in the same group as the main program. This problem doesn't seem to be the patchs fault, just something that becomes visible with this new feature. Is it something that can be fixed somehow?
See also the patch on Bug #336184
I added some more info to bug 336184 about the grouping problems. To follow up on comment 24, I think we want switch_group to be bound to <Alt>F6 by default whereas cycle_group should be unbound (stuff defined in metacity.schemas.in). Thanks for all the work Thomas & Björn! :-)
*** Bug 336886 has been marked as a duplicate of this bug. ***
Created attachment 62742 [details] [review] alt-f6 patch version three, taking into account Elijah's suggestions (In reply to comment #24) > Sweet, it's looking pretty good. > > - You've broken your fix from bug 141425 now. ;-) Try Alt-tabbing a few > times, don't let go of alt, then press Alt-F6. Instead of switching between > windows in the group of the focused window, the Alt-F6 is treated just like > another Alt-Tab. Same if Alt-Esc'ing was done. Oops. Fixed. > We may not want to actually > cancel, though; if someone is trying to get to the dialog of some other window, > it'd be handy to be able to Alt-tab to the parent window and then Alt-F6 to the > transient. I spent a while trying to get this to work, but you need to kill the current tabpopup and start a new one, and the code for this checks the currently focussed window. So you need to end the grab, give the parent window focus, and then start the new grab, and there doesn't seem to be a neat way to do this (or indeed a non-neat way that I could find). If I figure anything out I'll raise a separate bug.
This new patch breaks alt-esc; it seems that alt-esc is cancelling itself or something?
Created attachment 63416 [details] [review] Introduce cycling between windows of the same group on alt-f6, version four (now with added switch) Ah, well spotted. I'd missed a "break" in a switch statement. Here's a fixed version.
There's still one tiny bug left -- whenever an alt-esc action is cancelled, the corresponding window should be returned to it's original stacking order. Your current patch leaves it raised if it's cancelled by pressing alt+f6. However, I'd like to open up a new bug and make it so that Alt+F6 can be used combined with either Alt+Tab or Alt+Esc (so that e.g. Alt-Tab-Tab-Tab-F6 or Alt-Esc-Esc-F6-Esc would both be valid). This would allow mixing either tab or esc (but not both) with F6 without cancelling the window switch operation, much like how Ray made it possible to change the keyboard resize grab_op type in bug 310888 (see process_keyboard_resize_grab_op_change()). (Two more sidenotes, since I'm too lazy to file the bug but don't want to forget: (1) I'd also like to make Alt+F6 more discoverable (e.g. by hinting about it in the tabpopup when using Alt+Tab or Alt+Esc), (2) Alt-Tab can't switch to all windows in a group since some have skip_taskbar=true; however, we should select the most recently used one. That'll fix another bug in bugzilla that I don't want to look up the # for at the moment). I believe that doing this extra work would fix the last issue in your patch as a side effect, so I think we can ignore the issue for now. Thanks!
Wonderful! Okay, committed. -> FIXED
I opened bug 338660 about the remaining and related issues (usability feedback from usability-maint@ on that bug welcome)
*** Bug 346599 has been marked as a duplicate of this bug. ***