From 1ab6abc044b3b4d0fbed2c1298b49f1185af1bc2 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 7 Sep 2011 11:19:15 -0400 Subject: [PATCH] focus-follows-mouse: ignore events generated when reshaping the stage * Export meta_display_add_ignored_crossing_serial() * Add the serial for reshaping the stage * Increase the size of the "ignored_serials" array a bit to try to avoid the possibility of losing serials from multiple reshapes happening close together. https://bugzilla.gnome.org/show_bug.cgi?id=597190 --- src/compositor/compositor.c | 6 ++++++ src/core/display-private.h | 6 ++++-- src/core/display.c | 21 ++++++++++++++++----- src/meta/display.h | 3 +++ 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index ccda34402..47d8b558a 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -279,6 +279,12 @@ do_set_stage_input_region (MetaScreen *screen, Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); + + /* It's generally a good heuristic that when a crossing event is generated because + * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - + * it's not the user doing something, it's the environment changing under the user. + */ + meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region); } diff --git a/src/core/display-private.h b/src/core/display-private.h index cccc04e0f..c2129d08f 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -73,9 +73,11 @@ typedef enum { /* This is basically a bogus number, just has to be large enough * to handle the expected case of the alt+tab operation, where * we want to ignore serials from UnmapNotify on the tab popup, - * and the LeaveNotify/EnterNotify from the pointer ungrab + * and the LeaveNotify/EnterNotify from the pointer ungrab. It + * also has to be big enough to hold ignored serials from the point + * where we reshape the stage to the point where we get events back. */ -#define N_IGNORED_SERIALS 4 +#define N_IGNORED_SERIALS 10 typedef enum { META_TILE_NONE, diff --git a/src/core/display.c b/src/core/display.c index 9e44520ca..76697e11e 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1383,9 +1383,20 @@ meta_display_get_current_time_roundtrip (MetaDisplay *display) return timestamp; } -static void -add_ignored_serial (MetaDisplay *display, - unsigned long serial) +/** + * meta_display_add_ignored_crossing_serial: + * @display: a #MetaDisplay + * @serial: the serial to ignore + * + * Save the specified serial and ignore crossing events with that + * serial for the purpose of focus-follows-mouse. This can be used + * for certain changes to the window hierarchy that we don't want + * to change the focus window, even if they cause the pointer to + * end up in a new window. + */ +void +meta_display_add_ignored_crossing_serial (MetaDisplay *display, + unsigned long serial) { int i; @@ -1603,7 +1614,7 @@ event_callback (XEvent *event, if (meta_ui_window_should_not_cause_focus (display->xdisplay, modified)) { - add_ignored_serial (display, event->xany.serial); + meta_display_add_ignored_crossing_serial (display, event->xany.serial); meta_topic (META_DEBUG_FOCUS, "Adding EnterNotify serial %lu to ignored focus serials\n", event->xany.serial); @@ -1613,7 +1624,7 @@ event_callback (XEvent *event, event->xcrossing.mode == NotifyUngrab && modified == display->ungrab_should_not_cause_focus_window) { - add_ignored_serial (display, event->xany.serial); + meta_display_add_ignored_crossing_serial (display, event->xany.serial); meta_topic (META_DEBUG_FOCUS, "Adding LeaveNotify serial %lu to ignored focus serials\n", event->xany.serial); diff --git a/src/meta/display.h b/src/meta/display.h index f4ac20f7a..3a083afe5 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -155,4 +155,7 @@ GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display, Window meta_display_get_leader_window (MetaDisplay *display); +void meta_display_add_ignored_crossing_serial (MetaDisplay *display, + unsigned long serial); + #endif