diff --git a/src/core/display-private.h b/src/core/display-private.h index 1541a6318..d8064f12e 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -426,8 +426,14 @@ MetaWindow *meta_display_get_window_from_id (MetaDisplay *display, uint64_t window_id); uint64_t meta_display_generate_window_id (MetaDisplay *display); -gboolean meta_display_init_x11 (MetaDisplay *display, - GError **error); +void meta_display_init_x11 (MetaDisplay *display, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean meta_display_init_x11_finish (MetaDisplay *display, + GAsyncResult *result, + GError **error); + void meta_display_shutdown_x11 (MetaDisplay *display); #endif diff --git a/src/core/display.c b/src/core/display.c index 31346fae4..13f54c54b 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -656,13 +656,45 @@ on_ui_scaling_factor_changed (MetaSettings *settings, meta_display_reload_cursor (display); } -gboolean -meta_display_init_x11 (MetaDisplay *display, - GError **error) +static gboolean +meta_display_init_x11_display (MetaDisplay *display, + GError **error) { MetaX11Display *x11_display; - g_assert (display->x11_display == NULL); + x11_display = meta_x11_display_new (display, error); + if (!x11_display) + return FALSE; + + display->x11_display = x11_display; + g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0); + + meta_x11_display_create_guard_window (x11_display); + + if (!display->display_opening) + { + g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); + meta_display_manage_all_xwindows (display); + meta_compositor_redirect_x11_windows (display->compositor); + } + + return TRUE; +} + +#ifdef HAVE_WAYLAND +gboolean +meta_display_init_x11_finish (MetaDisplay *display, + GAsyncResult *result, + GError **error) +{ + MetaX11Display *x11_display; + + g_assert (g_task_get_source_tag (G_TASK (result)) == meta_display_init_x11); + + if (!g_task_propagate_boolean (G_TASK (result), error)) + return FALSE; + if (display->x11_display) + return TRUE; x11_display = meta_x11_display_new (display, error); if (!x11_display) @@ -684,6 +716,31 @@ meta_display_init_x11 (MetaDisplay *display, return TRUE; } +void +meta_display_init_x11 (MetaDisplay *display, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (display, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_display_init_x11); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +on_x11_initialized (MetaDisplay *display, + GAsyncResult *result, + gpointer user_data) +{ + if (!meta_display_init_x11_finish (display, result, NULL)) + g_critical ("Failed to init X11 display"); +} +#endif + void meta_display_shutdown_x11 (MetaDisplay *display) { @@ -791,16 +848,25 @@ meta_display_open (void) display->selection = meta_selection_new (display); meta_clipboard_manager_init (display); - if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY) +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) { - if (!meta_display_init_x11 (display, &error)) - g_error ("Failed to start Xwayland: %s", error->message); + if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY) + { + meta_display_init_x11 (display, NULL, + (GAsyncReadyCallback) on_x11_initialized, + NULL); + } - timestamp = display->x11_display->timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); } else +#endif { - timestamp = meta_display_get_current_time_roundtrip (display); + if (!meta_display_init_x11_display (display, &error)) + g_error ("Failed to init X11 display: %s", error->message); + + timestamp = display->x11_display->timestamp; } display->last_focus_time = timestamp; diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 07b203293..8e17d5401 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -545,6 +545,17 @@ xserver_finished_init (MetaXWaylandManager *manager) g_clear_pointer (&manager->init_loop, g_main_loop_unref); } +static void +on_init_x11_cb (MetaDisplay *display, + GAsyncResult *result, + gpointer user_data) +{ + g_autoptr (GError) error = NULL; + + if (!meta_display_init_x11_finish (display, result, &error)) + g_warning ("Failed to initialize X11 display: %s\n", error->message); +} + static gboolean on_displayfd_ready (int fd, GIOCondition condition, @@ -560,7 +571,10 @@ on_displayfd_ready (int fd, xserver_finished_init (manager); if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND) - meta_display_init_x11 (display, NULL); + { + meta_display_init_x11 (display, NULL, + (GAsyncReadyCallback) on_init_x11_cb, NULL); + } return G_SOURCE_REMOVE; }