[Xfce4-commits] <xfwm4:xfce-4.8> Check for both forward and backward cycling modifier to be released before exiting the cycle loop (Bug 6508), do not enter the cycle loop if corresponding shortcut has no modifier.

Olivier Fourdan noreply at xfce.org
Mon Nov 7 21:04:02 CET 2011


Updating branch refs/heads/xfce-4.8
         to 04004ce53e864fb0a923b01efc6f4b7c369aec8c (commit)
       from 6f99593212b14fb02e00d969dacce1c6e276cbe8 (commit)

commit 04004ce53e864fb0a923b01efc6f4b7c369aec8c
Author: Olivier Fourdan <fourdan at xfce.org>
Date:   Mon Nov 7 20:56:25 2011 +0100

    Check for both forward and backward cycling modifier to be released before exiting the cycle loop (Bug 6508),
    do not enter the cycle loop if corresponding shortcut has no modifier.

 src/cycle.c  |  122 +++++++++++++++++++++++++++++++++++++---------------------
 src/screen.c |   13 ++++++
 src/screen.h |    1 +
 3 files changed, 92 insertions(+), 44 deletions(-)

diff --git a/src/cycle.c b/src/cycle.c
index b81bbc2..9098d35 100644
--- a/src/cycle.c
+++ b/src/cycle.c
@@ -184,6 +184,42 @@ clientCycleFocusAndRaise (Client *c)
     clientSetLastRaise (c);
 }
 
+static void
+clientCycleActivate (Client *c)
+{
+    ScreenInfo *screen_info;
+    DisplayInfo *display_info;
+    Client *focused;
+    guint workspace;
+
+    if (c == NULL)
+    {
+        return;
+    }
+
+    screen_info = c->screen_info;
+    display_info = screen_info->display_info;
+    workspace = c->win_workspace;
+    focused = clientGetFocus ();
+
+    if ((focused) && (c != focused))
+    {
+        /* We might be able to avoid this if we are about to switch workspace */
+        clientAdjustFullscreenLayer (focused, FALSE);
+    }
+    if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN))
+    {
+        /* We are explicitely activating a window that was shown before show-desktop */
+        clientClearAllShowDesktop (screen_info);
+    }
+    if (workspace != screen_info->current_ws)
+    {
+        workspaceSwitch (screen_info, workspace, c, FALSE, myDisplayGetCurrentTime (display_info));
+    }
+
+    clientCycleFocusAndRaise (c);
+}
+
 static eventFilterStatus
 clientCycleEventFilter (XEvent * xevent, gpointer data)
 {
@@ -193,7 +229,7 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
     Client *c, *removed;
     eventFilterStatus status;
     KeyCode cancel;
-    int key, modifier;
+    int key, modifiers;
     gboolean key_pressed, cycling, gone;
 
     TRACE ("entering clientCycleEventFilter");
@@ -208,7 +244,8 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
     screen_info = c->screen_info;
     display_info = screen_info->display_info;
     cancel = screen_info->params->keys[KEY_CANCEL].keycode;
-    modifier = screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier;
+    modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier |
+                 screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier);
     status = EVENT_FILTER_STOP;
     removed = NULL;
     cycling = TRUE;
@@ -264,8 +301,8 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
                         c = c2;
                     }
 
-                    /* If last key press event had not our modifier pressed, finish cycling */
-                    if (!(xevent->xkey.state & modifier))
+                    /* If last key press event had not our modifiers pressed, finish cycling */
+                    if (!(xevent->xkey.state & modifiers))
                     {
                         cycling = FALSE;
                     }
@@ -291,10 +328,12 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
             {
                 int keysym = XLookupKeysym (&xevent->xkey, 0);
 
-                if (!(xevent->xkey.state & modifier) ||
-                    (IsModifierKey(keysym) && (keysym != XK_Shift_L) && (keysym != XK_Shift_R)))
+                if (IsModifierKey(keysym))
                 {
-                    cycling = FALSE;
+                    if (!(myScreenGetModifierPressed (screen_info) & modifiers))
+                    {
+                        cycling = FALSE;
+                    }
                 }
             }
             break;
