diff options
Diffstat (limited to 'src/core/display.c')
-rw-r--r-- | src/core/display.c | 25 |
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); |