compositor: Guard X11 types

This also moves meta_compositor_x11_redirect_windows to DisplayX11
where it makes more sense as meta_display_x11_redirection_windows

Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2272
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2445>
This commit is contained in:
Bilal Elmoussaoui 2022-05-31 11:42:47 +02:00
parent 184b8e9c8c
commit aaa3f34cc0
6 changed files with 90 additions and 79 deletions

View File

@ -67,8 +67,6 @@ MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (Me
void meta_compositor_locate_pointer (MetaCompositor *compositor); void meta_compositor_locate_pointer (MetaCompositor *compositor);
void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor); gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor);
MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor); MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);

View File

@ -54,15 +54,9 @@
#include "compositor/compositor-private.h" #include "compositor/compositor-private.h"
#include <X11/extensions/Xcomposite.h>
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-event-x11.h"
#include "backends/x11/meta-stage-x11.h"
#include "clutter/clutter-mutter.h" #include "clutter/clutter-mutter.h"
#include "cogl/cogl.h" #include "cogl/cogl.h"
#include "compositor/meta-later-private.h" #include "compositor/meta-later-private.h"
#include "compositor/meta-window-actor-x11.h"
#include "compositor/meta-window-actor-private.h" #include "compositor/meta-window-actor-private.h"
#include "compositor/meta-window-group-private.h" #include "compositor/meta-window-group-private.h"
#include "core/frame.h" #include "core/frame.h"
@ -75,16 +69,27 @@
#include "meta/meta-background-group.h" #include "meta/meta-background-group.h"
#include "meta/meta-context.h" #include "meta/meta-context.h"
#include "meta/meta-shadow-factory.h" #include "meta/meta-shadow-factory.h"
#include "meta/meta-x11-errors.h"
#include "meta/prefs.h" #include "meta/prefs.h"
#include "meta/window.h" #include "meta/window.h"
#include "x11/meta-x11-display-private.h"
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
#include "compositor/meta-window-actor-wayland.h" #include "compositor/meta-window-actor-wayland.h"
#include "wayland/meta-wayland-private.h" #include "wayland/meta-wayland-private.h"
#endif #endif
#ifdef HAVE_X11_CLIENT
#include <X11/extensions/Xcomposite.h>
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-event-x11.h"
#include "backends/x11/meta-stage-x11.h"
#include "compositor/meta-window-actor-x11.h"
#include "meta/meta-x11-errors.h"
#include "x11/meta-x11-display-private.h"
#endif
enum enum
{ {
PROP_0, PROP_0,
@ -327,6 +332,7 @@ void
meta_focus_stage_window (MetaDisplay *display, meta_focus_stage_window (MetaDisplay *display,
guint32 timestamp) guint32 timestamp)
{ {
#ifdef HAVE_X11_CLIENT
ClutterStage *stage; ClutterStage *stage;
Window window; Window window;
@ -342,18 +348,19 @@ meta_focus_stage_window (MetaDisplay *display,
meta_x11_display_set_input_focus_xwindow (display->x11_display, meta_x11_display_set_input_focus_xwindow (display->x11_display,
window, window,
timestamp); timestamp);
#endif
} }
gboolean gboolean
meta_stage_is_focused (MetaDisplay *display) meta_stage_is_focused (MetaDisplay *display)
{ {
ClutterStage *stage;
Window window;
if (meta_is_wayland_compositor ()) if (meta_is_wayland_compositor ())
return TRUE; return TRUE;
stage = CLUTTER_STAGE (meta_get_stage_for_display (display)); #ifdef HAVE_X11_CLIENT
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_display (display));
Window window;
if (!stage) if (!stage)
return FALSE; return FALSE;
@ -363,6 +370,9 @@ meta_stage_is_focused (MetaDisplay *display)
return FALSE; return FALSE;
return (display->x11_display->focus_xwindow == window); return (display->x11_display->focus_xwindow == window);
#else
return FALSE;
#endif
} }
void void
@ -377,62 +387,6 @@ meta_compositor_grab_end (MetaCompositor *compositor)
META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor); META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor);
} }
static void
redirect_windows (MetaCompositor *compositor,
MetaX11Display *x11_display)
{
MetaDisplay *display = meta_compositor_get_display (compositor);
MetaContext *context = meta_display_get_context (display);
Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
Window xroot = meta_x11_display_get_xroot (x11_display);
int screen_number = meta_x11_display_get_screen_number (x11_display);
guint n_retries;
guint max_retries;
if (meta_context_is_replacing (context))
max_retries = 5;
else
max_retries = 1;
n_retries = 0;
/* Some compositors (like old versions of Mutter) might not properly unredirect
* subwindows before destroying the WM selection window; so we wait a while
* for such a compositor to exit before giving up.
*/
while (TRUE)
{
meta_x11_error_trap_push (x11_display);
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
XSync (xdisplay, FALSE);
if (!meta_x11_error_trap_pop_with_return (x11_display))
break;
if (n_retries == max_retries)
{
/* This probably means that a non-WM compositor like xcompmgr is running;
* we have no way to get it to exit */
meta_fatal (_("Another compositing manager is already running on screen %i on display “%s”."),
screen_number, x11_display->name);
}
n_retries++;
g_usleep (G_USEC_PER_SEC);
}
}
void
meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
{
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
MetaDisplay *display = priv->display;
if (display->x11_display)
redirect_windows (compositor, display->x11_display);
}
static MetaCompositorView * static MetaCompositorView *
meta_compositor_create_view (MetaCompositor *compositor, meta_compositor_create_view (MetaCompositor *compositor,
ClutterStageView *stage_view) ClutterStageView *stage_view)
@ -514,9 +468,11 @@ meta_compositor_add_window (MetaCompositor *compositor,
switch (window->client_type) switch (window->client_type)
{ {
#ifdef HAVE_X11_CLIENT
case META_WINDOW_CLIENT_TYPE_X11: case META_WINDOW_CLIENT_TYPE_X11:
window_actor_type = META_TYPE_WINDOW_ACTOR_X11; window_actor_type = META_TYPE_WINDOW_ACTOR_X11;
break; break;
#endif
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
case META_WINDOW_CLIENT_TYPE_WAYLAND: case META_WINDOW_CLIENT_TYPE_WAYLAND:
@ -602,7 +558,9 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
if (!window_actor) if (!window_actor)
return; return;
#ifdef HAVE_X11_CLIENT
meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor)); meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor));
#endif
} }
void void

