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
This commit is contained in:
Carlos Garnacho 2018-12-30 18:25:08 +01:00 committed by Jonas Ådahl
parent 2f217109aa
commit 1d77641f0b
5 changed files with 50 additions and 43 deletions

View File

@ -140,14 +140,6 @@ struct _MetaDisplay
*/ */
guint allow_terminal_deactivation : 1; 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 >*/ /*< private-ish >*/
GHashTable *stamps; GHashTable *stamps;
GHashTable *wayland_windows; 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_sync_wayland_input_focus (MetaDisplay *display);
void meta_display_update_focus_window (MetaDisplay *display, void meta_display_update_focus_window (MetaDisplay *display,
MetaWindow *window, MetaWindow *window);
Window xwindow,
gulong serial,
gboolean focused_by_us);
void meta_display_sanity_check_timestamps (MetaDisplay *display, void meta_display_sanity_check_timestamps (MetaDisplay *display,
guint32 timestamp); guint32 timestamp);

View File

@ -1238,16 +1238,9 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
void void
meta_display_update_focus_window (MetaDisplay *display, meta_display_update_focus_window (MetaDisplay *display,
MetaWindow *window, MetaWindow *window)
Window xwindow,
gulong serial,
gboolean focused_by_us)
{ {
display->x11_display->focus_serial = serial; if (display->focus_window == window)
display->focused_by_us = focused_by_us;
if (display->x11_display->focus_xwindow == xwindow &&
display->focus_window == window)
return; return;
if (display->focus_window) if (display->focus_window)
@ -1264,28 +1257,25 @@ meta_display_update_focus_window (MetaDisplay *display,
*/ */
previous = display->focus_window; previous = display->focus_window;
display->focus_window = NULL; display->focus_window = NULL;
display->x11_display->focus_xwindow = None;
meta_window_set_focused_internal (previous, FALSE); meta_window_set_focused_internal (previous, FALSE);
} }
display->focus_window = window; display->focus_window = window;
display->x11_display->focus_xwindow = xwindow;
if (display->focus_window) if (display->focus_window)
{ {
meta_topic (META_DEBUG_FOCUS, "* Focus --> %s with serial %lu\n", meta_topic (META_DEBUG_FOCUS, "* Focus --> %s\n",
display->focus_window->desc, serial); display->focus_window->desc);
meta_window_set_focused_internal (display->focus_window, TRUE); meta_window_set_focused_internal (display->focus_window, TRUE);
} }
else 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 ()) if (meta_is_wayland_compositor ())
meta_display_sync_wayland_input_focus (display); meta_display_sync_wayland_input_focus (display);
g_object_notify (G_OBJECT (display), "focus-window"); g_object_notify (G_OBJECT (display), "focus-window");
meta_x11_display_update_active_window_hint (display->x11_display);
} }
gboolean gboolean

View File

@ -803,14 +803,15 @@ handle_window_focus_event (MetaX11Display *x11_display,
* multiple focus events with the same serial. * multiple focus events with the same serial.
*/ */
if (x11_display->server_focus_serial > x11_display->focus_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)) x11_display->server_focus_serial == x11_display->focus_serial))
{ {
meta_display_update_focus_window (display, meta_display_update_focus_window (display, focus_window);
focus_window, meta_x11_display_update_focus_window (x11_display,
focus_window ? focus_window->xwindow : None, focus_window ?
x11_display->server_focus_serial, focus_window->xwindow : None,
FALSE); x11_display->server_focus_serial,
FALSE);
return TRUE; return TRUE;
} }
else else
@ -1792,7 +1793,7 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
if (META_IS_BACKEND_X11 (backend)) if (META_IS_BACKEND_X11 (backend))
meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event); 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 && event->xany.serial > x11_display->focus_serial &&
display->focus_window && display->focus_window &&
!window_has_xwindow (display->focus_window, x11_display->server_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); display->focus_window->desc);
meta_display_update_focus_window (display, meta_display_update_focus_window (display,
meta_x11_display_lookup_x_window (x11_display, meta_x11_display_lookup_x_window (x11_display,
x11_display->server_focus_window), x11_display->server_focus_window));
x11_display->server_focus_window, meta_x11_display_update_focus_window (x11_display,
x11_display->server_focus_serial, x11_display->server_focus_window,
FALSE); x11_display->server_focus_serial,
FALSE);
} }
if (event->xany.window == x11_display->xroot) if (event->xany.window == x11_display->xroot)

View File

@ -134,6 +134,14 @@ struct _MetaX11Display
GList *output_streams; GList *output_streams;
} selection; } 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; guint keys_grabbed : 1;
/* we use property updates as sentinels for certain window focus events /* 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); void meta_x11_display_decrement_focus_sentinel (MetaX11Display *x11_display);
gboolean meta_x11_display_focus_sentinel_clear (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 */ #endif /* META_X11_DISPLAY_PRIVATE_H */

View File

@ -1822,6 +1822,22 @@ meta_x11_display_update_active_window_hint (MetaX11Display *x11_display)
meta_x11_error_trap_pop (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 static void
request_xserver_input_focus_change (MetaX11Display *x11_display, request_xserver_input_focus_change (MetaX11Display *x11_display,
MetaWindow *meta_window, MetaWindow *meta_window,
@ -1860,11 +1876,8 @@ request_xserver_input_focus_change (MetaX11Display *x11_display,
XUngrabServer (x11_display->xdisplay); XUngrabServer (x11_display->xdisplay);
XFlush (x11_display->xdisplay); XFlush (x11_display->xdisplay);
meta_display_update_focus_window (x11_display->display, meta_display_update_focus_window (x11_display->display, meta_window);
meta_window, meta_x11_display_update_focus_window (x11_display, xwindow, serial, TRUE);
xwindow,
serial,
TRUE);
meta_x11_error_trap_pop (x11_display); meta_x11_error_trap_pop (x11_display);