Hi,
On 03/06/2012 06:13 PM, Roland Stigge wrote:
> this bug is well reproducible, while looking around in the github code,
> I couldn't find a commit that fixes the problem, unfortunately.
The fixes from the github branch "wip-fix-xkb" fix it for me. :-)
I backported them, attaching the patch for the Debian package.
Roland
--- keybinder-0.2.2.orig/libkeybinder/keybinder.h
+++ keybinder-0.2.2/libkeybinder/keybinder.h
@@ -32,6 +32,8 @@ typedef void (* KeybinderHandler) (const
void keybinder_init (void);
+void keybinder_set_use_cooked_accelerators (gboolean use_cooked);
+
gboolean keybinder_bind (const char *keystring,
KeybinderHandler handler,
void *user_data);
--- keybinder-0.2.2.orig/libkeybinder/bind.c
+++ keybinder-0.2.2/libkeybinder/bind.c
@@ -71,6 +71,8 @@ struct Binding {
static GSList *bindings = NULL;
static guint32 last_event_time = 0;
static gboolean processing_event = FALSE;
+static gboolean detected_xkb_extension = FALSE;
+static gboolean use_xkb_extension = FALSE;
/* Return the modifier mask that needs to be pressed to produce key in the
* given group (keyboard layout) and level ("shift level").
@@ -191,13 +193,15 @@ grab_ungrab (GdkWindow *rootwin,
int k;
GdkKeymapKey *keys;
gint n_keys;
- GdkModifierType add_modifiers;
- XkbDescPtr xmap;
+ GdkModifierType add_modifiers = 0;
+ XkbDescPtr xmap = NULL;
gboolean success = FALSE;
- xmap = XkbGetMap(GDK_WINDOW_XDISPLAY(rootwin),
- XkbAllClientInfoMask,
- XkbUseCoreKbd);
+ if (use_xkb_extension) {
+ xmap = XkbGetMap(GDK_WINDOW_XDISPLAY(rootwin),
+ XkbAllClientInfoMask,
+ XkbUseCoreKbd);
+ }
gdk_keymap_get_entries_for_keyval(NULL, keyval, &keys, &n_keys);
@@ -213,16 +217,24 @@ grab_ungrab (GdkWindow *rootwin,
continue;
}
- add_modifiers = FinallyGetModifiersForKeycode(xmap,
+
+ TRACE (g_print("grab/ungrab keycode: %d, lev: %d, grp: %d, ",
+ keys[k].keycode, keys[k].level, keys[k].group));
+ if (use_xkb_extension) {
+ add_modifiers = FinallyGetModifiersForKeycode(xmap,
keys[k].keycode,
keys[k].group,
keys[k].level);
+ } else if (keys[k].level > 0) {
+ /* skip shifted/modified keys in non-xkb mode
+ * this might mean the key can't be bound at all
+ */
+ continue;
+ }
if (add_modifiers == MODIFIERS_ERROR) {
continue;
}
- TRACE (g_print("grab/ungrab keycode: %d, lev: %d, grp: %d, ",
- keys[k].keycode, keys[k].level, keys[k].group));
TRACE (g_print("modifiers: 0x%x (consumed: 0x%x)\n",
add_modifiers | modifiers, add_modifiers));
if (grab_ungrab_with_ignorable_modifiers(rootwin,
@@ -240,7 +252,9 @@ grab_ungrab (GdkWindow *rootwin,
}
g_free(keys);
- XkbFreeClientMap(xmap, 0, TRUE);
+ if (xmap) {
+ XkbFreeClientMap(xmap, 0, TRUE);
+ }
return success;
}
@@ -357,7 +371,8 @@ filter_func (GdkXEvent *gdk_xevent, GdkE
xevent->xkey.keycode,
xevent->xkey.state));
- gdk_keymap_translate_keyboard_state(
+ if (use_xkb_extension) {
+ gdk_keymap_translate_keyboard_state(
keymap,
xevent->xkey.keycode,
modifiers,
@@ -366,6 +381,10 @@ filter_func (GdkXEvent *gdk_xevent, GdkE
*/
WE_ONLY_USE_ONE_GROUP,
&keyval, NULL, NULL, &consumed);
+ } else {
+ consumed = 0;
+ keyval = XLookupKeysym(&xevent->xkey, 0);
+ }
/* Map non-virtual to virtual modifiers */
modifiers &= ~consumed;
@@ -431,6 +450,26 @@ keybinder_init ()
{
GdkKeymap *keymap = gdk_keymap_get_default ();
GdkWindow *rootwin = gdk_get_default_root_window ();
+ Display *disp;
+ int xkb_opcode;
+ int xkb_event_base;
+ int xkb_error_base;
+ int majver = XkbMajorVersion;
+ int minver = XkbMinorVersion;
+
+ if (!(disp = XOpenDisplay(NULL))) {
+ g_warning("keybinder_init: Unable to open display");
+ return;
+ }
+
+ detected_xkb_extension = XkbQueryExtension(disp,
+ &xkb_opcode,
+ &xkb_event_base,
+ &xkb_error_base,
+ &majver, &minver);
+
+ use_xkb_extension = detected_xkb_extension;
+ TRACE(g_print("XKB: %d, version: %d, %d\n", use_xkb_extension, majver, minver));
gdk_window_add_filter (rootwin, filter_func, NULL);
@@ -448,6 +487,12 @@ keybinder_init ()
NULL);
}
+void
+keybinder_set_use_cooked_accelerators (gboolean use_cooked)
+{
+ use_xkb_extension = use_cooked && detected_xkb_extension;
+}
+
gboolean
keybinder_bind (const char *keystring,
KeybinderHandler handler,