From a4c94065fc10260be15ae4252db5a16d76153265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org> Date: Sat, 3 Feb 2024 15:53:17 +0100 Subject: [PATCH] wayland: Use WleGtkSocket and WleGtkPlug from libwlembed --- configure.ac | 4 + savers/Makefile.am | 6 ++ savers/floaters.c | 9 ++ savers/popsquares.c | 9 ++ savers/slideshow.c | 9 ++ src/Makefile.am | 38 +++++++ src/gs-job.c | 50 +++++++--- src/gs-lock-plug.c | 9 ++ src/gs-manager.c | 54 ++++++++-- src/gs-manager.h | 7 ++ src/gs-window-x11.c | 150 +++++++++++++++++----------- src/xfce-desktop-utils.c | 101 ++++++++++++------- src/xfce-desktop-utils.h | 26 +++-- src/xfce4-screensaver-dialog.c | 8 ++ src/xfce4-screensaver-preferences.c | 54 ++++++++-- 15 files changed, 399 insertions(+), 135 deletions(-) diff --git a/configure.ac b/configure.ac index 03a388df..fc1bf886 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,8 @@ m4_define([libxscrnsaver_min_version], [1.2.3]) m4_define([libxklavier_min_version], [5.2]) m4_define([libwnck_min_version], [3.20]) +m4_define([libwlembed_min_version], [0.0.0]) + XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [glib_min_version]) XDT_CHECK_PACKAGE([GIO], [gio-2.0], [glib_min_version]) XDT_CHECK_PACKAGE([GTK], [gtk+-3.0], [gtk_min_version]) @@ -85,6 +87,8 @@ XDT_CHECK_OPTIONAL_FEATURE([WAYLAND], [wayland], [ XDT_FEATURE_DEPENDENCY([GDK_WAYLAND], [gdk-wayland-3.0], [gtk_min_version]) + XDT_FEATURE_DEPENDENCY([LIBWLEMBED], [libwlembed-0], [libwlembed_min_version]) + XDT_FEATURE_DEPENDENCY([LIBWLEMBED_GTK3], [libwlembed-gtk3-0], [libwlembed_min_version]) ], [the Wayland windowing system]) if test x"$ENABLE_X11" != x"yes" -a x"$ENABLE_WAYLAND" != x"yes"; then diff --git a/savers/Makefile.am b/savers/Makefile.am index 58f3c510..f534ac6e 100644 --- a/savers/Makefile.am +++ b/savers/Makefile.am @@ -78,6 +78,7 @@ floaters_CFLAGS = \ $(GLIB_CFLAGS) \ $(GTK_CFLAGS) \ $(LIBXFCE4UTIL_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ $(NULL) floaters_LDADD = \ @@ -85,6 +86,7 @@ floaters_LDADD = \ $(GLIB_LIBS) \ $(GTK_LIBS) \ $(LIBXFCE4UTIL_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ $(NULL) popsquares_SOURCES = \ @@ -97,6 +99,7 @@ popsquares_CFLAGS = \ $(GLIB_CFLAGS) \ $(GTK_CFLAGS) \ $(LIBXFCE4UTIL_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ $(NULL) popsquares_LDADD = \ @@ -104,6 +107,7 @@ popsquares_LDADD = \ $(GLIB_LIBS) \ $(GTK_LIBS) \ $(LIBXFCE4UTIL_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ $(NULL) slideshow_SOURCES = \ @@ -118,6 +122,7 @@ slideshow_CFLAGS = \ $(GLIB_CFLAGS) \ $(GTK_CFLAGS) \ $(LIBXFCE4UTIL_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ $(NULL) slideshow_LDADD = \ @@ -125,6 +130,7 @@ slideshow_LDADD = \ $(GLIB_LIBS) \ $(GTK_LIBS) \ $(LIBXFCE4UTIL_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ $(NULL) EXTRA_DIST = \ diff --git a/savers/floaters.c b/savers/floaters.c index 6bc1c433..4a97d09e 100644 --- a/savers/floaters.c +++ b/savers/floaters.c @@ -38,6 +38,10 @@ #include <gdk/gdkx.h> #include <gtk/gtkx.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include <libxfce4util/libxfce4util.h> @@ -1152,6 +1156,11 @@ main (int argc, if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { window = gtk_plug_new (strtoul (g_getenv ("XSCREENSAVER_WINDOW"), NULL, 0)); } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + window = wle_gtk_plug_new (g_getenv ("XSCREENSAVER_WINDOW")); + } #endif gtk_widget_set_app_paintable (window, TRUE); diff --git a/savers/popsquares.c b/savers/popsquares.c index 1a4fc40c..dcba4bcd 100644 --- a/savers/popsquares.c +++ b/savers/popsquares.c @@ -29,6 +29,10 @@ #include <gdk/gdkx.h> #include <gtk/gtkx.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include <libxfce4util/libxfce4util.h> @@ -57,6 +61,11 @@ main (int argc, if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { window = gtk_plug_new (strtoul (g_getenv ("XSCREENSAVER_WINDOW"), NULL, 0)); } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + window = wle_gtk_plug_new (g_getenv ("XSCREENSAVER_WINDOW")); + } #endif gtk_widget_set_app_paintable (window, TRUE); g_signal_connect (G_OBJECT (window), "destroy", diff --git a/savers/slideshow.c b/savers/slideshow.c index c62c52b5..c08c3737 100644 --- a/savers/slideshow.c +++ b/savers/slideshow.c @@ -32,6 +32,10 @@ #include <gdk/gdkx.h> #include <gtk/gtkx.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include <libxfce4util/libxfce4util.h> @@ -97,6 +101,11 @@ main (int argc, char **argv) { if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { window = gtk_plug_new (strtoul (g_getenv ("XSCREENSAVER_WINDOW"), NULL, 0)); } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + window = wle_gtk_plug_new (g_getenv ("XSCREENSAVER_WINDOW")); + } #endif gtk_widget_set_app_paintable (window, TRUE); g_signal_connect (G_OBJECT (window), "destroy", diff --git a/src/Makefile.am b/src/Makefile.am index 5770f04d..3a3e8ab6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,6 +104,12 @@ test_window_SOURCES = \ subprocs.h \ xfce-desktop-utils.c \ xfce-desktop-utils.h \ + gs-manager.c \ + gs-manager.h \ + gs-theme-manager.c \ + gs-theme-manager.h \ + gs-job.c \ + gs-job.h \ $(NULL) test_window_CFLAGS = \ @@ -112,6 +118,7 @@ test_window_CFLAGS = \ $(DBUS_GLIB_CFLAGS) \ $(LIBXFCE4UI_CFLAGS) \ $(XFCONF_CFLAGS) \ + $(GARCON_GTK3_CFLAGS) \ $(NULL) test_window_LDADD = \ @@ -120,6 +127,7 @@ test_window_LDADD = \ $(DBUS_GLIB_LIBS) \ $(LIBXFCE4UI_LIBS) \ $(XFCONF_LIBS) \ + $(GARCON_GTK3_LIBS) \ $(NULL) if ENABLE_X11 @@ -141,6 +149,18 @@ test_window_LDADD += \ $(NULL) endif +if ENABLE_WAYLAND +test_window_CFLAGS += \ + $(LIBWLEMBED_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ + $(NULL) + +test_window_LDADD += \ + $(LIBWLEMBED_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ + $(NULL) +endif + xfce4_screensaver_dialog_built_sources = \ xfce4-screensaver-dialog-css.h \ xfce4-screensaver-dialog-ui.h @@ -179,6 +199,7 @@ xfce4_screensaver_dialog_CFLAGS = \ $(LIBXFCE4UI_CFLAGS) \ $(XFCONF_CFLAGS) \ $(AUTH_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ $(NULL) xfce4_screensaver_dialog_LDADD = \ @@ -188,6 +209,7 @@ xfce4_screensaver_dialog_LDADD = \ $(LIBXFCE4UI_LIBS) \ $(XFCONF_LIBS) \ $(AUTH_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ $(NULL) if ENABLE_X11 @@ -296,6 +318,18 @@ xfce4_screensaver_LDADD += \ $(NULL) endif +if ENABLE_WAYLAND +xfce4_screensaver_CFLAGS += \ + $(LIBWLEMBED_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ + $(NULL) + +xfce4_screensaver_LDADD += \ + $(LIBWLEMBED_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ + $(NULL) +endif + xfce4_screensaver_LDFLAGS = -export-dynamic xfce4_screensaver_preferences_built_sources = \ @@ -325,6 +359,8 @@ xfce4_screensaver_preferences_CFLAGS = \ $(XFCONF_CFLAGS) \ $(GARCON_GTK3_CFLAGS) \ $(LIBXKLAVIER_CFLAGS) \ + $(LIBWLEMBED_CFLAGS) \ + $(LIBWLEMBED_GTK3_CFLAGS) \ $(NULL) xfce4_screensaver_preferences_LDADD = \ @@ -334,6 +370,8 @@ xfce4_screensaver_preferences_LDADD = \ $(XFCONF_LIBS) \ $(GARCON_GTK3_LIBS) \ $(LIBXKLAVIER_LIBS) \ + $(LIBWLEMBED_LIBS) \ + $(LIBWLEMBED_GTK3_LIBS) \ $(NULL) if MAINTAINER_MODE diff --git a/src/gs-job.c b/src/gs-job.c index af6cfdf8..7031a9e6 100644 --- a/src/gs-job.c +++ b/src/gs-job.c @@ -37,6 +37,11 @@ #include <gdk/gdkx.h> #include <gtk/gtkx.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed/libwlembed.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) #include <sys/resource.h> @@ -47,6 +52,7 @@ #include "gs-prefs.h" #include "gs-theme-manager.h" #include "subprocs.h" +#include "xfce-desktop-utils.h" static void gs_job_finalize (GObject *object); @@ -83,6 +89,11 @@ widget_get_id_string (GtkWidget *widget) { id = g_strdup_printf ("0x%lX", gtk_socket_get_id (GTK_SOCKET (widget))); } #endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + id = g_strdup (wle_gtk_socket_get_embedding_token (WLE_GTK_SOCKET (widget))); + } +#endif return id; } @@ -281,13 +292,25 @@ get_env_vars (GtkWidget *widget) { "LANG", "LANGUAGE", "DBUS_SESSION_BUS_ADDRESS", - "G_DEBUG" + "G_DEBUG", + "LD_LIBRARY_PATH", + "XDG_RUNTIME_DIR", }; env = g_ptr_array_new (); display_name = gdk_display_get_name (gtk_widget_get_display (widget)); - g_ptr_array_add (env, g_strdup_printf ("DISPLAY=%s", display_name)); +#ifdef ENABLE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { + g_ptr_array_add (env, g_strdup_printf ("DISPLAY=%s", display_name)); + } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + g_ptr_array_add (env, g_strdup_printf ("WAYLAND_DISPLAY=%s", display_name)); + g_ptr_array_add (env, g_strdup_printf ("DISPLAY=%s", g_getenv ("DISPLAY"))); + } +#endif g_ptr_array_add (env, g_strdup_printf ("HOME=%s", g_get_home_dir ())); @@ -342,17 +365,18 @@ spawn_on_widget (GtkWidget *widget, env = get_env_vars (widget); error = NULL; - result = g_spawn_async_with_pipes (NULL, - argv, - (char **)env->pdata, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, - NULL, - &child_pid, - NULL, - NULL, - watch_func != NULL ? &standard_error : NULL, - &error); + result = spawn_async_with_pipes (widget, + NULL, + argv, + (char **)env->pdata, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &child_pid, + NULL, + NULL, + watch_func != NULL ? &standard_error : NULL, + &error); for (guint i = 0; i < env->len; i++) { g_free (g_ptr_array_index (env, i)); diff --git a/src/gs-lock-plug.c b/src/gs-lock-plug.c index 8b535d68..f2c68789 100644 --- a/src/gs-lock-plug.c +++ b/src/gs-lock-plug.c @@ -43,6 +43,10 @@ #include "xfcekbd-indicator.h" #endif #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include <libxfce4util/libxfce4util.h> #include <xfconf/xfconf.h> @@ -1607,6 +1611,11 @@ gs_lock_plug_init (GSLockPlug *plug) { if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { plug->priv->plug_widget = gtk_plug_new (0); } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + plug->priv->plug_widget = wle_gtk_plug_new (g_getenv ("WLE_EMBEDDING_TOKEN")); + } #endif g_object_set_data (G_OBJECT (plug->priv->plug_widget), "gs-lock-plug", plug); diff --git a/src/gs-manager.c b/src/gs-manager.c index a8c53768..dae02976 100644 --- a/src/gs-manager.c +++ b/src/gs-manager.c @@ -29,6 +29,10 @@ #include <gdk/gdkx.h> #include "gs-grab.h" #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include "gs-debug.h" #include "gs-job.h" @@ -61,6 +65,9 @@ struct GSManagerPrivate { #ifdef ENABLE_X11 GSGrab *grab; #endif +#ifdef ENABLE_WAYLAND + WleEmbeddedCompositor *compositor; +#endif }; enum { @@ -445,6 +452,17 @@ gs_manager_init (GSManager *manager) { NULL, (GDestroyNotify) remove_job); manager->priv->windows = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) gs_window_destroy); + +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + GError *error = NULL; + manager->priv->compositor = wle_gtk_create_embedded_compositor ("xfce4-screensaver", &error); + if (manager->priv->compositor == NULL) { + g_critical ("Failed to create embedded compositor: %s", error->message); + g_error_free (error); + } + } +#endif } static void @@ -958,6 +976,12 @@ gs_manager_finalize (GObject *object) { g_object_unref (manager->priv->prefs); +#ifdef ENABLE_WAYLAND + if (manager->priv->compositor != NULL) { + g_object_unref (manager->priv->compositor); + } +#endif + G_OBJECT_CLASS (gs_manager_parent_class)->finalize (object); } @@ -983,14 +1007,13 @@ gs_manager_create_windows (GSManager *manager) { GSManager * gs_manager_new (void) { - GObject *manager; - GSManager *mgr; - - manager = g_object_new (GS_TYPE_MANAGER, NULL); - - mgr = GS_MANAGER (manager); - - return mgr; + static GSManager *manager = NULL; + if (manager == NULL) { + manager = g_object_new (GS_TYPE_MANAGER, NULL); + } else { + g_object_ref (manager); + } + return manager; } static void @@ -1022,6 +1045,14 @@ gs_manager_activate (GSManager *manager) { } #endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + if (manager->priv->compositor == NULL) { + return FALSE; + } + } +#endif + gs_manager_create_windows (GS_MANAGER (manager)); manager->priv->active = TRUE; @@ -1101,3 +1132,10 @@ gs_manager_request_unlock (GSManager *manager) { return TRUE; } + +#ifdef ENABLE_WAYLAND +WleEmbeddedCompositor * +gs_manager_get_compositor (GSManager *manager) { + return manager->priv->compositor; +} +#endif diff --git a/src/gs-manager.h b/src/gs-manager.h index fa615b48..edb5ebb6 100644 --- a/src/gs-manager.h +++ b/src/gs-manager.h @@ -24,6 +24,9 @@ #define SRC_GS_MANAGER_H_ #include "gs-prefs.h" +#ifdef ENABLE_WAYLAND +#include <libwlembed/libwlembed.h> +#endif G_BEGIN_DECLS @@ -72,6 +75,10 @@ void gs_manager_show_message (GSManager *manager, const char *icon); gboolean gs_manager_request_unlock (GSManager *manager); +#ifdef ENABLE_WAYLAND +WleEmbeddedCompositor *gs_manager_get_compositor (GSManager *manager); +#endif + G_END_DECLS #endif /* SRC_GS_MANAGER_H_ */ diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c index 6546c33b..91dac297 100644 --- a/src/gs-window-x11.c +++ b/src/gs-window-x11.c @@ -35,6 +35,10 @@ #include <gtk/gtkx.h> #include <X11/extensions/shape.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include "gs-debug.h" #include "gs-marshal.h" @@ -42,6 +46,7 @@ #include "gs-window.h" #include "subprocs.h" #include "xfce-desktop-utils.h" +#include "gs-manager.h" static void gs_window_finalize (GObject *object); @@ -60,6 +65,7 @@ enum { #define INFO_BAR_SECONDS 30 struct GSWindowPrivate { + GSManager *manager; GdkMonitor *monitor; GdkRectangle geometry; @@ -796,7 +802,7 @@ error_watch (GIOChannel *source, } static gboolean -spawn_on_window (GSWindow *window, +spawn_on_window (GtkWidget *socket, char *command, int *pid, GIOFunc watch_func, @@ -822,18 +828,19 @@ spawn_on_window (GSWindow *window, } error = NULL; - envp = spawn_make_environment_for_display (gtk_widget_get_display (GTK_WIDGET (window)), NULL); - result = g_spawn_async_with_pipes (NULL, - argv, - envp, - G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, - NULL, - NULL, - &child_pid, - NULL, - &standard_output, - redirect_stderr ? &standard_error : NULL, - &error); + envp = spawn_make_environment_for_display (socket); + result = spawn_async_with_pipes (socket, + NULL, + argv, + envp, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, + NULL, + NULL, + &child_pid, + NULL, + &standard_output, + redirect_stderr ? &standard_error : NULL, + &error); if (!result) { gs_debug ("Could not start command '%s': %s", command, error->message); @@ -884,15 +891,13 @@ spawn_on_window (GSWindow *window, } static void -lock_plug_added (GtkWidget *widget, - GSWindow *window) { - gtk_widget_show (widget); +lock_plug_added (GSWindow *window) { + gtk_widget_show (window->priv->lock_socket); } static gboolean -lock_plug_removed (GtkWidget *widget, - GSWindow *window) { - gtk_widget_hide (widget); +lock_plug_removed (GSWindow *window) { + gtk_widget_hide (window->priv->lock_socket); gtk_container_remove (GTK_CONTAINER (window->priv->overlay), GTK_WIDGET (window->priv->lock_box)); window->priv->lock_box = NULL; @@ -903,15 +908,13 @@ lock_plug_removed (GtkWidget *widget, } static void -keyboard_plug_added (GtkWidget *widget, - GSWindow *window) { - gtk_widget_show (widget); +keyboard_plug_added (GSWindow *window) { + gtk_widget_show (window->priv->keyboard_socket); } static gboolean -keyboard_plug_removed (GtkWidget *widget, - GSWindow *window) { - gtk_widget_hide (widget); +keyboard_plug_removed (GSWindow *window) { + gtk_widget_hide (window->priv->keyboard_socket); gtk_container_remove (GTK_CONTAINER (window->priv->overlay), GTK_WIDGET (window->priv->keyboard_socket)); return TRUE; @@ -992,6 +995,11 @@ socket_new (GSWindow *window) { if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { return gtk_socket_new (); } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + return wle_gtk_socket_new (gs_manager_get_compositor (window->priv->manager)); + } #endif return NULL; } @@ -1032,10 +1040,10 @@ create_keyboard_socket (GSWindow *window, g_signal_connect (window->priv->keyboard_socket, "destroy", G_CALLBACK (keyboard_socket_destroyed), window); - g_signal_connect (window->priv->keyboard_socket, "plug_added", - G_CALLBACK (keyboard_plug_added), window); - g_signal_connect (window->priv->keyboard_socket, "plug_removed", - G_CALLBACK (keyboard_plug_removed), window); + g_signal_connect_swapped (window->priv->keyboard_socket, "plug_added", + G_CALLBACK (keyboard_plug_added), window); + g_signal_connect_swapped (window->priv->keyboard_socket, "plug_removed", + G_CALLBACK (keyboard_plug_removed), window); gtk_overlay_add_overlay (GTK_OVERLAY (window->priv->overlay), window->priv->keyboard_socket); #ifdef ENABLE_X11 @@ -1099,6 +1107,12 @@ keyboard_process_finish (GSWindow *window) { g_spawn_close_pid (window->priv->keyboard_pid); window->priv->keyboard_pid = 0; } + +#ifdef ENABLE_WAYLAND + if (window->priv->keyboard_socket != NULL) { + keyboard_plug_removed (window); + } +#endif } static gboolean @@ -1120,12 +1134,16 @@ keyboard_process_watch (GIOChannel *source, switch (status) { case G_IO_STATUS_NORMAL: { - gulong id; - char c; - gs_debug ("Keyboard command output: %s", line); - if (1 == sscanf (line, " %lu %c", &id, &c)) { - create_keyboard_socket (window, id); +#ifdef ENABLE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { + gulong id; + char c; + gs_debug ("Keyboard command output: %s", line); + if (1 == sscanf (line, " %lu %c", &id, &c)) { + create_keyboard_socket (window, id); + } } +#endif } break; case G_IO_STATUS_EOF: @@ -1134,7 +1152,7 @@ keyboard_process_watch (GIOChannel *source, case G_IO_STATUS_ERROR: gs_debug ("Error reading from child: %s\n", error->message); g_error_free (error); - return FALSE; + finished = TRUE; case G_IO_STATUS_AGAIN: default: break; @@ -1162,13 +1180,19 @@ embed_keyboard (GSWindow *window) { || window->priv->prefs->keyboard_command == NULL) return; +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + create_keyboard_socket (window, 0); + } +#endif + gs_debug ("Adding embedded keyboard widget"); /* FIXME: verify command is safe */ gs_debug ("Running command: %s", window->priv->prefs->keyboard_command); - res = spawn_on_window (window, + res = spawn_on_window (window->priv->keyboard_socket, window->priv->prefs->keyboard_command, &window->priv->keyboard_pid, (GIOFunc)keyboard_process_watch, @@ -1202,10 +1226,10 @@ create_lock_socket (GSWindow *window, G_CALLBACK (lock_socket_show), window); g_signal_connect (window->priv->lock_socket, "destroy", G_CALLBACK (lock_socket_destroyed), window); - g_signal_connect (window->priv->lock_socket, "plug_added", - G_CALLBACK (lock_plug_added), window); - g_signal_connect (window->priv->lock_socket, "plug_removed", - G_CALLBACK (lock_plug_removed), window); + g_signal_connect_swapped (window->priv->lock_socket, "plug-added", + G_CALLBACK (lock_plug_added), window); + g_signal_connect_swapped (window->priv->lock_socket, "plug-removed", + G_CALLBACK (lock_plug_removed), window); #ifdef ENABLE_X11 if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { @@ -1260,10 +1284,14 @@ popdown_dialog (GSWindow *window) { gs_window_dialog_finish (window); gtk_widget_show (window->priv->drawing_area); - // TODO: Avoids a critical warning due to GTK bug - // remove this if https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6841 get merged - gtk_widget_set_can_focus (window->priv->drawing_area, TRUE); - gtk_widget_grab_focus (window->priv->drawing_area); +#ifdef ENABLE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { + // TODO: Avoids a critical warning due to GTK bug + // remove this if https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6841 get merged + gtk_widget_set_can_focus (window->priv->drawing_area, TRUE); + gtk_widget_grab_focus (window->priv->drawing_area); + } +#endif gs_window_clear (window); set_invisible_cursor (gtk_widget_get_window (GTK_WIDGET (window)), TRUE); @@ -1274,14 +1302,8 @@ popdown_dialog (GSWindow *window) { window->priv->last_x = -1; window->priv->last_y = -1; - if (window->priv->lock_box != NULL) { - gtk_container_remove (GTK_CONTAINER (window->priv->overlay), GTK_WIDGET (window->priv->lock_box)); - window->priv->lock_box = NULL; - } - - if (window->priv->overlay != NULL) { - gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->overlay)); - window->priv->overlay = NULL; + if (window->priv->lock_socket != NULL) { + lock_plug_removed (window); } remove_popup_dialog_idle (window); @@ -1309,11 +1331,15 @@ dialog_process_watch (GIOChannel *source, gs_debug ("Command output: %s", line); if (strstr (line, "WINDOW ID=") != NULL) { - gulong id; - char c; - if (1 == sscanf (line, " WINDOW ID= %lu %c", &id, &c)) { - create_lock_socket (window, id); +#ifdef ENABLE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { + gulong id; + char c; + if (1 == sscanf (line, " WINDOW ID= %lu %c", &id, &c)) { + create_lock_socket (window, id); + } } +#endif } else if (strstr (line, "NOTICE=") != NULL) { if (strstr (line, "NOTICE=AUTH FAILED") != NULL) { gs_debug ("Authorization failed"); @@ -1338,7 +1364,7 @@ dialog_process_watch (GIOChannel *source, case G_IO_STATUS_ERROR: gs_debug ("Error reading from child: %s\n", error->message); g_error_free (error); - return FALSE; + finished = TRUE; case G_IO_STATUS_AGAIN: default: break; @@ -1456,8 +1482,14 @@ popup_dialog (GSWindow *window) { gtk_widget_queue_draw (GTK_WIDGET (window)); set_invisible_cursor (gtk_widget_get_window (GTK_WIDGET (window)), FALSE); +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + create_lock_socket (window, 0); + } +#endif + gs_debug ("Executing %s", command->str); - result = spawn_on_window (window, + result = spawn_on_window (window->priv->lock_socket, command->str, &window->priv->lock_pid, (GIOFunc)dialog_process_watch, @@ -1979,6 +2011,7 @@ gs_window_init (GSWindow *window) { window->priv->last_x = -1; window->priv->last_y = -1; + window->priv->manager = gs_manager_new (); window->priv->prefs = gs_prefs_new(); gtk_window_set_decorated (GTK_WINDOW (window), FALSE); @@ -2070,6 +2103,7 @@ gs_window_finalize (GObject *object) { gs_window_dialog_finish (window); g_object_unref (window->priv->prefs); + g_object_unref (window->priv->manager); G_OBJECT_CLASS (gs_window_parent_class)->finalize (object); } diff --git a/src/xfce-desktop-utils.c b/src/xfce-desktop-utils.c index 16c305d6..ba2651c0 100644 --- a/src/xfce-desktop-utils.c +++ b/src/xfce-desktop-utils.c @@ -25,16 +25,18 @@ #include <config.h> -#include <string.h> #include <gio/gio.h> -#include <glib.h> -#include <gdk/gdk.h> -#include <gtk/gtk.h> +#ifdef ENABLE_X11 +#include <gdk/gdkx.h> +#endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include <libxfce4util/libxfce4util.h> -#include <xfce-desktop-utils.h> - +#include "xfce-desktop-utils.h" #include "gs-debug.h" /** @@ -79,40 +81,65 @@ xfce_gdk_spawn_command_line_on_screen (GdkScreen *screen, } gchar ** -spawn_make_environment_for_display (GdkDisplay *display, - gchar **envp) { - gchar **retval = NULL; - const gchar *display_name; - gint display_index = -1; - gint i, env_len; - gboolean own_envp = FALSE; - - g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); - - if (envp == NULL) { - envp = g_get_environ (); - own_envp = TRUE; +spawn_make_environment_for_display (GtkWidget *socket) { + gchar **retval = NULL; + const gchar *display_name = gdk_display_get_name (gdk_display_get_default ()); + gchar **envp = g_get_environ (); + gint env_len = g_strv_length (envp); + +#ifdef ENABLE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { + retval = g_new0 (char *, env_len + 1); + for (gint i = 0; i < env_len; i++) { + if (strcmp (envp[i], "DISPLAY") == 0) { + retval[i] = g_strconcat ("DISPLAY=", display_name, NULL); + } else { + retval[i] = g_strdup (envp[i]); + } + } } - - for (env_len = 0; envp[env_len]; env_len++) - if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0) - display_index = env_len; - - retval = g_new (char *, env_len + 1); - retval[env_len] = NULL; - - display_name = gdk_display_get_name (display); - - for (i = 0; i < env_len; i++) - if (i == display_index) - retval[i] = g_strconcat ("DISPLAY=", display_name, NULL); - else +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + retval = g_new0 (char *, env_len + 3); + for (gint i = 0; i < env_len; i++) { retval[i] = g_strdup (envp[i]); + } + retval[env_len] = g_strdup_printf ("WAYLAND_DISPLAY=%s", display_name); + retval[env_len + 1] = g_strdup_printf ("WLE_EMBEDDING_TOKEN=%s", wle_gtk_socket_get_embedding_token (WLE_GTK_SOCKET (socket))); + } +#endif - if (own_envp) - g_strfreev (envp); - - g_assert (i == env_len); + g_strfreev (envp); return retval; } + +gboolean +spawn_async_with_pipes (GtkWidget *socket, + const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) { +#ifdef ENABLE_X11 + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { + return g_spawn_async_with_pipes (working_directory, argv, envp, flags, child_setup, user_data, + child_pid, standard_input, standard_output, standard_error, error); + } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + return wle_embedded_compositor_spawn_with_pipes (wle_gtk_socket_get_embedded_compositor (WLE_GTK_SOCKET (socket)), + working_directory, argv, envp, flags, child_setup, user_data, + child_pid, standard_input, standard_output, standard_error, error); + } +#endif + return FALSE; +} diff --git a/src/xfce-desktop-utils.h b/src/xfce-desktop-utils.h index 29c5582b..9e36a12d 100644 --- a/src/xfce-desktop-utils.h +++ b/src/xfce-desktop-utils.h @@ -26,19 +26,29 @@ #ifndef SRC_XFCE_DESKTOP_UTILS_H_ #define SRC_XFCE_DESKTOP_UTILS_H_ -#include <glib.h> -#include <gdk/gdk.h> #include <gtk/gtk.h> G_BEGIN_DECLS /* replace gdk_spawn_command_line_on_screen, not available in GTK3 */ -gboolean xfce_gdk_spawn_command_line_on_screen (GdkScreen *screen, - const gchar *command, - GError **error); - -gchar **spawn_make_environment_for_display (GdkDisplay *display, - gchar **envp); +gboolean xfce_gdk_spawn_command_line_on_screen (GdkScreen *screen, + const gchar *command, + GError **error); + +gchar **spawn_make_environment_for_display (GtkWidget *socket); + +gboolean spawn_async_with_pipes (GtkWidget *socket, + const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error); G_END_DECLS diff --git a/src/xfce4-screensaver-dialog.c b/src/xfce4-screensaver-dialog.c index 506170cc..ad0976b1 100644 --- a/src/xfce4-screensaver-dialog.c +++ b/src/xfce4-screensaver-dialog.c @@ -37,6 +37,9 @@ #include <gdk/gdkx.h> #include <gtk/gtkx.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#endif #include <libxfce4util/libxfce4util.h> #include <xfconf/xfconf.h> @@ -95,6 +98,11 @@ static char* get_id_string(GtkWidget* widget) { id = g_strdup_printf ("%lu", gtk_plug_get_id (GTK_PLUG (widget))); } #endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + id = g_strdup (""); + } +#endif return id; } diff --git a/src/xfce4-screensaver-preferences.c b/src/xfce4-screensaver-preferences.c index d4f1ee87..8db70a2e 100644 --- a/src/xfce4-screensaver-preferences.c +++ b/src/xfce4-screensaver-preferences.c @@ -37,6 +37,11 @@ #include <gdk/gdkx.h> #include <gtk/gtkx.h> #endif +#ifdef ENABLE_WAYLAND +#include <gdk/gdkwayland.h> +#include <libwlembed/libwlembed.h> +#include <libwlembed-gtk3/libwlembed-gtk3.h> +#endif #include <libxfce4ui/libxfce4ui.h> #include <xfconf/xfconf.h> @@ -68,6 +73,9 @@ static GSThemeManager *theme_manager = NULL; static GSJob *job = NULL; static XfconfChannel *screensaver_channel = NULL; static XfceScreensaver *xfce_screensaver = NULL; +#ifdef ENABLE_WAYLAND +static WleEmbeddedCompositor *compositor = NULL; +#endif static gboolean idle_delay_writable; static gboolean lock_delay_writable; @@ -611,17 +619,26 @@ preview_on_draw (GtkWidget *widget, } static void -preview_set_theme (GtkWidget *widget, - const char *theme, +preview_set_theme (const char *theme, const char *name) { - GtkWidget *label; + GtkWidget *label, *preview; char *markup; + preview = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (builder, "saver_themes_preview_area"))); + if (!gtk_widget_is_visible (preview)) { + preview = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (builder, "fullscreen_preview_area"))); + } + if (job != NULL) { gs_job_stop (job); +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + wle_gtk_socket_destroy_embedded_view (WLE_GTK_SOCKET (preview)); + } +#endif } - gtk_widget_queue_draw (widget); + gtk_widget_queue_draw (preview); label = GTK_WIDGET (gtk_builder_get_object (builder, "fullscreen_preview_theme_label")); markup = g_markup_printf_escaped ("<i>%s</i>", name); @@ -789,8 +806,7 @@ tree_selection_next (GtkTreeSelection *selection) { } static void -tree_selection_changed_cb (GtkTreeSelection *selection, - GtkWidget *preview) { +tree_selection_changed_cb (GtkTreeSelection *selection) { GtkWidget *configure_button; GtkTreeIter iter; GtkTreeModel *model; @@ -816,7 +832,7 @@ tree_selection_changed_cb (GtkTreeSelection *selection, return; } - preview_set_theme (preview, theme, name); + preview_set_theme (theme, name); config_set_theme (theme); g_free (theme); @@ -1022,12 +1038,11 @@ setup_treeview (GtkWidget *tree, gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (select), "changed", G_CALLBACK (tree_selection_changed_cb), - preview); + NULL); } static void reload_theme (GtkWidget *treeview) { - GtkWidget *preview; GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; @@ -1056,8 +1071,7 @@ reload_theme (GtkWidget *treeview) { return; } - preview = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (builder, "saver_themes_preview_area"))); - preview_set_theme (preview, theme, name); + preview_set_theme (theme, name); g_free (theme); g_free (name); @@ -1812,6 +1826,19 @@ configure_capplet (void) { gtk_container_add (GTK_CONTAINER (preview), gtk_socket_new ()); gtk_container_add (GTK_CONTAINER (fullscreen_preview_area), gtk_socket_new ()); } +#endif +#ifdef ENABLE_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + GError *_error = NULL; + compositor = wle_gtk_create_embedded_compositor ("xfce4-screensaver-preferences", &_error); + if (compositor == NULL) { + g_critical ("Failed to create embedded compositor: %s", _error->message); + g_error_free (_error); + } else { + gtk_container_add (GTK_CONTAINER (preview), wle_gtk_socket_new (compositor)); + gtk_container_add (GTK_CONTAINER (fullscreen_preview_area), wle_gtk_socket_new (compositor)); + } + } #endif preview = gtk_bin_get_child (GTK_BIN (preview)); gtk_widget_set_app_paintable (preview, TRUE); @@ -2026,6 +2053,11 @@ finalize_capplet (void) { if (active_theme) g_free (active_theme); + +#ifdef ENABLE_WAYLAND + if (compositor) + g_object_unref (compositor); +#endif } int -- GitLab