diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.c b/libxfce4kbd-private/xfce-shortcuts-grabber.c index 43dfca6..823fc5d 100644 --- a/libxfce4kbd-private/xfce-shortcuts-grabber.c +++ b/libxfce4kbd-private/xfce-shortcuts-grabber.c @@ -68,6 +68,7 @@ static GdkFilterReturn xfce_shortcuts_grabber_event_filter (GdkXEvent struct _XfceShortcutsGrabberPrivate { GHashTable *keys; + GQueue* keyvals; }; struct _XfceKey @@ -112,6 +113,7 @@ xfce_shortcuts_grabber_init (XfceShortcutsGrabber *grabber) { grabber->priv = XFCE_SHORTCUTS_GRABBER_GET_PRIVATE (grabber); grabber->priv->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + grabber->priv->keyvals = g_queue_new(); /* Workaround: Make sure modmap is up to date * There is possibly a bug in GTK+ where virtual modifiers are not @@ -153,6 +155,7 @@ xfce_shortcuts_grabber_finalize (GObject *object) xfce_shortcuts_grabber_ungrab_all (grabber); g_hash_table_unref (grabber->priv->keys); + g_queue_free(grabber->priv->keyvals); (*G_OBJECT_CLASS (xfce_shortcuts_grabber_parent_class)->finalize) (object); } @@ -402,16 +405,12 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, GdkModifierType consumed, modifiers; XEvent *xevent; guint keyval, mod_mask; - gchar *raw_shortcut_name; gint timestamp; g_return_val_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber), GDK_FILTER_CONTINUE); xevent = (XEvent *) gdk_xevent; - if (xevent->type != KeyPress) - return GDK_FILTER_CONTINUE; - context.grabber = grabber; context.result = NULL; timestamp = xevent->xkey.time; @@ -421,12 +420,35 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, keymap = gdk_keymap_get_default (); mod_mask = gtk_accelerator_get_default_mod_mask (); modifiers = xevent->xkey.state; + static GdkModifierType previous_modifiers = 0; gdk_keymap_translate_keyboard_state (keymap, xevent->xkey.keycode, modifiers, XkbGroupForCoreState (xevent->xkey.state), &keyval, NULL, NULL, &consumed); - + if (xevent->type == KeyPress) + { + previous_modifiers = modifiers; + g_queue_push_tail(grabber->priv->keyvals, GPOINTER_TO_INT(keyval)); + return GDK_FILTER_CONTINUE; + } + else if (xevent->type == KeyRelease) + { + modifiers = previous_modifiers; + previous_modifiers = 0; + if(grabber->priv->keyvals->length == 0) + { + return GDK_FILTER_CONTINUE; + } + guint prevkeyval = (guint)g_queue_pop_tail(grabber->priv->keyvals); + g_queue_clear(grabber->priv->keyvals); + if(prevkeyval != keyval) + { + return GDK_FILTER_CONTINUE; + } + } + else + return GDK_FILTER_CONTINUE; /* We want Alt + Print to be Alt + Print not SysReq. See bug #7897 */ if (keyval == GDK_KEY_Sys_Req && (modifiers & GDK_MOD1_MASK) != 0) { @@ -464,12 +486,13 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, * will compare them with values we also get from this function and as * it has its own logic, it's easier and safer to do so. * See bug #8744 for a "live" example. */ - raw_shortcut_name = gtk_accelerator_name (keyval, modifiers); +#if defined(DEBUG) && (DEBUG > 0) + gchar *raw_shortcut_name = gtk_accelerator_name (keyval, modifiers); gtk_accelerator_parse (raw_shortcut_name, &context.keyval, &context.modifiers); TRACE ("Looking for %s", raw_shortcut_name); g_free (raw_shortcut_name); - +#endif g_hash_table_foreach (grabber->priv->keys, (GHFunc) find_event_key, &context); if (G_LIKELY (context.result != NULL))