GNOME Bugzilla – Bug 611089
Accelerator for ctrl+space triggered when only space pressed in fr-oss layout
Last modified: 2014-08-20 19:06:52 UTC
Hello, This report follows https://bugs.launchpad.net/dreampie/+bug/525502 . In the fr-oss keyboard layout, an event which is supposed to be triggered by pressing ctrl+space is triggered by every press on space. To reproduce: Write this into a file (accel_bug.py, for example): ================== import gtk w = gtk.Window() ag = gtk.AccelGroup() def cb(*args): print 'hi' ag.connect_group(ord(' '), gtk.gdk.CONTROL_MASK, 0, cb) w.add_accel_group(ag) w.show_all() gtk.main() ================== If I just run python accel_bug.py, a window appears and whenever you press ctrl+space, "hi" is printed to the terminal. If before that I switch to fr-oss keyboard layout, by running setxkbmap fr oss then whenever I press the space key "hi" is printed, even without pressing ctrl. I run ubuntu karmic 9.10 on i386. Thanks, Noam
*** Bug 659129 has been marked as a duplicate of this bug. ***
This bug is linked to one specific feature of the keymap fr(oss): it inherits from nbsp(level4nl) which defines the space key as LOCAL_EIGHT_LEVEL, bearing the symbols space, no-break space in combination with Shift + AltGr and narrow no-break space in combination with Shift + Ctrl_Right. This bug does not reproduce when you load the keymap fr-oss using an option that loads another rule for the space key, for instance nbsp:level3n: $ setxkbmap -layout fr -variant oss -option nbsp:level3n I guess this bug would be reproducible with any keymap as long as the option nbsp:level4nl is used.
PS: I use Debian testing on amd64.
If the Ctrl+space shortcut is added with gtk_binding_entry_add_signal(), there is no problem. The bug occurs only with a GtkAccelGroup. That's why the Ctrl+space shortcut for showing the completion in GtkSourceView works well, because it uses gtk_binding. But if we add the same shortcut in a menu (with a GtkActionEntry), then the bug occurs, because a GtkAccelGroup is used. I attach two C programs. It's fairly easy to reproduce the bug, we just have to change the keyboard layout to "fr oss": > $ setxkbmap fr oss
Created attachment 196777 [details] Test with gtk_binding_entry_add_signal(), works well.
Created attachment 196779 [details] Test with GtkAccelGroup: bug It's the same as the Python code from the first comment, but in C language.
The problem comes from the _gtk_key_hash_lookup() function. I think there is a misuse of the consumed modifiers returned by gdk_keymap_translate_keyboard_state(). Here is the relevant code: > if (gdk_keymap_map_virtual_modifiers (key_hash->keymap, &modifiers) && > ((modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) || > (modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods))) In the case of a Ctrl+Space accelerator, and a simple space is pressed: - 'modifiers' is GDK_CONTROL_MASK (the modifiers of the accelerator). - 'state' is 0 (the modifiers of the GdkEventKey). - 'consumed_modifiers' has several modifiers activated, like GDK_SHIFT_MASK and GDK_LOCK_MASK. But here is the problem, with the fr oss keyboard layout, GDK_CONTROL_MASK is also present in consumed_modifiers, while it is not present with other keyboard layouts that most people use. With GDK_CONTROL_MASK present in consumed_modifiers, the if condition is true and the accelerator is activated. As described in the note of the documentation about gdk_keymap_translate_keyboard_state(), it seems that > modifiers & ~consumed_modifiers is not correct. It should be: > if (gdk_keymap_map_virtual_modifiers (key_hash->keymap, &modifiers) && > ((modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) || > (modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods))) Now the simple space doesn't trigger the ctrl+space accelerator. Nice! But there is another problem, now when we press ctrl+space, the accelerator is not triggered (with the fr oss layout). Indeed, the 'state' now contains GDK_CONTROL_MASK, but it is removed by the consumed modifiers. Maybe the bug comes from the gdk_keymap_translate_keyboard_state() function: does it return the correct consumed modifiers? In the case of Ctrl+space in fr oss, the keyval is the "normal" space character. So is it normal that GDK_CONTROL_MASK is present in consumed_modifiers? Also, it seems strange to me that the consumed_modifiers contains modifiers that are not present in the 'state'. According to the documentation: > An older interpretation consumed_modifiers was that it contained all > modifiers that might affect the translation of the key I'm maybe wrong, but it seems that the old interpretation is still the case. I use the X11 backend, so gdk_x11_keymap_translate_keyboard_state() is called.
Created attachment 219794 [details] [review] GtkKeyHash: fix misuse of consumed modifiers Use the new interpretation of the consumed modifiers returned by gdk_keymap_translate_keyboard_state().
I cannot reproduce this bug anymore with gtk+ 3.13.