@@ -325,7 +364,7 @@ clientCycle (Client * c, XKeyEvent * ev)
     ClientCycleData passdata;
     GList *client_list, *selected;
     gboolean g1, g2;
-    int key;
+    int key, modifier;
 
     g_return_if_fail (c != NULL);
     TRACE ("entering clientCycle");
@@ -339,6 +378,36 @@ clientCycle (Client * c, XKeyEvent * ev)
         return;
     }
 
+    modifier = 0;
+    key = myScreenGetKeyPressed (screen_info, ev);
+    if (key == KEY_CYCLE_REVERSE_WINDOWS)
+    {
+        selected = g_list_last (client_list);
+        modifier = screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier;
+    }
+    else
+    {
+        selected = g_list_next (client_list);
+        modifier = screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier;
+    }
+    if (!selected)
+    {
+        /* Only one element in list */
+        selected = client_list;
+    }
+
+    if (!modifier)
+    {
+        /*
+         * The shortcut has no modifier so there's no point in entering
+         * the cycle loop, just select the next or previous window and
+         * that's it...
+         */
+        clientCycleActivate ((Client *) selected->data);
+        g_list_free (client_list);
+        return;
+    }
+
     g1 = myScreenGrabKeyboard (screen_info, ev->time);
     g2 = myScreenGrabPointer (screen_info, LeaveWindowMask,  None, ev->time);
 
@@ -353,21 +422,7 @@ clientCycle (Client * c, XKeyEvent * ev)
 
         return;
     }
-    key = myScreenGetKeyPressed (screen_info, ev);
 
-    if (key == KEY_CYCLE_REVERSE_WINDOWS)
-    {
-        selected = g_list_last (client_list);
-    }
-    else
-    {
-        selected = g_list_next (client_list);
-    }
-    if (!selected)
-    {
-        /* Only one element in list */
-        selected = client_list;
-    }
     passdata.wireframe = None;
 
     TRACE ("entering cycle loop");
@@ -389,28 +444,7 @@ clientCycle (Client * c, XKeyEvent * ev)
     c = tabwinGetSelected (passdata.tabwin);
     if (c)
     {
-        Client *focused;
-        guint workspace;
-
-        workspace = c->win_workspace;
-        focused = clientGetFocus ();
-
-        if ((focused) && (c != focused))
-        {
-            /* We might be able to avoid this if we are about to switch workspace */
-            clientAdjustFullscreenLayer (focused, FALSE);
-        }
-        if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN))
-        {
-            /* We are explicitely activating a window that was shown before show-desktop */
-            clientClearAllShowDesktop (screen_info);
-        }
-        if (workspace != screen_info->current_ws)
-        {
-            workspaceSwitch (screen_info, workspace, c, FALSE, myDisplayGetCurrentTime (display_info));
-        }
-
-        clientCycleFocusAndRaise (c);
+        clientCycleActivate (c);
     }
 
     tabwinDestroy (passdata.tabwin);
diff --git a/src/screen.c b/src/screen.c
index 9851387..a76ec0f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -561,6 +561,19 @@ myScreenGetKeyPressed (ScreenInfo *screen_info, XKeyEvent * ev)
     return key;
 }
 
+int
+myScreenGetModifierPressed (ScreenInfo *screen_info)
+{
+    Window dr, window;
+    unsigned int modifiers;
+    int rx, ry, wx, wy;
+
+    XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot,
+                   &dr, &window, &rx, &ry, &wx, &wy, &modifiers);
+
+    return (int) modifiers;
+}
+
 Client *
 myScreenGetClientFromWindow (ScreenInfo *screen_info, Window w, unsigned short mode)
 {
diff --git a/src/screen.h b/src/screen.h
index 01e6564..88e4845 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -212,6 +212,7 @@ void                     myScreenGrabKeys                       (ScreenInfo *);
 void                     myScreenUngrabKeys                     (ScreenInfo *);
 int                      myScreenGetKeyPressed                  (ScreenInfo *,
                                                                  XKeyEvent *);
+int                      myScreenGetModifierPressed             (ScreenInfo *);
 Client                  *myScreenGetClientFromWindow            (ScreenInfo *,
                                                                  Window,
                                                                  unsigned short);


More information about the Xfce4-commits mailing list