* Author: Igor Baranov aka BIG (bigmephi@mail.ru) * This patch addresses a behavior of Super-key like when you press in combination with other keys, as well as for a single. * 1. Invokes shortcuts via holding Super+ (i.e. Super+D, Super+L, ...) * 2. Invokes Super-key shortcut on RELEASE of Super-key if no any other shortcut (Super+) was invoked. diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.c b/libxfce4kbd-private/xfce-shortcuts-grabber.c index 43dfca6..3afc0cd 100644 --- a/libxfce4kbd-private/xfce-shortcuts-grabber.c +++ b/libxfce4kbd-private/xfce-shortcuts-grabber.c @@ -131,6 +131,7 @@ xfce_shortcuts_grabber_constructed (GObject *object) XfceShortcutsGrabber *grabber = XFCE_SHORTCUTS_GRABBER (object); + grabber->superKeyContext.shouldWeFireShortcut = 0; keymap = gdk_keymap_get_default (); g_signal_connect (keymap, "keys-changed", G_CALLBACK (xfce_shortcuts_grabber_keys_changed), grabber); @@ -390,7 +391,30 @@ find_event_key (const gchar *shortcut, return FALSE; } - +static GdkFilterReturn xfce_filter_superkey(XEvent *xevent, guint keyval, XfceShortcutsGrabber* grabber) +{ + if (keyval == GDK_KEY_Super_L || keyval == GDK_KEY_Super_R) + { + if (xevent->type == KeyRelease) + { + if (grabber->superKeyContext.shouldWeFireShortcut) + { + xevent->type = KeyPress; + xevent->xkey.state &= ~GDK_MOD4_MASK; + grabber->superKeyContext.shouldWeFireShortcut = 0; + return GDK_FILTER_TRANSLATE; + } + return GDK_FILTER_CONTINUE; + } + grabber->superKeyContext.shouldWeFireShortcut = 1; + return GDK_FILTER_CONTINUE; + } + else if (xevent->type == KeyPress) + { + grabber->superKeyContext.shouldWeFireShortcut = 0; + } + return GDK_FILTER_TRANSLATE; +} static GdkFilterReturn xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, @@ -409,9 +433,6 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, xevent = (XEvent *) gdk_xevent; - if (xevent->type != KeyPress) - return GDK_FILTER_CONTINUE; - context.grabber = grabber; context.result = NULL; timestamp = xevent->xkey.time; @@ -420,12 +441,16 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, gdk_error_trap_push (); keymap = gdk_keymap_get_default (); mod_mask = gtk_accelerator_get_default_mod_mask (); - modifiers = xevent->xkey.state; gdk_keymap_translate_keyboard_state (keymap, xevent->xkey.keycode, - modifiers, + xevent->xkey.state, XkbGroupForCoreState (xevent->xkey.state), &keyval, NULL, NULL, &consumed); + if (xfce_filter_superkey(xevent, keyval, grabber) == GDK_FILTER_CONTINUE || + xevent->type != KeyPress) + goto out_continue; + + modifiers = xevent->xkey.state; /* We want Alt + Print to be Alt + Print not SysReq. See bug #7897 */ if (keyval == GDK_KEY_Sys_Req && (modifiers & GDK_MOD1_MASK) != 0) @@ -479,6 +504,8 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, gdk_flush (); +out_continue: + #if GTK_CHECK_VERSION (3, 0, 0) gdk_error_trap_pop_ignored (); #else @@ -489,7 +516,6 @@ xfce_shortcuts_grabber_event_filter (GdkXEvent *gdk_xevent, } - XfceShortcutsGrabber * xfce_shortcuts_grabber_new (void) { diff --git a/libxfce4kbd-private/xfce-shortcuts-grabber.h b/libxfce4kbd-private/xfce-shortcuts-grabber.h index e240226..2765364 100644 --- a/libxfce4kbd-private/xfce-shortcuts-grabber.h +++ b/libxfce4kbd-private/xfce-shortcuts-grabber.h @@ -55,6 +55,9 @@ struct _XfceShortcutsGrabber { GObject __parent__; + struct { + int shouldWeFireShortcut; + } superKeyContext; XfceShortcutsGrabberPrivate *priv; };