Compare commits
17 Commits
wip/smcv/c
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8aeec308fb | ||
![]() |
252fd771b1 | ||
![]() |
41bff1e997 | ||
![]() |
323742e736 | ||
![]() |
14f41f3130 | ||
![]() |
21b4cf8a50 | ||
![]() |
a4f47820c3 | ||
![]() |
471eca3745 | ||
![]() |
c1f39514ca | ||
![]() |
038720fecc | ||
![]() |
d367d97364 | ||
![]() |
885f89a217 | ||
![]() |
21411faeb1 | ||
![]() |
cf4a9b3f6a | ||
![]() |
1226c599c9 | ||
![]() |
c9459fa096 | ||
![]() |
d31fb640d5 |
@@ -124,6 +124,8 @@
|
||||
real-time scheduling. The executable
|
||||
or user must have CAP_SYS_NICE.
|
||||
Requires a restart.
|
||||
• “autostart-xwayland” — initializes Xwayland lazily if there are
|
||||
X11 clients. Requires restart.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
|
@@ -34,6 +34,7 @@ typedef enum _MetaExperimentalFeature
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
|
||||
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1),
|
||||
META_EXPERIMENTAL_FEATURE_RT_SCHEDULER = (1 << 2),
|
||||
META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND = (1 << 3),
|
||||
} MetaExperimentalFeature;
|
||||
|
||||
#define META_TYPE_SETTINGS (meta_settings_get_type ())
|
||||
|
@@ -266,6 +266,8 @@ experimental_features_handler (GVariant *features_variant,
|
||||
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
|
||||
else if (g_str_equal (feature, "rt-scheduler"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_RT_SCHEDULER;
|
||||
else if (g_str_equal (feature, "autostart-xwayland"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND;
|
||||
else
|
||||
g_info ("Unknown experimental feature '%s'\n", feature);
|
||||
}
|
||||
|
@@ -74,4 +74,6 @@ MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (Me
|
||||
|
||||
void meta_compositor_locate_pointer (MetaCompositor *compositor);
|
||||
|
||||
void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
|
||||
|
||||
#endif /* META_COMPOSITOR_PRIVATE_H */
|
||||
|
@@ -516,6 +516,15 @@ redirect_windows (MetaX11Display *x11_display)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
|
||||
{
|
||||
MetaDisplay *display = compositor->display;
|
||||
|
||||
if (display->x11_display)
|
||||
redirect_windows (display->x11_display);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_manage (MetaCompositor *compositor)
|
||||
{
|
||||
@@ -595,8 +604,7 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay);
|
||||
}
|
||||
|
||||
if (display->x11_display)
|
||||
redirect_windows (display->x11_display);
|
||||
meta_compositor_redirect_x11_windows (compositor);
|
||||
|
||||
compositor->plugin_mgr = meta_plugin_manager_new (compositor);
|
||||
}
|
||||
|
@@ -264,7 +264,7 @@ struct _MetaDisplayClass
|
||||
|
||||
gboolean meta_display_open (void);
|
||||
|
||||
void meta_display_manage_all_windows (MetaDisplay *display);
|
||||
void meta_display_manage_all_xwindows (MetaDisplay *display);
|
||||
void meta_display_unmanage_windows (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
|
||||
|
@@ -49,6 +49,7 @@
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/cm/meta-backend-x11-cm.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "compositor/compositor-private.h"
|
||||
#include "core/bell.h"
|
||||
#include "core/boxes-private.h"
|
||||
#include "core/display-private.h"
|
||||
@@ -149,6 +150,7 @@ enum
|
||||
SHOWING_DESKTOP_CHANGED,
|
||||
RESTACKED,
|
||||
WORKAREAS_CHANGED,
|
||||
INIT_XSERVER,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -479,6 +481,13 @@ meta_display_class_init (MetaDisplayClass *klass)
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
display_signals[INIT_XSERVER] =
|
||||
g_signal_new ("init-xserver",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FOCUS_WINDOW,
|
||||
g_param_spec_object ("focus-window",
|
||||
@@ -643,10 +652,15 @@ meta_display_init_x11 (MetaDisplay *display,
|
||||
|
||||
display->x11_display = x11_display;
|
||||
g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0);
|
||||
meta_x11_display_create_guard_window (x11_display);
|
||||
|
||||
if (!display->display_opening)
|
||||
meta_display_manage_all_windows (display);
|
||||
if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
|
||||
{
|
||||
meta_x11_display_create_guard_window (x11_display);
|
||||
if (!display->display_opening)
|
||||
meta_display_manage_all_xwindows (display);
|
||||
|
||||
meta_compositor_redirect_x11_windows (display->compositor);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -758,7 +772,7 @@ meta_display_open (void)
|
||||
display->selection = meta_selection_new (display);
|
||||
meta_clipboard_manager_init (display);
|
||||
|
||||
if (meta_should_autostart_x11_display ())
|
||||
if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY)
|
||||
{
|
||||
if (!meta_display_init_x11 (display, &error))
|
||||
g_error ("Failed to start Xwayland: %s", error->message);
|
||||
@@ -797,7 +811,7 @@ meta_display_open (void)
|
||||
* we start out with no windows.
|
||||
*/
|
||||
if (!meta_is_wayland_compositor ())
|
||||
meta_display_manage_all_windows (display);
|
||||
meta_display_manage_all_xwindows (display);
|
||||
|
||||
if (old_active_xwindow != None)
|
||||
{
|
||||
@@ -2448,7 +2462,7 @@ meta_resize_gravity_from_grab_op (MetaGrabOp op)
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_manage_all_windows (MetaDisplay *display)
|
||||
meta_display_manage_all_xwindows (MetaDisplay *display)
|
||||
{
|
||||
guint64 *_children;
|
||||
guint64 *children;
|
||||
@@ -2462,7 +2476,8 @@ meta_display_manage_all_windows (MetaDisplay *display)
|
||||
|
||||
for (i = 0; i < n_children; ++i)
|
||||
{
|
||||
g_assert (META_STACK_ID_IS_X11 (children[i]));
|
||||
if (!META_STACK_ID_IS_X11 (children[i]))
|
||||
continue;
|
||||
meta_window_x11_new (display, children[i], TRUE,
|
||||
META_COMP_EFFECT_NONE);
|
||||
}
|
||||
|
@@ -190,9 +190,14 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
"Incrementing unmaps_pending on %s for reparent back to root\n", window->desc);
|
||||
window->unmaps_pending += 1;
|
||||
}
|
||||
meta_stack_tracker_record_add (window->display->stack_tracker,
|
||||
window->xwindow,
|
||||
XNextRequest (x11_display->xdisplay));
|
||||
|
||||
if (!x11_display->closing)
|
||||
{
|
||||
meta_stack_tracker_record_add (window->display->stack_tracker,
|
||||
window->xwindow,
|
||||
XNextRequest (x11_display->xdisplay));
|
||||
}
|
||||
|
||||
XReparentWindow (x11_display->xdisplay,
|
||||
window->xwindow,
|
||||
x11_display->xroot,
|
||||
|
@@ -1570,6 +1570,8 @@ meta_window_grab_keys (MetaWindow *window)
|
||||
MetaDisplay *display = window->display;
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
return;
|
||||
if (window->all_keys_grabbed)
|
||||
return;
|
||||
|
||||
@@ -1604,7 +1606,7 @@ meta_window_grab_keys (MetaWindow *window)
|
||||
void
|
||||
meta_window_ungrab_keys (MetaWindow *window)
|
||||
{
|
||||
if (window->keys_grabbed)
|
||||
if (!meta_is_wayland_compositor () && window->keys_grabbed)
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
@@ -1663,7 +1665,11 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
}
|
||||
|
||||
meta_change_keygrab (keys, display->x11_display->xroot, TRUE, &resolved_combo);
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
meta_change_keygrab (keys, display->x11_display->xroot,
|
||||
TRUE, &resolved_combo);
|
||||
}
|
||||
|
||||
grab = g_new0 (MetaKeyGrab, 1);
|
||||
grab->action = next_dynamic_keybinding_action ();
|
||||
@@ -1709,8 +1715,11 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
|
||||
{
|
||||
int i;
|
||||
|
||||
meta_change_keygrab (keys, display->x11_display->xroot,
|
||||
FALSE, &binding->resolved_combo);
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
meta_change_keygrab (keys, display->x11_display->xroot,
|
||||
FALSE, &binding->resolved_combo);
|
||||
}
|
||||
|
||||
for (i = 0; i < binding->resolved_combo.len; i++)
|
||||
{
|
||||
@@ -1788,7 +1797,7 @@ meta_window_grab_all_keys (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
Window grabwindow;
|
||||
gboolean retval;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
if (window->all_keys_grabbed)
|
||||
return FALSE;
|
||||
@@ -1804,25 +1813,29 @@ meta_window_grab_all_keys (MetaWindow *window,
|
||||
window->desc);
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
grabwindow = meta_window_x11_get_toplevel_xwindow (window);
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Grabbing all keys on window %s\n", window->desc);
|
||||
retval = grab_keyboard (grabwindow, timestamp, XIGrabModeAsync);
|
||||
if (retval)
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
window->keys_grabbed = FALSE;
|
||||
window->all_keys_grabbed = TRUE;
|
||||
window->grab_on_frame = window->frame != NULL;
|
||||
grabwindow = meta_window_x11_get_toplevel_xwindow (window);
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Grabbing all keys on window %s\n", window->desc);
|
||||
retval = grab_keyboard (grabwindow, timestamp, XIGrabModeAsync);
|
||||
if (retval)
|
||||
{
|
||||
window->keys_grabbed = FALSE;
|
||||
window->all_keys_grabbed = TRUE;
|
||||
window->grab_on_frame = window->frame != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp)
|
||||
meta_window_ungrab_all_keys (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
if (window->all_keys_grabbed)
|
||||
if (!meta_is_wayland_compositor () && window->all_keys_grabbed)
|
||||
{
|
||||
ungrab_keyboard (timestamp);
|
||||
|
||||
|
@@ -30,10 +30,17 @@ typedef enum _MetaCompositorType
|
||||
META_COMPOSITOR_TYPE_X11,
|
||||
} MetaCompositorType;
|
||||
|
||||
typedef enum _MetaDisplayPolicy
|
||||
{
|
||||
META_DISPLAY_POLICY_MANDATORY,
|
||||
META_DISPLAY_POLICY_ON_DEMAND,
|
||||
META_DISPLAY_POLICY_DISABLED,
|
||||
} MetaDisplayPolicy;
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_override_compositor_configuration (MetaCompositorType compositor_type,
|
||||
GType backend_gtype);
|
||||
|
||||
gboolean meta_should_autostart_x11_display (void);
|
||||
MetaDisplayPolicy meta_get_x11_display_policy (void);
|
||||
|
||||
#endif /* META_MAIN_PRIVATE_H */
|
||||
|
@@ -717,15 +717,27 @@ prefs_changed_callback (MetaPreference pref,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_should_autostart_x11_display (void)
|
||||
MetaDisplayPolicy
|
||||
meta_get_x11_display_policy (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
gboolean wants_x11 = TRUE;
|
||||
|
||||
if (META_IS_BACKEND_X11_CM (backend))
|
||||
return META_DISPLAY_POLICY_MANDATORY;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
wants_x11 = !opt_no_x11;
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
|
||||
if (opt_no_x11)
|
||||
return META_DISPLAY_POLICY_DISABLED;
|
||||
|
||||
if (meta_settings_is_experimental_feature_enabled (settings,
|
||||
META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND))
|
||||
return META_DISPLAY_POLICY_ON_DEMAND;
|
||||
}
|
||||
#endif
|
||||
|
||||
return META_IS_BACKEND_X11_CM (backend) || wants_x11;
|
||||
return META_DISPLAY_POLICY_MANDATORY;
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@ meta_launch_context_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (meta_launch_context_parent_class)->constructed (object);
|
||||
|
||||
x11_display = getenv ("DISPLAY");
|
||||
x11_display = meta_x11_get_display_name ();
|
||||
wayland_display = getenv ("WAYLAND_DISPLAY");
|
||||
|
||||
if (x11_display)
|
||||
|
@@ -508,6 +508,42 @@ query_xserver_stack (MetaDisplay *display,
|
||||
XFree (children);
|
||||
}
|
||||
|
||||
static void
|
||||
drop_x11_windows (MetaDisplay *display,
|
||||
MetaStackTracker *tracker)
|
||||
{
|
||||
GArray *new_stack;
|
||||
GList *l;
|
||||
int i;
|
||||
|
||||
tracker->xserver_serial = 0;
|
||||
|
||||
new_stack = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
|
||||
for (i = 0; i < tracker->verified_stack->len; i++)
|
||||
{
|
||||
guint64 window = g_array_index (tracker->verified_stack, guint64, i);
|
||||
|
||||
if (!META_STACK_ID_IS_X11 (window))
|
||||
g_array_append_val (new_stack, window);
|
||||
}
|
||||
|
||||
g_array_unref (tracker->verified_stack);
|
||||
tracker->verified_stack = new_stack;
|
||||
l = tracker->unverified_predictions->head;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaStackOp *op = l->data;
|
||||
GList *next = l->next;
|
||||
|
||||
if (META_STACK_ID_IS_X11 (op->any.window))
|
||||
g_queue_remove (tracker->unverified_predictions, op);
|
||||
|
||||
l = next;
|
||||
}
|
||||
}
|
||||
|
||||
MetaStackTracker *
|
||||
meta_stack_tracker_new (MetaDisplay *display)
|
||||
{
|
||||
@@ -523,6 +559,10 @@ meta_stack_tracker_new (MetaDisplay *display)
|
||||
"x11-display-opened",
|
||||
G_CALLBACK (query_xserver_stack),
|
||||
tracker);
|
||||
g_signal_connect (display,
|
||||
"x11-display-closing",
|
||||
G_CALLBACK (drop_x11_windows),
|
||||
tracker);
|
||||
|
||||
meta_stack_tracker_dump (tracker);
|
||||
|
||||
@@ -546,6 +586,9 @@ meta_stack_tracker_free (MetaStackTracker *tracker)
|
||||
g_signal_handlers_disconnect_by_func (tracker->display,
|
||||
(gpointer)query_xserver_stack,
|
||||
tracker);
|
||||
g_signal_handlers_disconnect_by_func (tracker->display,
|
||||
drop_x11_windows,
|
||||
tracker);
|
||||
|
||||
g_free (tracker);
|
||||
}
|
||||
|
@@ -48,16 +48,26 @@ typedef struct
|
||||
char *lock_file;
|
||||
int abstract_fd;
|
||||
int unix_fd;
|
||||
char *name;
|
||||
} MetaXWaylandConnection;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaXWaylandConnection private_connection;
|
||||
MetaXWaylandConnection public_connection;
|
||||
|
||||
guint xserver_grace_period_id;
|
||||
struct wl_display *wayland_display;
|
||||
struct wl_client *client;
|
||||
struct wl_resource *xserver_resource;
|
||||
char *display_name;
|
||||
char *auth_file;
|
||||
|
||||
GCancellable *xserver_died_cancellable;
|
||||
GSubprocess *proc;
|
||||
GMainLoop *init_loop;
|
||||
|
||||
GList *x11_windows;
|
||||
|
||||
MetaXWaylandDnd *dnd;
|
||||
} MetaXWaylandManager;
|
||||
|
||||
|
@@ -418,9 +418,9 @@ meta_wayland_init (void)
|
||||
meta_wayland_eglstream_controller_init (compositor);
|
||||
#endif
|
||||
|
||||
if (meta_should_autostart_x11_display ())
|
||||
if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
|
||||
{
|
||||
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
||||
if (!meta_xwayland_init (&compositor->xwayland_manager, compositor->wayland_display))
|
||||
g_error ("Failed to start X Wayland");
|
||||
}
|
||||
|
||||
@@ -443,9 +443,9 @@ meta_wayland_init (void)
|
||||
compositor->display_name = g_strdup (display_name);
|
||||
}
|
||||
|
||||
if (meta_should_autostart_x11_display ())
|
||||
if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
|
||||
{
|
||||
set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
|
||||
set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name);
|
||||
set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor));
|
||||
}
|
||||
|
||||
@@ -461,7 +461,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
|
||||
const char *
|
||||
meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
return compositor->xwayland_manager.display_name;
|
||||
return compositor->xwayland_manager.private_connection.name;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -471,7 +471,7 @@ meta_wayland_finalize (void)
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
meta_xwayland_stop (&compositor->xwayland_manager);
|
||||
meta_xwayland_shutdown (&compositor->xwayland_manager);
|
||||
g_clear_pointer (&compositor->display_name, g_free);
|
||||
}
|
||||
|
||||
|
@@ -25,14 +25,14 @@
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
gboolean
|
||||
meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
struct wl_display *display);
|
||||
meta_xwayland_init (MetaXWaylandManager *manager,
|
||||
struct wl_display *display);
|
||||
|
||||
void
|
||||
meta_xwayland_complete_init (MetaDisplay *display);
|
||||
|
||||
void
|
||||
meta_xwayland_stop (MetaXWaylandManager *manager);
|
||||
meta_xwayland_shutdown (MetaXWaylandManager *manager);
|
||||
|
||||
/* wl_data_device/X11 selection interoperation */
|
||||
void meta_xwayland_init_dnd (void);
|
||||
|
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
#include "core/main-private.h"
|
||||
#include "meta/main.h"
|
||||
#include "wayland/meta-wayland-actor-surface.h"
|
||||
|
||||
@@ -70,6 +71,8 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
|
||||
static int display_number_override = -1;
|
||||
|
||||
static void meta_xwayland_stop_xserver (MetaXWaylandManager *manager);
|
||||
|
||||
void
|
||||
meta_xwayland_associate_window_with_surface (MetaWindow *window,
|
||||
MetaWaylandSurface *surface)
|
||||
@@ -368,24 +371,45 @@ xserver_died (GObject *source,
|
||||
g_warning ("Failed to finish waiting for Xwayland: %s", error->message);
|
||||
}
|
||||
else if (!g_subprocess_get_successful (proc))
|
||||
g_warning ("X Wayland crashed; exiting");
|
||||
else
|
||||
{
|
||||
/* For now we simply abort if we see the server exit.
|
||||
*
|
||||
* In the future X will only be loaded lazily for legacy X support
|
||||
* but for now it's a hard requirement. */
|
||||
g_warning ("Spurious exit of X Wayland server");
|
||||
}
|
||||
g_warning ("X Wayland process exited");
|
||||
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY)
|
||||
{
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
}
|
||||
else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (display->x11_display)
|
||||
meta_display_shutdown_x11 (display);
|
||||
|
||||
if (!meta_xwayland_init (&compositor->xwayland_manager,
|
||||
compositor->wayland_display))
|
||||
g_warning ("Failed to init X sockets");
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shutdown_xwayland_cb (gpointer data)
|
||||
{
|
||||
MetaXWaylandManager *manager = data;
|
||||
|
||||
g_debug ("Shutting down Xwayland");
|
||||
manager->xserver_grace_period_id = 0;
|
||||
meta_display_shutdown_x11 (meta_get_display ());
|
||||
meta_xwayland_stop_xserver (manager);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static int
|
||||
x_io_error (Display *display)
|
||||
{
|
||||
g_warning ("Connection to xwayland lost");
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
|
||||
if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY)
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -397,7 +421,36 @@ meta_xwayland_override_display_number (int number)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
choose_xdisplay (MetaXWaylandManager *manager)
|
||||
open_display_sockets (MetaXWaylandManager *manager,
|
||||
int display_index,
|
||||
int *abstract_fd_out,
|
||||
int *unix_fd_out,
|
||||
gboolean *fatal)
|
||||
{
|
||||
int abstract_fd, unix_fd;
|
||||
|
||||
abstract_fd = bind_to_abstract_socket (display_index,
|
||||
fatal);
|
||||
if (abstract_fd < 0)
|
||||
return FALSE;
|
||||
|
||||
unix_fd = bind_to_unix_socket (display_index);
|
||||
if (unix_fd < 0)
|
||||
{
|
||||
*fatal = FALSE;
|
||||
close (abstract_fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*abstract_fd_out = abstract_fd;
|
||||
*unix_fd_out = unix_fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
choose_xdisplay (MetaXWaylandManager *manager,
|
||||
MetaXWaylandConnection *connection)
|
||||
{
|
||||
int display = 0;
|
||||
char *lock_file = NULL;
|
||||
@@ -417,8 +470,10 @@ choose_xdisplay (MetaXWaylandManager *manager)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
manager->abstract_fd = bind_to_abstract_socket (display, &fatal);
|
||||
if (manager->abstract_fd < 0)
|
||||
if (!open_display_sockets (manager, display,
|
||||
&connection->abstract_fd,
|
||||
&connection->unix_fd,
|
||||
&fatal))
|
||||
{
|
||||
unlink (lock_file);
|
||||
|
||||
@@ -429,27 +484,18 @@ choose_xdisplay (MetaXWaylandManager *manager)
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to bind abstract socket");
|
||||
g_warning ("Failed to bind X11 socket");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
manager->unix_fd = bind_to_unix_socket (display);
|
||||
if (manager->unix_fd < 0)
|
||||
{
|
||||
unlink (lock_file);
|
||||
close (manager->abstract_fd);
|
||||
display++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
while (1);
|
||||
|
||||
manager->display_index = display;
|
||||
manager->display_name = g_strdup_printf (":%d", manager->display_index);
|
||||
manager->lock_file = lock_file;
|
||||
connection->display_index = display;
|
||||
connection->name = g_strdup_printf (":%d", connection->display_index);
|
||||
connection->lock_file = lock_file;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -536,6 +582,7 @@ on_displayfd_ready (int fd,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaXWaylandManager *manager = user_data;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
/* The server writes its display name to the displayfd
|
||||
* socket when it's ready. We don't care about the data
|
||||
@@ -543,11 +590,17 @@ on_displayfd_ready (int fd,
|
||||
* that means it's ready. */
|
||||
xserver_finished_init (manager);
|
||||
|
||||
g_signal_emit_by_name (display, "init-xserver",
|
||||
manager->private_connection.display_index);
|
||||
|
||||
if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
|
||||
meta_display_init_x11 (display, NULL);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_xwayland_init_xserver (MetaXWaylandManager *manager)
|
||||
meta_xwayland_start_xserver (MetaXWaylandManager *manager)
|
||||
{
|
||||
int xwayland_client_fd[2];
|
||||
int displayfd[2];
|
||||
@@ -581,14 +634,15 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
|
||||
launcher = g_subprocess_launcher_new (flags);
|
||||
|
||||
g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5);
|
||||
g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7);
|
||||
|
||||
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
|
||||
|
||||
manager->proc = g_subprocess_launcher_spawn (launcher, &error,
|
||||
XWAYLAND_PATH, manager->display_name,
|
||||
XWAYLAND_PATH, manager->public_connection.name,
|
||||
"-rootless",
|
||||
"-noreset",
|
||||
"-accessx",
|
||||
@@ -597,6 +651,7 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
|
||||
"-listen", "4",
|
||||
"-listen", "5",
|
||||
"-displayfd", "6",
|
||||
"-initfd", "7",
|
||||
NULL);
|
||||
if (!manager->proc)
|
||||
{
|
||||
@@ -620,30 +675,133 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
struct wl_display *wl_display)
|
||||
static gboolean
|
||||
xdisplay_connection_activity_cb (gint fd,
|
||||
GIOCondition cond,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (!choose_xdisplay (manager))
|
||||
return FALSE;
|
||||
MetaXWaylandManager *manager = user_data;
|
||||
|
||||
if (!meta_xwayland_start_xserver (manager))
|
||||
g_critical ("Could not start Xserver");
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
window_unmanaged_cb (MetaWindow *window,
|
||||
MetaXWaylandManager *manager)
|
||||
{
|
||||
manager->x11_windows = g_list_remove (manager->x11_windows, window);
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
window_unmanaged_cb,
|
||||
manager);
|
||||
if (!manager->x11_windows)
|
||||
{
|
||||
g_debug ("All X11 windows gone, setting shutdown timeout");
|
||||
manager->xserver_grace_period_id =
|
||||
g_timeout_add_seconds (10, shutdown_xwayland_cb, manager);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
window_created_cb (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
MetaXWaylandManager *manager)
|
||||
{
|
||||
if (window->xwindow &&
|
||||
meta_window_get_client_pid (window) != getpid ())
|
||||
{
|
||||
manager->x11_windows = g_list_prepend (manager->x11_windows, window);
|
||||
g_signal_connect (window, "unmanaged",
|
||||
G_CALLBACK (window_unmanaged_cb), manager);
|
||||
if (manager->xserver_grace_period_id)
|
||||
{
|
||||
g_source_remove (manager->xserver_grace_period_id);
|
||||
manager->xserver_grace_period_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_xwayland_stop_xserver (MetaXWaylandManager *manager)
|
||||
{
|
||||
if (manager->proc)
|
||||
g_subprocess_send_signal (manager->proc, SIGTERM);
|
||||
g_signal_handlers_disconnect_by_func (meta_get_display (),
|
||||
window_created_cb,
|
||||
manager);
|
||||
g_clear_object (&manager->xserver_died_cancellable);
|
||||
g_clear_object (&manager->proc);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_xwayland_init (MetaXWaylandManager *manager,
|
||||
struct wl_display *wl_display)
|
||||
{
|
||||
MetaDisplayPolicy policy;
|
||||
gboolean fatal;
|
||||
|
||||
if (!manager->public_connection.name)
|
||||
{
|
||||
if (!choose_xdisplay (manager, &manager->public_connection))
|
||||
return FALSE;
|
||||
if (!choose_xdisplay (manager, &manager->private_connection))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!open_display_sockets (manager,
|
||||
manager->public_connection.display_index,
|
||||
&manager->public_connection.abstract_fd,
|
||||
&manager->public_connection.unix_fd,
|
||||
&fatal))
|
||||
return FALSE;
|
||||
|
||||
if (!open_display_sockets (manager,
|
||||
manager->private_connection.display_index,
|
||||
&manager->private_connection.abstract_fd,
|
||||
&manager->private_connection.unix_fd,
|
||||
&fatal))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!prepare_auth_file (manager))
|
||||
return FALSE;
|
||||
|
||||
manager->wayland_display = wl_display;
|
||||
return meta_xwayland_init_xserver (manager);
|
||||
policy = meta_get_x11_display_policy ();
|
||||
|
||||
if (policy == META_DISPLAY_POLICY_MANDATORY)
|
||||
{
|
||||
return meta_xwayland_start_xserver (manager);
|
||||
}
|
||||
else if (policy == META_DISPLAY_POLICY_ON_DEMAND)
|
||||
{
|
||||
g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN,
|
||||
xdisplay_connection_activity_cb, manager);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_x11_display_closing (MetaDisplay *display)
|
||||
{
|
||||
meta_xwayland_shutdown_dnd ();
|
||||
g_signal_handlers_disconnect_by_func (display,
|
||||
on_x11_display_closing,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* To be called right after connecting */
|
||||
void
|
||||
meta_xwayland_complete_init (MetaDisplay *display)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaXWaylandManager *manager = &compositor->xwayland_manager;
|
||||
|
||||
/* We install an X IO error handler in addition to the child watch,
|
||||
because after Xlib connects our child watch may not be called soon
|
||||
enough, and therefore we won't crash when X exits (and most important
|
||||
@@ -654,31 +812,41 @@ meta_xwayland_complete_init (MetaDisplay *display)
|
||||
g_signal_connect (display, "x11-display-closing",
|
||||
G_CALLBACK (on_x11_display_closing), NULL);
|
||||
meta_xwayland_init_dnd ();
|
||||
|
||||
g_signal_connect (meta_get_display (), "window-created",
|
||||
G_CALLBACK (window_created_cb), manager);
|
||||
}
|
||||
|
||||
void
|
||||
meta_xwayland_stop (MetaXWaylandManager *manager)
|
||||
meta_xwayland_shutdown (MetaXWaylandManager *manager)
|
||||
{
|
||||
char path[256];
|
||||
|
||||
g_cancellable_cancel (manager->xserver_died_cancellable);
|
||||
g_clear_object (&manager->proc);
|
||||
g_clear_object (&manager->xserver_died_cancellable);
|
||||
|
||||
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
|
||||
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index);
|
||||
unlink (path);
|
||||
|
||||
g_clear_pointer (&manager->display_name, g_free);
|
||||
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index);
|
||||
unlink (path);
|
||||
|
||||
g_clear_pointer (&manager->public_connection.name, g_free);
|
||||
g_clear_pointer (&manager->private_connection.name, g_free);
|
||||
if (manager->public_connection.lock_file)
|
||||
{
|
||||
unlink (manager->public_connection.lock_file);
|
||||
g_clear_pointer (&manager->public_connection.lock_file, g_free);
|
||||
}
|
||||
if (manager->private_connection.lock_file)
|
||||
{
|
||||
unlink (manager->private_connection.lock_file);
|
||||
g_clear_pointer (&manager->private_connection.lock_file, g_free);
|
||||
}
|
||||
if (manager->auth_file)
|
||||
{
|
||||
unlink (manager->auth_file);
|
||||
g_clear_pointer (&manager->auth_file, g_free);
|
||||
}
|
||||
if (manager->lock_file)
|
||||
{
|
||||
unlink (manager->lock_file);
|
||||
g_clear_pointer (&manager->lock_file, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -144,6 +144,8 @@ struct _MetaX11Display
|
||||
|
||||
guint keys_grabbed : 1;
|
||||
|
||||
guint closing : 1;
|
||||
|
||||
/* we use property updates as sentinels for certain window focus events
|
||||
* to avoid some race conditions on EnterNotify events
|
||||
*/
|
||||
@@ -249,4 +251,6 @@ void meta_x11_display_set_input_focus (MetaX11Display *x11_display,
|
||||
Window xwindow,
|
||||
guint32 timestamp);
|
||||
|
||||
const gchar * meta_x11_get_display_name (void);
|
||||
|
||||
#endif /* META_X11_DISPLAY_PRIVATE_H */
|
||||
|
@@ -129,17 +129,19 @@ meta_x11_display_dispose (GObject *object)
|
||||
{
|
||||
MetaX11Display *x11_display = META_X11_DISPLAY (object);
|
||||
|
||||
x11_display->closing = TRUE;
|
||||
|
||||
meta_x11_startup_notification_release (x11_display);
|
||||
|
||||
meta_prefs_remove_listener (prefs_changed_callback, x11_display);
|
||||
|
||||
meta_x11_display_ungrab_keys (x11_display);
|
||||
|
||||
g_clear_object (&x11_display->x11_stack);
|
||||
|
||||
meta_x11_selection_shutdown (x11_display);
|
||||
meta_x11_display_unmanage_windows (x11_display);
|
||||
|
||||
g_clear_object (&x11_display->x11_stack);
|
||||
|
||||
if (x11_display->ui)
|
||||
{
|
||||
meta_ui_free (x11_display->ui);
|
||||
@@ -182,21 +184,8 @@ meta_x11_display_dispose (GObject *object)
|
||||
|
||||
if (x11_display->guard_window != None)
|
||||
{
|
||||
MetaStackTracker *stack_tracker = x11_display->display->stack_tracker;
|
||||
|
||||
if (stack_tracker)
|
||||
{
|
||||
unsigned long serial;
|
||||
|
||||
serial = XNextRequest (x11_display->xdisplay);
|
||||
meta_stack_tracker_record_remove (stack_tracker,
|
||||
x11_display->guard_window,
|
||||
serial);
|
||||
}
|
||||
|
||||
XUnmapWindow (x11_display->xdisplay, x11_display->guard_window);
|
||||
XDestroyWindow (x11_display->xdisplay, x11_display->guard_window);
|
||||
|
||||
x11_display->guard_window = None;
|
||||
}
|
||||
|
||||
@@ -988,6 +977,25 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings)
|
||||
gnome_wm_keybindings = wm_keybindings;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
meta_x11_get_display_name (void)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
return meta_wayland_get_xwayland_display_name (compositor);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return g_getenv ("DISPLAY");
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_x11_init_gdk_display (GError **error)
|
||||
{
|
||||
@@ -996,7 +1004,7 @@ meta_x11_init_gdk_display (GError **error)
|
||||
const char *gdk_gl_env = NULL;
|
||||
Display *xdisplay;
|
||||
|
||||
xdisplay_name = g_getenv ("DISPLAY");
|
||||
xdisplay_name = meta_x11_get_display_name ();
|
||||
if (!xdisplay_name)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
|
Reference in New Issue
Block a user