View File

@ -198,7 +198,7 @@ meta_compositor_x11_manage (MetaCompositor *compositor,
compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay); compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay);
meta_compositor_redirect_x11_windows (META_COMPOSITOR (compositor)); meta_x11_display_redirect_windows (x11_display, display);
return TRUE; return TRUE;
} }

View File

@ -638,7 +638,7 @@ create_compositor (MetaDisplay *display)
} }
static void static void
meta_display_init (MetaDisplay *disp) meta_display_init (MetaDisplay *display)
{ {
/* Some stuff could go in here that's currently in _open, /* Some stuff could go in here that's currently in _open,
* but it doesn't really matter. */ * but it doesn't really matter. */
@ -704,6 +704,7 @@ on_monitor_privacy_screen_changed (MetaDisplay *display,
: _("Privacy Screen Disabled")); : _("Privacy Screen Disabled"));
} }
#ifdef HAVE_X11_CLIENT
static gboolean static gboolean
meta_display_init_x11_display (MetaDisplay *display, meta_display_init_x11_display (MetaDisplay *display,
GError **error) GError **error)
@ -723,13 +724,12 @@ meta_display_init_x11_display (MetaDisplay *display,
{ {
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
meta_display_manage_all_xwindows (display); meta_display_manage_all_xwindows (display);
meta_compositor_redirect_x11_windows (display->compositor); meta_x11_display_redirect_windows (x11_display, display);
} }
return TRUE; return TRUE;
} }
#ifdef HAVE_WAYLAND
gboolean gboolean
meta_display_init_x11_finish (MetaDisplay *display, meta_display_init_x11_finish (MetaDisplay *display,
GAsyncResult *result, GAsyncResult *result,
@ -763,7 +763,7 @@ meta_display_init_x11_finish (MetaDisplay *display,
{ {
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
meta_display_manage_all_xwindows (display); meta_display_manage_all_xwindows (display);
meta_compositor_redirect_x11_windows (display->compositor); meta_x11_display_redirect_windows (x11_display, display);
} }
return TRUE; return TRUE;
@ -834,7 +834,7 @@ on_x11_initialized (MetaDisplay *display,
if (!meta_display_init_x11_finish (display, result, &error)) if (!meta_display_init_x11_finish (display, result, &error))
g_critical ("Failed to init X11 display: %s", error->message); g_critical ("Failed to init X11 display: %s", error->message);
} }
#endif #endif /* HAVE_X11_CLIENT */
void void
meta_display_shutdown_x11 (MetaDisplay *display) meta_display_shutdown_x11 (MetaDisplay *display)
@ -931,10 +931,12 @@ meta_display_new (MetaContext *context,
{ {
MetaWaylandCompositor *wayland_compositor = MetaWaylandCompositor *wayland_compositor =
wayland_compositor_from_display (display); wayland_compositor_from_display (display);
MetaX11DisplayPolicy x11_display_policy;
meta_wayland_compositor_init_display (wayland_compositor, display); meta_wayland_compositor_init_display (wayland_compositor, display);
#ifdef HAVE_XWAYLAND
MetaX11DisplayPolicy x11_display_policy;
x11_display_policy = meta_context_get_x11_display_policy (context); x11_display_policy = meta_context_get_x11_display_policy (context);
if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY) if (x11_display_policy == META_X11_DISPLAY_POLICY_MANDATORY)
{ {
@ -942,11 +944,12 @@ meta_display_new (MetaContext *context,
(GAsyncReadyCallback) on_x11_initialized, (GAsyncReadyCallback) on_x11_initialized,
NULL); NULL);
} }
#endif /* HAVE_XWAYLAND */
timestamp = meta_display_get_current_time_roundtrip (display); timestamp = meta_display_get_current_time_roundtrip (display);
} }
else else
#endif #endif /* HAVE_WAYLAND */
#ifdef HAVE_X11
{ {
if (!meta_display_init_x11_display (display, error)) if (!meta_display_init_x11_display (display, error))
{ {
@ -956,6 +959,11 @@ meta_display_new (MetaContext *context,
timestamp = display->x11_display->timestamp; timestamp = display->x11_display->timestamp;
} }
#else
{
g_assert_not_reached ();
}
#endif
display->last_focus_time = timestamp; display->last_focus_time = timestamp;
display->last_user_time = timestamp; display->last_user_time = timestamp;

View File

@ -56,4 +56,7 @@ META_EXPORT
void meta_x11_display_remove_event_func (MetaX11Display *x11_display, void meta_x11_display_remove_event_func (MetaX11Display *x11_display,
unsigned int id); unsigned int id);
META_EXPORT
void meta_x11_display_redirect_windows (MetaX11Display *x11_display,
MetaDisplay *display);
#endif /* META_X11_DISPLAY_H */ #endif /* META_X11_DISPLAY_H */

View File

@ -2497,3 +2497,47 @@ meta_x11_display_run_event_funcs (MetaX11Display *x11_display,
l = next; l = next;
} }
} }
void
meta_x11_display_redirect_windows (MetaX11Display *x11_display,
MetaDisplay *display)
{
MetaContext *context = meta_display_get_context (display);
Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
Window xroot = meta_x11_display_get_xroot (x11_display);
int screen_number = meta_x11_display_get_screen_number (x11_display);
guint n_retries;
guint max_retries;
if (meta_context_is_replacing (context))
max_retries = 5;
else
max_retries = 1;
n_retries = 0;
/* Some compositors (like old versions of Mutter) might not properly unredirect
* subwindows before destroying the WM selection window; so we wait a while
* for such a compositor to exit before giving up.
*/
while (TRUE)
{
meta_x11_error_trap_push (x11_display);
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
XSync (xdisplay, FALSE);
if (!meta_x11_error_trap_pop_with_return (x11_display))
break;
if (n_retries == max_retries)
{
/* This probably means that a non-WM compositor like xcompmgr is running;
* we have no way to get it to exit */
meta_fatal (_("Another compositing manager is already running on screen %i on display “%s”."),
screen_number, x11_display->name);
}
n_retries++;
g_usleep (G_USEC_PER_SEC);
}
}