From 2625edec103eb4a85cb77482d385bb903de898b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 18 Apr 2023 22:07:37 +0200 Subject: [PATCH] x11/x11-display: Set compositor selection earlier on XWayland When the X11 display is actually XWayland there's no point to delay the compositor selection, given that mutter itself is the compositor and doing this may cause the first X11 client that starts not to receive the right information (and in some cases misbehave). Since some toolkits are not handling the compositor selection changes properly at later times, let's make their life easier by just initializing the selection as early as the other X11 properties, given that in this case there's nothing to replace. Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2472 Part-of: --- src/compositor/meta-compositor-x11.c | 2 +- src/core/display.c | 1 - src/x11/meta-x11-display-private.h | 3 ++- src/x11/meta-x11-display.c | 28 +++++++++++++++++++++++++--- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c index f142ce14b..333cb60f3 100644 --- a/src/compositor/meta-compositor-x11.c +++ b/src/compositor/meta-compositor-x11.c @@ -171,7 +171,7 @@ meta_compositor_x11_manage (MetaCompositor *compositor, determine_server_clock_source (compositor_x11); - meta_x11_display_set_cm_selection (display->x11_display); + meta_x11_display_set_cm_selection (display->x11_display, CurrentTime); compositor_x11->output = display->x11_display->composite_overlay_window; diff --git a/src/core/display.c b/src/core/display.c index 0ee95c0f0..eca1c0fcc 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -762,7 +762,6 @@ meta_display_init_x11_finish (MetaDisplay *display, if (!display->display_opening) { g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); - meta_x11_display_set_cm_selection (x11_display); meta_display_manage_all_xwindows (display); meta_compositor_redirect_x11_windows (display->compositor); } diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index 287aefa37..ef9c7e11a 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -292,7 +292,8 @@ int meta_x11_display_get_screen_number (MetaX11Display *x11_display); int meta_x11_display_get_damage_event_base (MetaX11Display *x11_display); -void meta_x11_display_set_cm_selection (MetaX11Display *x11_display); +void meta_x11_display_set_cm_selection (MetaX11Display *x11_display, + uint32_t timestamp); gboolean meta_x11_display_xwindow_is_a_no_focus_window (MetaX11Display *x11_display, Window xwindow); diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 3efd81acd..903309269 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -736,6 +736,10 @@ take_manager_selection (MetaX11Display *x11_display, { XEvent event; +#ifdef HAVE_XWAYLAND + g_return_val_if_fail (!meta_is_wayland_compositor (), new_owner); +#endif + /* We sort of block infinitely here which is probably lame. */ meta_verbose ("Waiting for old window manager to exit"); @@ -1430,6 +1434,22 @@ meta_x11_display_new (MetaDisplay *display, x11_display->wm_sn_atom = wm_sn_atom; x11_display->wm_sn_timestamp = timestamp; +#ifdef HAVE_XWAYLAND + if (meta_is_wayland_compositor ()) + { + meta_x11_display_set_cm_selection (x11_display, timestamp); + + if (x11_display->wm_cm_selection_window == None) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to acquire compositor ownership"); + + g_object_run_dispose (G_OBJECT (x11_display)); + return NULL; + } + } +#endif + init_event_masks (x11_display); meta_x11_display_init_frames_client (x11_display); @@ -1854,13 +1874,15 @@ on_monitors_changed_internal (MetaMonitorManager *monitor_manager, } void -meta_x11_display_set_cm_selection (MetaX11Display *x11_display) +meta_x11_display_set_cm_selection (MetaX11Display *x11_display, + uint32_t timestamp) { char selection[32]; Atom a; - guint32 timestamp; - timestamp = meta_x11_display_get_current_time_roundtrip (x11_display); + if (timestamp == CurrentTime) + timestamp = meta_x11_display_get_current_time_roundtrip (x11_display); + g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", DefaultScreen (x11_display->xdisplay)); a = XInternAtom (x11_display->xdisplay, selection, False);