From 5e7754f7424d1314a43cd11a5ac855d8df5ba2ed Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Thu, 16 Feb 2023 09:43:37 +0100 Subject: [PATCH] x11/display: Delay cursor updates When a client (either Wayland or X11) is started, the window activation will update the cursor to the "busy" cursor. Mutter will then set the X11 cursor on the X11 root window to match that so that X11 applications which do not explicitly set a cursor inherit from that default (busy) cursor. Updating the X11 cursor too often can hammer the X11 connection and cause a deadlock with Xwayland. Reload the X11 cursor in a later handler to avoid that issue. Part-of: --- src/x11/meta-x11-display-private.h | 2 ++ src/x11/meta-x11-display.c | 46 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index c50e52a2a..da6c8632a 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -206,6 +206,8 @@ struct _MetaX11Display MetaX11Stack *x11_stack; XserverRegion empty_region; + + unsigned int reload_x11_cursor_later; }; MetaX11Display *meta_x11_display_new (MetaDisplay *display, GError **error); diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 363d816a4..cb6d9a0e5 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -103,6 +103,8 @@ static void prefs_changed_callback (MetaPreference pref, static void meta_x11_display_init_frames_client (MetaX11Display *x11_display); +static void meta_x11_display_remove_cursor_later (MetaX11Display *x11_display); + static MetaBackend * backend_from_x11_display (MetaX11Display *x11_display) { @@ -274,6 +276,8 @@ meta_x11_display_dispose (GObject *object) g_clear_handle_id (&x11_display->display_close_idle, g_source_remove); + meta_x11_display_remove_cursor_later (x11_display); + g_free (x11_display->name); x11_display->name = NULL; @@ -1601,13 +1605,53 @@ set_cursor_theme (Display *xdisplay, meta_prefs_get_cursor_size () * scale); } +static void +meta_x11_display_remove_cursor_later (MetaX11Display *x11_display) +{ + if (x11_display->reload_x11_cursor_later) + { + MetaDisplay *display = x11_display->display; + MetaLaters *laters = meta_compositor_get_laters (display->compositor); + + meta_laters_remove (laters, x11_display->reload_x11_cursor_later); + x11_display->reload_x11_cursor_later = 0; + } +} + +static gboolean +reload_x11_cursor_later (gpointer user_data) +{ + MetaX11Display *x11_display = user_data; + + x11_display->reload_x11_cursor_later = 0; + meta_x11_display_reload_cursor (x11_display); + + return G_SOURCE_REMOVE; +} + +static void +schedule_reload_x11_cursor (MetaX11Display *x11_display) +{ + MetaDisplay *display = x11_display->display; + MetaLaters *laters = meta_compositor_get_laters (display->compositor); + + if (x11_display->reload_x11_cursor_later) + return; + + x11_display->reload_x11_cursor_later = + meta_laters_add (laters, META_LATER_BEFORE_REDRAW, + reload_x11_cursor_later, + x11_display, + NULL); +} + static void update_cursor_theme (MetaX11Display *x11_display) { MetaBackend *backend = backend_from_x11_display (x11_display); set_cursor_theme (x11_display->xdisplay, backend); - meta_x11_display_reload_cursor (x11_display); + schedule_reload_x11_cursor (x11_display); if (META_IS_BACKEND_X11 (backend)) {