From 1d77641f0b00f7159168c18250c36ff7710f7954 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 30 Dec 2018 18:25:08 +0100 Subject: [PATCH] x11: Separate X11 focus handling into MetaX11Display method Updating the MetaWindow focus and the X Window focus is interrelated but independent. Call one after the other in the places we handle window focus changes. https://gitlab.gnome.org/GNOME/mutter/merge_requests/420 --- src/core/display-private.h | 13 +------------ src/core/display.c | 20 +++++--------------- src/x11/events.c | 24 +++++++++++++----------- src/x11/meta-x11-display-private.h | 13 +++++++++++++ src/x11/meta-x11-display.c | 23 ++++++++++++++++++----- 5 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index ea683a39a..be2f44433 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -140,14 +140,6 @@ struct _MetaDisplay */ guint allow_terminal_deactivation : 1; - /* If true, server->focus_serial refers to us changing the focus; in - * this case, we can ignore focus events that have exactly focus_serial, - * since we take care to make another request immediately afterwards. - * But if focus is being changed by another client, we have to accept - * multiple events with the same serial. - */ - guint focused_by_us : 1; - /*< private-ish >*/ GHashTable *stamps; GHashTable *wayland_windows; @@ -371,10 +363,7 @@ gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); void meta_display_sync_wayland_input_focus (MetaDisplay *display); void meta_display_update_focus_window (MetaDisplay *display, - MetaWindow *window, - Window xwindow, - gulong serial, - gboolean focused_by_us); + MetaWindow *window); void meta_display_sanity_check_timestamps (MetaDisplay *display, guint32 timestamp); diff --git a/src/core/display.c b/src/core/display.c index a9659fe9c..413b62a04 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1238,16 +1238,9 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display) void meta_display_update_focus_window (MetaDisplay *display, - MetaWindow *window, - Window xwindow, - gulong serial, - gboolean focused_by_us) + MetaWindow *window) { - display->x11_display->focus_serial = serial; - display->focused_by_us = focused_by_us; - - if (display->x11_display->focus_xwindow == xwindow && - display->focus_window == window) + if (display->focus_window == window) return; if (display->focus_window) @@ -1264,28 +1257,25 @@ meta_display_update_focus_window (MetaDisplay *display, */ previous = display->focus_window; display->focus_window = NULL; - display->x11_display->focus_xwindow = None; meta_window_set_focused_internal (previous, FALSE); } display->focus_window = window; - display->x11_display->focus_xwindow = xwindow; if (display->focus_window) { - meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n", - display->focus_window->desc, serial); + meta_topic (META_DEBUG_FOCUS, "* Focus --> %s\n", + display->focus_window->desc); meta_window_set_focused_internal (display->focus_window, TRUE); } else - meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL with serial %lu\n", serial); + meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL\n"); if (meta_is_wayland_compositor ()) meta_display_sync_wayland_input_focus (display); g_object_notify (G_OBJECT (display), "focus-window"); - meta_x11_display_update_active_window_hint (display->x11_display); } gboolean diff --git a/src/x11/events.c b/src/x11/events.c index 5fdff162c..02c8509dc 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -803,14 +803,15 @@ handle_window_focus_event (MetaX11Display *x11_display, * multiple focus events with the same serial. */ if (x11_display->server_focus_serial > x11_display->focus_serial || - (!display->focused_by_us && + (!x11_display->focused_by_us && x11_display->server_focus_serial == x11_display->focus_serial)) { - meta_display_update_focus_window (display, - focus_window, - focus_window ? focus_window->xwindow : None, - x11_display->server_focus_serial, - FALSE); + meta_display_update_focus_window (display, focus_window); + meta_x11_display_update_focus_window (x11_display, + focus_window ? + focus_window->xwindow : None, + x11_display->server_focus_serial, + FALSE); return TRUE; } else @@ -1792,7 +1793,7 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, if (META_IS_BACKEND_X11 (backend)) meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event); - if (display->focused_by_us && + if (x11_display->focused_by_us && event->xany.serial > x11_display->focus_serial && display->focus_window && !window_has_xwindow (display->focus_window, x11_display->server_focus_window)) @@ -1801,10 +1802,11 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display, display->focus_window->desc); meta_display_update_focus_window (display, meta_x11_display_lookup_x_window (x11_display, - x11_display->server_focus_window), - x11_display->server_focus_window, - x11_display->server_focus_serial, - FALSE); + x11_display->server_focus_window)); + meta_x11_display_update_focus_window (x11_display, + x11_display->server_focus_window, + x11_display->server_focus_serial, + FALSE); } if (event->xany.window == x11_display->xroot) diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index d19cdd688..0a6cafda0 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -134,6 +134,14 @@ struct _MetaX11Display GList *output_streams; } selection; + /* If true, server->focus_serial refers to us changing the focus; in + * this case, we can ignore focus events that have exactly focus_serial, + * since we take care to make another request immediately afterwards. + * But if focus is being changed by another client, we have to accept + * multiple events with the same serial. + */ + guint focused_by_us : 1; + guint keys_grabbed : 1; /* we use property updates as sentinels for certain window focus events @@ -233,4 +241,9 @@ void meta_x11_display_increment_focus_sentinel (MetaX11Display *x11_display); void meta_x11_display_decrement_focus_sentinel (MetaX11Display *x11_display); gboolean meta_x11_display_focus_sentinel_clear (MetaX11Display *x11_display); +void meta_x11_display_update_focus_window (MetaX11Display *x11_display, + Window xwindow, + gulong serial, + gboolean focused_by_us); + #endif /* META_X11_DISPLAY_PRIVATE_H */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 98c4e3e43..4711ca0aa 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -1822,6 +1822,22 @@ meta_x11_display_update_active_window_hint (MetaX11Display *x11_display) meta_x11_error_trap_pop (x11_display); } +void +meta_x11_display_update_focus_window (MetaX11Display *x11_display, + Window xwindow, + gulong serial, + gboolean focused_by_us) +{ + x11_display->focus_serial = serial; + x11_display->focused_by_us = !!focused_by_us; + + if (x11_display->focus_xwindow == xwindow) + return; + + x11_display->focus_xwindow = xwindow; + meta_x11_display_update_active_window_hint (x11_display); +} + static void request_xserver_input_focus_change (MetaX11Display *x11_display, MetaWindow *meta_window, @@ -1860,11 +1876,8 @@ request_xserver_input_focus_change (MetaX11Display *x11_display, XUngrabServer (x11_display->xdisplay); XFlush (x11_display->xdisplay); - meta_display_update_focus_window (x11_display->display, - meta_window, - xwindow, - serial, - TRUE); + meta_display_update_focus_window (x11_display->display, meta_window); + meta_x11_display_update_focus_window (x11_display, xwindow, serial, TRUE); meta_x11_error_trap_pop (x11_display);