GNOME Bugzilla – Bug 414947
Move "move-focus" signal to GtkWidget
Last modified: 2011-02-04 16:11:01 UTC
GTK has three widgets implementing a "move-focus" signal: GtkWindow, GtkTextView and GtkToolbar. Having this on GtkWidget would allow for much greater configurability of focus behavior on a per-container basis, which is esp. important for devices with restricted set of keys (e.g. no TAB key as on phones or on the Nokia 770/800). Moreover, it's ugly to have the same signal three times. Patch follows (which doesn't make things less ugly, but still...)
Created attachment 83970 [details] [review] Patch implementing the above
*** Bug 406082 has been marked as a duplicate of this bug. ***
Created attachment 86498 [details] [review] Updated patch Fixes a typo and a small (but crashing) bug in the previous patch.
Looks ok to me.
Comment on attachment 86498 [details] [review] Updated patch >@@ -1921,19 +1912,20 @@ gtk_toolbar_focus_home_or_end (GtkToolba > /* Keybinding handler. This function is called when the user presses > * Ctrl TAB or an arrow key. > */ >-static gboolean >-gtk_toolbar_move_focus (GtkToolbar *toolbar, >+static void >+gtk_toolbar_move_focus (GtkWidget *widget, > GtkDirectionType dir) Mitch, i have a slight recollection of you stating via IM that this void<->gboolean switch could indicate a problem. is there anything problematic about it or can the patch go in?
Indeed, however it's not a crasher problem as i first thought, since removing the boolean return value will simply leave direct callers of g_signal_emit() with a random return value and won't write to random memory. Moreover, this is a binding signal that shouldn't be called by any application code anyway. However, this changes the focus behavior of toolbars. I'm investigating how exactly, it seems to be pretty weird.
Hm, I tried gedit's toolbar with both upstream and my hacked GTK+, and the difference in behavior is marginal. It would help though if somebody explained to me how it is supposed to behave. Both versions don't make very much sense to me :)
I think Soeren is the best person to answer that.
As I recall, toolbar keyboard navigation is supposed to work like this: * Toolbars are in the normal focus chain - ie., you can tab to them, or, if the currently focused widgets uses tab for other purposes, ctrl-tab to them. - this is broken with many applications since their main areas swallow both tab and ctrl tab * When focus is on the toolbar, focus can be moved between items with arrows. For items, such as entries, that swallow arrow presses, ctrl-tab should move to the next item. * When focus is put on the toolbar, the item that had focus the last time should get it again. Eg., if you put the focus on toolbar item 2, then tab out of the toolbar, then tab back in, item 2 should get focus again.
Here are my old notes on behavior: The current consensus is put the first item of each toolbar in the regular TAB focus chain. Then when a toolbar item has focus, the arrow keys move focus from around on the toolbar. For toolbar items that use the arrow keys for other purposes, GtkEntry mainly, Ctrl-TAB should move focus to the next toolbar item. When the toolbar has a handle, ie., is inside a GtkHandlebox, the first item on the toolbar should still get focus when you TAB into the toolbar, but then left arrow should move focus to the handle. Focus does not wrap around, and Home and End should work. Wrt. the boolean return, I think FALSE means "let the parent handle it", and TRUE means "I handled it; don't let other widgets see it".
This code is from gtkbindings.c: if (query.return_type == G_TYPE_BOOLEAN) { if (g_value_get_boolean (&return_val)) handled = TRUE; g_value_unset (&return_val); } else handled = TRUE; So if the signal in question has a non-boolean return type, the signal is always considered handled. For the toolbar having all keypresses considered handled would be a problem as keypresses "leaving" the toolbar would no longer be handled by the parent but instead be 'stuck' inside the toolbar. This means keyboard navigation between two toolbars next to each other would no longer work, and that it would no longer be possible to focus toolbar handles.
I'm aware of that, but try the patch. I can leave toolbars even with the patch. It only behaves slightly differently, and I'm pretty sure we can fix that. I would really like to get that patch in before the freeze.
Comitted to trunk: 2007-06-04 Michael Natterer <mitch@imendio.com> Move "move-focus" signals from several widgets to GtkWidget to enable more flexible costomization of keyboard navigation via bindings. Fixes bug #414947. * gtk/gtkwidget.c: add "move-focus" binding signal, default to calling the toplevel GtkWindow's "move-focus" vfunc. * gtk/gtktextview.[ch] * gtk/gtkwindow.[ch]: remove "move-focus" signals and add compat code that makes sure that both emitting the signal on the widget and overriding the virtual functions keeps working as before. * gtk/gtktoolbar.c: remove "move-focus" signal here too and use GtkWidget's signal. This change slightly changes keyboard navigation in toolbars. I'll fix the behavior if somebody can explain me if and how exactly the new behavior is broken.