summaryrefslogtreecommitdiff
path: root/src/core/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/display.c')
-rw-r--r--src/core/display.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/core/display.c b/src/core/display.c
index 63a93b02..17324b5f 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1423,9 +1423,11 @@ button_press_event_new (XEvent *xevent,
static void
update_focus_window (MetaDisplay *display,
MetaWindow *window,
- gulong serial)
+ gulong serial,
+ gboolean focused_by_us)
{
display->focus_serial = serial;
+ display->focused_by_us = focused_by_us;
if (window == display->focus_window)
return;
@@ -1535,7 +1537,8 @@ request_xserver_input_focus_change (MetaDisplay *display,
update_focus_window (display,
meta_window,
- serial);
+ serial,
+ TRUE);
meta_error_trap_pop (display);
@@ -1645,10 +1648,18 @@ handle_window_focus_event (MetaDisplay *display,
else
g_return_if_reached ();
- if (display->server_focus_serial > display->focus_serial)
+ /* If display->focused_by_us, then the focus_serial will be used only
+ * for a focus change we made and have already accounted for.
+ * (See request_xserver_input_focus_change().) Otherwise, we can get
+ * multiple focus events with the same serial.
+ */
+ if (display->server_focus_serial > display->focus_serial ||
+ (!display->focused_by_us &&
+ display->server_focus_serial == display->focus_serial))
{
update_focus_window (display, focus_window,
- display->server_focus_serial);
+ display->server_focus_serial,
+ FALSE);
}
}
@@ -1693,7 +1704,8 @@ event_callback (XEvent *event,
display->current_time = event_get_time (display, event);
display->xinerama_cache_invalidated = TRUE;
- if (event->xany.serial > display->focus_serial &&
+ if (display->focused_by_us &&
+ event->xany.serial > display->focus_serial &&
display->focus_window &&
display->focus_window->xwindow != display->server_focus_window)
{
@@ -1701,7 +1713,8 @@ event_callback (XEvent *event,
display->focus_window->desc);
update_focus_window (display,
meta_display_lookup_x_window (display, display->server_focus_window),
- display->server_focus_serial);
+ display->server_focus_serial,
+ FALSE);
}
modified = event_get_modified_window (display, event);