[Xfce4-commits] [xfce/xfwm4] 01/01: Fix cycle vs. focus follow mouse

noreply at xfce.org noreply at xfce.org
Tue Dec 30 22:32:45 CET 2014


This is an automated email from the git hooks/post-receive script.

olivier pushed a commit to branch master
in repository xfce/xfwm4.

commit 45d9fce5b6740118b17570732201199e37016f49
Author: Olivier Fourdan <fourdan at xfce.org>
Date:   Tue Dec 30 22:13:01 2014 +0100

    Fix cycle vs. focus follow mouse
    
    Bug: 11166
    
    Enabling selection with the mouse in the cycle/wab window implies
    that events are routed to their usual,  respective windows, meaning
    that enter/leave notify events also reach regular windows.
    
    An unfortunate side effect is that, in focus follow mouse, focus
    could be sent back to the window underneath the pointer instead
    of the desired selected window if the pointer was located inside
    the cycle/tab window when it got unmapped.
    
    To avoid this, track enter/leave notify events in the cycle/tab
    windows and swallow the enter notify event resulting from the
    cycle/tab window being unmapped.
    
    Signed-off-by: Olivier Fourdan <fourdan at xfce.org>
---
 src/cycle.c |   93 ++++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 63 insertions(+), 30 deletions(-)

diff --git a/src/cycle.c b/src/cycle.c
index 93819d4..1f1dccc 100644
--- a/src/cycle.c
+++ b/src/cycle.c
@@ -54,6 +54,7 @@ struct _ClientCycleData
 {
     Tabwin *tabwin;
     Window wireframe;
+    gboolean inside;
 };
 
 static gint
@@ -233,8 +234,6 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
     int key, modifiers;
     gboolean key_pressed, cycling, gone;
     GList *li;
-    Window mouse_window = 0;
-    XButtonEvent ev;
 
     TRACE ("entering clientCycleEventFilter");
 
@@ -346,40 +345,44 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
             }
             break;
         case ButtonPress:
-            status = EVENT_FILTER_STOP;
-            ev = xevent->xbutton;
-            /* window of the event, we might accept it later */
-            mouse_window = xevent->xbutton.window;
-            if (mouse_window != 0)
+            /* only accept events for the tab windows */
+            for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
             {
-                /* only accept events for the tab windows */
-                for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
+                if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == xevent->xbutton.window)
                 {
-                    if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == mouse_window)
+                    if  (xevent->xbutton.button == Button1)
                     {
-                        if  (ev.button == Button1)
-                        {
-                            c2 = tabwinSelectHovered (passdata->tabwin);
-                            cycling = FALSE;
-                            break;
-                        }
-                        else if  (ev.button == Button4)
-                        {
-                            /* Mouse wheel scroll up */
-                            TRACE ("Cycle: previous");
-                            c2 = tabwinSelectPrev(passdata->tabwin);
-                        }
-                        else if (ev.button == Button5)
-                        {
-                            /* Mouse wheel scroll down */
-                            TRACE ("Cycle: next");
-                            c2 = tabwinSelectNext(passdata->tabwin);
-                        }
+                        c2 = tabwinSelectHovered (passdata->tabwin);
+                        cycling = FALSE;
+                        break;
+                    }
+                    else if  (xevent->xbutton.button == Button4)
+                    {
+                        /* Mouse wheel scroll up */
+                        TRACE ("Cycle: previous");
+                        c2 = tabwinSelectPrev(passdata->tabwin);
+                    }
+                    else if (xevent->xbutton.button == Button5)
+                    {
+                        /* Mouse wheel scroll down */
+                        TRACE ("Cycle: next");
+                        c2 = tabwinSelectNext(passdata->tabwin);
                     }
                 }
-                if (c2)
+            }
+            if (c2)
+            {
+                c = c2;
+            }
+            break;
+        case EnterNotify:
+        case LeaveNotify:
+            /* Track whether the pointer is inside one of the tab-windows */
+            for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next)
+            {
+                if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == xevent->xcrossing.window)
                 {
-                    c = c2;
+                    passdata->inside = (xevent->xcrossing.type == EnterNotify);
                 }
             }
             break;
@@ -415,6 +418,26 @@ clientCycleEventFilter (XEvent * xevent, gpointer data)
     return status;
 }
 
+static eventFilterStatus
+clientCycleFlushEventFilter (XEvent * xevent, gpointer data)
+{
+    DisplayInfo *display_info = (DisplayInfo *) data;
+
+    /* Update the display time */
+    myDisplayUpdateCurrentTime (display_info, xevent);
+
+    switch (xevent->type)
+    {
+        case EnterNotify:
+            gtk_main_quit ();
+            return EVENT_FILTER_STOP;
+            break;
+        default:
+            break;
+    }
+    return EVENT_FILTER_CONTINUE;
+}
+
 void
 clientCycle (Client * c, XKeyEvent * ev)
 {
@@ -483,6 +506,7 @@ clientCycle (Client * c, XKeyEvent * ev)
     }
 
     passdata.wireframe = None;
+    passdata.inside = FALSE;
 
     TRACE ("entering cycle loop");
     if (screen_info->params->cycle_draw_frame)
@@ -511,6 +535,15 @@ clientCycle (Client * c, XKeyEvent * ev)
     g_free (passdata.tabwin);
     g_list_free (client_list);
 
+    if (passdata.inside)
+    {
+        /* A bit of a hack, flush EnterNotify if the pointer is inside
+         * the tabwin to defeat focus-follow-mouse tracking */
+        eventFilterPush (display_info->xfilter, clientCycleFlushEventFilter, display_info);
+        gtk_main ();
+        eventFilterPop (display_info->xfilter);
+    }
+
     myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
     myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list