[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