From d25120239c4202025ade06815579b979ef5a8da5 Mon Sep 17 00:00:00 2001 From: Peridot Bot <rockyautomation@rockylinux.org> Date: Thu, 3 Apr 2025 21:26:38 +0000 Subject: [PATCH] import gnome-kiosk-47.0-10.el10 --- ...se-the-meta-window-API-for-set-above.patch | 49 ++ ...itor-Add-a-window-configuration-file.patch | 517 ++++++++++++++++++ ...sitor-Apply-the-window-configuration.patch | 124 +++++ ...an-API-to-retrieve-a-boolean-setting.patch | 78 +++ ...mpositor-Make-set-above-configurable.patch | 81 +++ SPECS/gnome-kiosk.spec | 16 +- 6 files changed, 862 insertions(+), 3 deletions(-) create mode 100644 SOURCES/0001-compositor-Use-the-meta-window-API-for-set-above.patch create mode 100644 SOURCES/0002-compositor-Add-a-window-configuration-file.patch create mode 100644 SOURCES/0003-compositor-Apply-the-window-configuration.patch create mode 100644 SOURCES/0004-compositor-Add-an-API-to-retrieve-a-boolean-setting.patch create mode 100644 SOURCES/0005-compositor-Make-set-above-configurable.patch diff --git a/SOURCES/0001-compositor-Use-the-meta-window-API-for-set-above.patch b/SOURCES/0001-compositor-Use-the-meta-window-API-for-set-above.patch new file mode 100644 index 0000000..c2cf142 --- /dev/null +++ b/SOURCES/0001-compositor-Use-the-meta-window-API-for-set-above.patch @@ -0,0 +1,49 @@ +From 231001c019b379f573baa0e869811fa8c429775b Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <ofourdan@redhat.com> +Date: Wed, 13 Nov 2024 11:36:25 +0100 +Subject: [PATCH 1/5] compositor: Use the meta window API for set-above + +Currently, GNOME Kiosk would place windows that need to be above in a +special window group on top. + +Unfortunately, that means windows in that group will remain there, and +there is no way to send these back to the notmal layer using the +existing mutter API. + +To avoid the problem, use the meta_window_make_above() API. + +See-also: https://gitlab.gnome.org/GNOME/gnome-kiosk/-/issues/26 +(cherry picked from commit 1c2994e5eada4286655d007f91c22452c27f8ead) +--- + compositor/kiosk-compositor.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/compositor/kiosk-compositor.c b/compositor/kiosk-compositor.c +index 8432a24..37588da 100644 +--- a/compositor/kiosk-compositor.c ++++ b/compositor/kiosk-compositor.c +@@ -377,18 +377,10 @@ kiosk_compositor_map (MetaPlugin *plugin, + meta_window_make_fullscreen (window); + easing_duration = 3000; + } else { +- ClutterActor *window_group; +- + g_debug ("KioskCompositor: Mapping window that does not need to be fullscreened"); +- window_group = meta_get_top_window_group_for_display (self->display); +- +- if (kiosk_compositor_wants_window_above (self, window)) { +- g_object_ref (G_OBJECT (actor)); +- clutter_actor_remove_child (clutter_actor_get_parent (CLUTTER_ACTOR (actor)), CLUTTER_ACTOR (actor)); +- clutter_actor_add_child (window_group, CLUTTER_ACTOR (actor)); +- clutter_actor_set_child_above_sibling (window_group, CLUTTER_ACTOR (actor), NULL); +- g_object_unref (G_OBJECT (actor)); +- } ++ ++ if (kiosk_compositor_wants_window_above (self, window)) ++ meta_window_make_above (window); + + easing_duration = 500; + } +-- +2.49.0 + diff --git a/SOURCES/0002-compositor-Add-a-window-configuration-file.patch b/SOURCES/0002-compositor-Add-a-window-configuration-file.patch new file mode 100644 index 0000000..bc1cc7b --- /dev/null +++ b/SOURCES/0002-compositor-Add-a-window-configuration-file.patch @@ -0,0 +1,517 @@ +From f30b19d09bf521f3b731e08551428c5a7afb26c6 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <ofourdan@redhat.com> +Date: Fri, 11 Oct 2024 14:36:02 +0200 +Subject: [PATCH 2/5] compositor: Add a window configuration file + +This adds a configuration file to specify the windows configuration at +start-up. + +The file is an "ini" style file with sections and keys/values. + +There can be as many sections as desired, each section gets evaluated. + +There are two categories of keys, the "match" keys and the "set" keys. + +The "match" keys are used to filter the windows before applying the +values from the "set" keys. + +The "match" keys can take wildcards and patterns. + +Currently the following "match" keys as supported: + + * match-title (string) - Matches the window title + * match-class (string) - Matches the window class + * match-sandboxed-app-id (string) - Matches the sandboxed application id + +The following "set" keys are supported: + + * set-fullscreen (boolean) - Whether the window should be fullscreen + * set-x (integer) - the X position + * set-y (integer) - the Y position + * set-width (integer) - the width + * set-height (integer) - the height + +E.g.: + + # Place all windows at (0,0) by default + [all] + set-x=0 + set-y=0 + + # Make all Mozilla windows fullscreen + [mozilla] + match-class=org.mozilla.* + set-fullscreen=true + + # All other windows will be set fullscreen automatically using the + # existing GNOME Kiosk heuristic, as before. + +see-also: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4076 +(cherry picked from commit 9cb4f91724e489ab8b849ffb83f5a6c01e0ac552) +(cherry picked from commit 047bd8c83f4a6e950b0ce608417cba178df19f10) +--- + CONFIG.md | 62 ++++++ + compositor/kiosk-window-config.c | 315 +++++++++++++++++++++++++++++++ + compositor/kiosk-window-config.h | 21 +++ + meson.build | 1 + + window-config.ini | 17 ++ + 5 files changed, 416 insertions(+) + create mode 100644 CONFIG.md + create mode 100644 compositor/kiosk-window-config.c + create mode 100644 compositor/kiosk-window-config.h + create mode 100644 window-config.ini + +diff --git a/CONFIG.md b/CONFIG.md +new file mode 100644 +index 0000000..b0045ee +--- /dev/null ++++ b/CONFIG.md +@@ -0,0 +1,62 @@ ++# Configuration file ++ ++GNOME Kiosk takes a configuration file to specify the windows configuration at start-up. ++ ++The configuration file called `window-config.ini` is searched in multiple places on the ++system. The first instance of the file found is used. ++ ++ * The base directory in which user-specific application configuration is stored ++ `$XDG_CONFIG_HOME/gnome-kiosk/window-config.ini` (usually `$HOME/.config/gnome-kiosk/window-config.ini`) ++ * The system-wide list of directories in which system-wide application data is stored `$XDG_DATA_DIRS` ++ This list usually includes: ++ - `/var/lib/flatpak/exports/share/gnome-kiosk/window-config.ini` ++ - `/usr/local/share/gnome-kiosk/window-config.ini` ++ - `/usr/share/gnome-kiosk/window-config.ini` ++ ++# Syntax ++ ++The configuration file is an "ini" style file with sections and keys/values. ++ ++There can be as many sections as desired. ++ ++The name of the sections does not matter, there is no special name of section, ++each section gets evaluated. ++ ++There are two categories of keys, the "*match*" keys and the "*set*" keys. ++ ++The "*match*" keys are used to filter the windows before applying the ++values from the "*set*" keys. ++ ++The "*match*" keys can take wildcards and patterns. ++ ++The following "*match*" keys as supported: ++ ++ * `match-title` (string) - Matches the window title ++ * `match-class` (string) - Matches the window class ++ * `match-sandboxed-app-id` (string) - Matches the sandboxed application id ++ ++The following "*set*" keys are supported: ++ ++ * `set-fullscreen` (boolean) - Whether the window should be fullscreen ++ * `set-x` (integer) - the X position ++ * `set-y` (integer) - the Y position ++ * `set-width` (integer) - the width ++ * `set-height` (integer) - the height ++ ++# Example ++ ++``` ++ # Place all windows at (0,0) by default, not fullscreen ++ [all] ++ set-x=0 ++ set-y=0 ++ set-fullscreen=false ++ ++ # Make all Mozilla windows fullscreen ++ [mozilla] ++ match-class=org.mozilla.* ++ set-fullscreen=true ++ ++ # All other windows will be set fullscreen automatically using the ++ # existing GNOME Kiosk heuristic, as before. ++``` +diff --git a/compositor/kiosk-window-config.c b/compositor/kiosk-window-config.c +new file mode 100644 +index 0000000..5e6c830 +--- /dev/null ++++ b/compositor/kiosk-window-config.c +@@ -0,0 +1,315 @@ ++#include "config.h" ++ ++#include <stdlib.h> ++#include <string.h> ++ ++#include "kiosk-window-config.h" ++ ++#define KIOSK_WINDOW_CONFIG_DIR "gnome-kiosk" ++#define KIOSK_WINDOW_CONFIG_FILENAME "window-config.ini" ++#define KIOSK_WINDOW_CONFIG_GET_KEY_VALUE(f) ((KioskWindowConfigGetKeyValue) (f)) ++ ++typedef gpointer (*KioskWindowConfigGetKeyValue) (GKeyFile *key_file, ++ const char *section_name, ++ const char *key_name, ++ GError **error); ++ ++struct _KioskWindowConfig ++{ ++ GObject parent; ++ ++ GKeyFile *config_key_file; ++}; ++ ++G_DEFINE_TYPE (KioskWindowConfig, kiosk_window_config, G_TYPE_OBJECT) ++ ++static gboolean ++kiosk_window_config_try_load_file (KioskWindowConfig *kiosk_window_config, ++ char *filename) ++{ ++ g_autoptr (GError) error = NULL; ++ ++ if (!g_key_file_load_from_file (kiosk_window_config->config_key_file, ++ filename, ++ G_KEY_FILE_NONE, ++ &error)) { ++ g_debug ("KioskWindowConfig: Error loading key file %s: %s", ++ filename, error->message); ++ ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++kiosk_window_config_load (KioskWindowConfig *kiosk_window_config) ++{ ++ const char * const *xdg_data_dirs; ++ g_autofree gchar *filename = NULL; ++ int i; ++ ++ /* Try user config first */ ++ filename = g_build_filename (g_get_user_config_dir (), ++ KIOSK_WINDOW_CONFIG_DIR, ++ KIOSK_WINDOW_CONFIG_FILENAME, NULL); ++ ++ if (kiosk_window_config_try_load_file (kiosk_window_config, filename)) ++ goto out; ++ ++ /* Then system config */ ++ xdg_data_dirs = g_get_system_data_dirs (); ++ for (i = 0; xdg_data_dirs[i]; i++) { ++ filename = g_build_filename (xdg_data_dirs[i], ++ KIOSK_WINDOW_CONFIG_DIR, ++ KIOSK_WINDOW_CONFIG_FILENAME, NULL); ++ ++ if (kiosk_window_config_try_load_file (kiosk_window_config, filename)) ++ goto out; ++ } ++ ++ g_debug ("KioskWindowConfig: No configuration file found"); ++ ++ return FALSE; ++out: ++ g_debug ("KioskWindowConfig: Loading key file %s", filename); ++ ++ return TRUE; ++} ++ ++static void ++kiosk_window_config_init (KioskWindowConfig *self) ++{ ++ self->config_key_file = g_key_file_new (); ++ kiosk_window_config_load (self); ++} ++ ++static void ++kiosk_window_config_dispose (GObject *object) ++{ ++ KioskWindowConfig *self = KIOSK_WINDOW_CONFIG (object); ++ ++ g_clear_pointer (&self->config_key_file, g_key_file_free); ++ ++ G_OBJECT_CLASS (kiosk_window_config_parent_class)->dispose (object); ++} ++ ++static void ++kiosk_window_config_class_init (KioskWindowConfigClass *klass) ++{ ++ GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ++ ++ gobject_class->dispose = kiosk_window_config_dispose; ++} ++ ++#define KIOSK_WINDOW_CONFIG_CHECK_FUNC_VALUE(self, section, key, func, value) \ ++ G_STMT_START { \ ++ g_autoptr (GError) error = NULL; \ ++ if (!g_key_file_has_key (self->config_key_file, section, key, NULL)) { \ ++ g_debug ("KioskWindowConfig: No key '%s' in section [%s]", \ ++ key, section); \ ++ return FALSE; \ ++ } \ ++ *value = func (self->config_key_file, section, key, &error); \ ++ if (error) { \ ++ g_debug ("KioskWindowConfig: Error with key '%s' in section [%s]: %s", \ ++ key, section, error->message); \ ++ return FALSE; \ ++ } \ ++ return TRUE; \ ++ } G_STMT_END ++ ++static gboolean ++kiosk_window_config_check_for_string_value (KioskWindowConfig *kiosk_window_config, ++ const char *section_name, ++ const char *key_name, ++ char **value) ++{ ++ KIOSK_WINDOW_CONFIG_CHECK_FUNC_VALUE (kiosk_window_config, ++ section_name, ++ key_name, ++ g_key_file_get_string, ++ value); ++} ++ ++static gboolean ++kiosk_window_config_check_for_integer_value (KioskWindowConfig *kiosk_window_config, ++ const char *section_name, ++ const char *key_name, ++ int *value) ++{ ++ KIOSK_WINDOW_CONFIG_CHECK_FUNC_VALUE (kiosk_window_config, ++ section_name, ++ key_name, ++ g_key_file_get_integer, ++ value); ++} ++ ++static gboolean ++kiosk_window_config_check_for_boolean_value (KioskWindowConfig *kiosk_window_config, ++ const char *section_name, ++ const char *key_name, ++ gboolean *value) ++{ ++ KIOSK_WINDOW_CONFIG_CHECK_FUNC_VALUE (kiosk_window_config, ++ section_name, ++ key_name, ++ g_key_file_get_boolean, ++ value); ++} ++ ++static void ++kiosk_window_config_apply_config (KioskWindowConfig *kiosk_window_config, ++ MetaWindowConfig *window_config, ++ const char *section_name) ++{ ++ MtkRectangle rect; ++ int new_x, new_y, new_width, new_height; ++ gboolean fullscreen; ++ ++ if (kiosk_window_config_check_for_boolean_value (kiosk_window_config, ++ section_name, ++ "set-fullscreen", ++ &fullscreen)) { ++ g_debug ("KioskWindowConfig: Using 'set-fullscreen=%s' from section [%s]", ++ fullscreen ? "TRUE" : "FALSE", section_name); ++ meta_window_config_set_is_fullscreen (window_config, fullscreen); ++ } ++ ++ rect = meta_window_config_get_rect (window_config); ++ ++ if (kiosk_window_config_check_for_integer_value (kiosk_window_config, ++ section_name, ++ "set-x", ++ &new_x)) { ++ g_debug ("KioskWindowConfig: Using 'set-x=%i' from section [%s]", ++ new_x, section_name); ++ rect.x = new_x; ++ } ++ ++ if (kiosk_window_config_check_for_integer_value (kiosk_window_config, ++ section_name, ++ "set-y", ++ &new_y)) { ++ g_debug ("KioskWindowConfig: Using 'set-y=%i' from section [%s]", ++ new_y, section_name); ++ rect.y = new_y; ++ } ++ ++ if (kiosk_window_config_check_for_integer_value (kiosk_window_config, ++ section_name, ++ "set-width", ++ &new_width)) { ++ g_debug ("KioskWindowConfig: Using 'set-width=%i' from section [%s]", ++ new_width, section_name); ++ rect.width = new_width; ++ } ++ ++ if (kiosk_window_config_check_for_integer_value (kiosk_window_config, ++ section_name, ++ "set-height", ++ &new_height)) { ++ g_debug ("KioskWindowConfig: Using 'set-height=%i' from section [%s]", ++ new_height, section_name); ++ rect.height = new_height; ++ } ++ ++ meta_window_config_set_rect (window_config, rect); ++} ++ ++static gboolean ++kiosk_window_config_match_string_key (KioskWindowConfig *kiosk_window_config, ++ const char *section_name, ++ const char *key_name, ++ const char *value) ++{ ++ g_autofree gchar *key_value = NULL; ++ g_autoptr (GError) error = NULL; ++ gboolean is_a_match = TRUE; ++ ++ /* Keys are used to filter out, no key means we have a match */ ++ if (!kiosk_window_config_check_for_string_value (kiosk_window_config, ++ section_name, ++ key_name, ++ &key_value)) ++ return TRUE; ++ ++ is_a_match = g_pattern_match_simple (key_value, value); ++ g_debug ("KioskWindowConfig: Value '%s' %s key '%s=%s' from section [%s]", ++ value, ++ is_a_match ? "matches" : "does not match", ++ key_name, ++ key_value, ++ section_name); ++ ++ return is_a_match; ++} ++ ++static gboolean ++kiosk_window_config_match_window (KioskWindowConfig *kiosk_window_config, ++ MetaWindow *window, ++ const char *section_name) ++{ ++ const char *match_value; ++ ++ g_debug ("KioskWindowConfig: Checking section [%s]", section_name); ++ ++ match_value = meta_window_get_title (window); ++ if (match_value && ++ !kiosk_window_config_match_string_key (kiosk_window_config, ++ section_name, ++ "match-title", ++ match_value)) ++ return FALSE; ++ ++ match_value = meta_window_get_wm_class (window); ++ if (match_value && ++ !kiosk_window_config_match_string_key (kiosk_window_config, ++ section_name, ++ "match-class", ++ match_value)) ++ return FALSE; ++ ++ match_value = meta_window_get_sandboxed_app_id (window); ++ if (match_value && ++ !kiosk_window_config_match_string_key (kiosk_window_config, ++ section_name, ++ "match-sandboxed-app-id", ++ match_value)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++void ++kiosk_window_config_update_window (KioskWindowConfig *kiosk_window_config, ++ MetaWindow *window, ++ MetaWindowConfig *window_config) ++{ ++ g_auto (GStrv) sections; ++ gsize length; ++ int i; ++ ++ sections = g_key_file_get_groups (kiosk_window_config->config_key_file, &length); ++ for (i = 0; i < length; i++) { ++ if (!kiosk_window_config_match_window (kiosk_window_config, ++ window, ++ sections[i])) ++ continue; ++ ++ kiosk_window_config_apply_config (kiosk_window_config, ++ window_config, ++ sections[i]); ++ } ++} ++ ++KioskWindowConfig * ++kiosk_window_config_new (void) ++{ ++ KioskWindowConfig *kiosk_window_config; ++ ++ kiosk_window_config = g_object_new (KIOSK_TYPE_WINDOW_CONFIG, ++ NULL); ++ ++ return kiosk_window_config; ++} +diff --git a/compositor/kiosk-window-config.h b/compositor/kiosk-window-config.h +new file mode 100644 +index 0000000..1c7e8ea +--- /dev/null ++++ b/compositor/kiosk-window-config.h +@@ -0,0 +1,21 @@ ++#pragma once ++ ++#include <glib-object.h> ++#include <glib.h> ++ ++#include <meta/window.h> ++#include <meta/meta-window-config.h> ++ ++G_BEGIN_DECLS ++ ++#define KIOSK_TYPE_WINDOW_CONFIG (kiosk_window_config_get_type ()) ++G_DECLARE_FINAL_TYPE (KioskWindowConfig, kiosk_window_config, ++ KIOSK, WINDOW_CONFIG, GObject) ++ ++KioskWindowConfig *kiosk_window_config_new (void); ++ ++void kiosk_window_config_update_window (KioskWindowConfig *kiosk_window_config, ++ MetaWindow *window, ++ MetaWindowConfig *window_config); ++ ++G_END_DECLS +diff --git a/meson.build b/meson.build +index 23aaff7..c3eb74c 100644 +--- a/meson.build ++++ b/meson.build +@@ -166,6 +166,7 @@ compositor_sources += 'compositor/kiosk-service.c' + compositor_sources += 'compositor/kiosk-shell-service.c' + compositor_sources += 'compositor/kiosk-shell-introspect-service.c' + compositor_sources += 'compositor/kiosk-shell-screenshot-service.c' ++compositor_sources += 'compositor/kiosk-window-config.c' + compositor_sources += 'compositor/kiosk-screenshot.c' + + if mutter_have_x11 +diff --git a/window-config.ini b/window-config.ini +new file mode 100644 +index 0000000..c4c825e +--- /dev/null ++++ b/window-config.ini +@@ -0,0 +1,17 @@ ++# This is just an example for a window configuration file. ++# Copy this file to $HOME/.config/gnome-kiosk/window-config.ini ++ ++# The section names are free and all sections get evaluated. ++ ++# Place all windows at (0,0) by default ++[all] ++set-x=0 ++set-y=0 ++ ++# Make all Mozilla windows fullscreen ++[browser] ++match-class=org.mozilla* ++set-fullscreen=true ++ ++# All other windows will be set fullscreen automatically using the ++# existing GNOME Kiosk heuristic, as before. +-- +2.49.0 + diff --git a/SOURCES/0003-compositor-Apply-the-window-configuration.patch b/SOURCES/0003-compositor-Apply-the-window-configuration.patch new file mode 100644 index 0000000..3f01dd3 --- /dev/null +++ b/SOURCES/0003-compositor-Apply-the-window-configuration.patch @@ -0,0 +1,124 @@ +From bf79fe519d55a5fc6d31775164e0a4c5831a9020 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <ofourdan@redhat.com> +Date: Fri, 25 Oct 2024 14:04:17 +0200 +Subject: [PATCH 3/5] compositor: Apply the window configuration + +Use the "MetaWindow::configure" signal in mutter-16 to apply the GNOME +Kiosk window configuration. + +(cherry picked from commit 30d0c4233f84234bd6d470fc42715593360e115a) +--- + compositor/kiosk-compositor.c | 47 +++++++++++++++++++++++++++++++++-- + 1 file changed, 45 insertions(+), 2 deletions(-) + +diff --git a/compositor/kiosk-compositor.c b/compositor/kiosk-compositor.c +index 37588da..650ac50 100644 +--- a/compositor/kiosk-compositor.c ++++ b/compositor/kiosk-compositor.c +@@ -12,6 +12,7 @@ + #include <meta/keybindings.h> + #include <meta/meta-context.h> + #include <meta/util.h> ++#include <meta/meta-window-config.h> + #include <meta/meta-window-group.h> + + #include <systemd/sd-daemon.h> +@@ -25,6 +26,7 @@ + #include "kiosk-window-tracker.h" + #include "kiosk-shell-introspect-service.h" + #include "kiosk-shell-screenshot-service.h" ++#include "kiosk-window-config.h" + + #include "org.gnome.DisplayManager.Manager.h" + +@@ -48,6 +50,7 @@ struct _KioskCompositor + KioskWindowTracker *tracker; + KioskShellIntrospectService *introspect_service; + KioskShellScreenshotService *screenshot_service; ++ KioskWindowConfig *kiosk_window_config; + }; + + enum +@@ -61,6 +64,8 @@ static guint signals[NUMBER_OF_SIGNALS] = { 0, }; + G_DEFINE_TYPE (KioskCompositor, kiosk_compositor, META_TYPE_PLUGIN) + + static void kiosk_compositor_dispose (GObject *object); ++static gboolean kiosk_compositor_wants_window_fullscreen (KioskCompositor *self, ++ MetaWindow *window); + + static void + kiosk_compositor_dispose (GObject *object) +@@ -220,6 +225,39 @@ neuter_builtin_keybindings (KioskCompositor *self) + } + } + ++static void ++kiosk_compositor_on_window_configure (MetaWindow *window, ++ MetaWindowConfig *window_config, ++ gpointer user_data) ++{ ++ KioskCompositor *self = KIOSK_COMPOSITOR (user_data); ++ gboolean fullscreen; ++ ++ if (!meta_window_config_get_is_initial (window_config)) { ++ g_debug ("KioskCompositor: Ignoring configure for window: %s", ++ meta_window_get_description (window)); ++ return; ++ } ++ ++ g_debug ("KioskCompositor: configure window: %s", meta_window_get_description (window)); ++ ++ fullscreen = kiosk_compositor_wants_window_fullscreen (self, window); ++ meta_window_config_set_is_fullscreen (window_config, fullscreen); ++ kiosk_window_config_update_window (self->kiosk_window_config, ++ window, ++ window_config); ++} ++ ++static void ++kiosk_compositor_on_window_created (MetaDisplay *display, ++ MetaWindow *window, ++ gpointer user_data) ++{ ++ g_signal_connect (window, "configure", ++ G_CALLBACK (kiosk_compositor_on_window_configure), ++ user_data); ++} ++ + static void + kiosk_compositor_start (MetaPlugin *plugin) + { +@@ -250,6 +288,7 @@ kiosk_compositor_start (MetaPlugin *plugin) + self->input_sources_manager = kiosk_input_sources_manager_new (self); + self->app_system = kiosk_app_system_new (self); + self->tracker = kiosk_window_tracker_new (self, self->app_system); ++ self->kiosk_window_config = kiosk_window_config_new (); + self->introspect_service = kiosk_shell_introspect_service_new (self); + kiosk_shell_introspect_service_start (self->introspect_service, &error); + self->screenshot_service = kiosk_shell_screenshot_service_new (self); +@@ -265,6 +304,11 @@ kiosk_compositor_start (MetaPlugin *plugin) + self->cancellable, + KIOSK_OBJECT_CALLBACK (register_session), + NULL); ++ ++ g_signal_connect_object (self->display, "window-created", ++ G_CALLBACK (kiosk_compositor_on_window_created), ++ self, ++ G_CONNECT_DEFAULT); + } + + static void +@@ -372,9 +416,8 @@ kiosk_compositor_map (MetaPlugin *plugin, + + window = meta_window_actor_get_meta_window (actor); + +- if (kiosk_compositor_wants_window_fullscreen (self, window)) { ++ if (meta_window_is_fullscreen (window)) { + g_debug ("KioskCompositor: Mapping window that does need to be fullscreened"); +- meta_window_make_fullscreen (window); + easing_duration = 3000; + } else { + g_debug ("KioskCompositor: Mapping window that does not need to be fullscreened"); +-- +2.49.0 + diff --git a/SOURCES/0004-compositor-Add-an-API-to-retrieve-a-boolean-setting.patch b/SOURCES/0004-compositor-Add-an-API-to-retrieve-a-boolean-setting.patch new file mode 100644 index 0000000..017786d --- /dev/null +++ b/SOURCES/0004-compositor-Add-an-API-to-retrieve-a-boolean-setting.patch @@ -0,0 +1,78 @@ +From fed3a11e0f9c21f2361b3fea564c51957cd24fa5 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <ofourdan@redhat.com> +Date: Tue, 12 Nov 2024 10:38:19 +0100 +Subject: [PATCH 4/5] compositor: Add an API to retrieve a boolean setting + +This adds a direct search API to the window configuration to retrieve +the boolean value for a matching window. + +This is preparation work for the following commit. + +(cherry picked from commit 62a7053d14b8432ef8dbc3ad78cd043ea95cf043) +--- + compositor/kiosk-window-config.c | 32 ++++++++++++++++++++++++++++++++ + compositor/kiosk-window-config.h | 5 +++++ + 2 files changed, 37 insertions(+) + +diff --git a/compositor/kiosk-window-config.c b/compositor/kiosk-window-config.c +index 5e6c830..a07798b 100644 +--- a/compositor/kiosk-window-config.c ++++ b/compositor/kiosk-window-config.c +@@ -281,6 +281,38 @@ kiosk_window_config_match_window (KioskWindowConfig *kiosk_window_config, + return TRUE; + } + ++gboolean ++kiosk_window_config_get_boolean_for_window (KioskWindowConfig *kiosk_window_config, ++ MetaWindow *window, ++ const char *key_name, ++ gboolean *value) ++{ ++ g_auto (GStrv) sections; ++ gsize length; ++ gboolean key_found = FALSE; ++ int i; ++ ++ sections = g_key_file_get_groups (kiosk_window_config->config_key_file, &length); ++ for (i = 0; i < length; i++) { ++ if (!kiosk_window_config_match_window (kiosk_window_config, ++ window, ++ sections[i])) ++ continue; ++ ++ if (kiosk_window_config_check_for_boolean_value (kiosk_window_config, ++ sections[i], ++ key_name, ++ value)) { ++ g_debug ("KioskWindowConfig: Using '%s=%s' from section [%s]", ++ key_name, *value ? "TRUE" : "FALSE", sections[i]); ++ ++ key_found = TRUE; ++ } ++ } ++ ++ return key_found; ++} ++ + void + kiosk_window_config_update_window (KioskWindowConfig *kiosk_window_config, + MetaWindow *window, +diff --git a/compositor/kiosk-window-config.h b/compositor/kiosk-window-config.h +index 1c7e8ea..3482c43 100644 +--- a/compositor/kiosk-window-config.h ++++ b/compositor/kiosk-window-config.h +@@ -14,6 +14,11 @@ G_DECLARE_FINAL_TYPE (KioskWindowConfig, kiosk_window_config, + + KioskWindowConfig *kiosk_window_config_new (void); + ++gboolean kiosk_window_config_get_boolean_for_window (KioskWindowConfig *kiosk_window_config, ++ MetaWindow *window, ++ const char *key_name, ++ gboolean *value); ++ + void kiosk_window_config_update_window (KioskWindowConfig *kiosk_window_config, + MetaWindow *window, + MetaWindowConfig *window_config); +-- +2.49.0 + diff --git a/SOURCES/0005-compositor-Make-set-above-configurable.patch b/SOURCES/0005-compositor-Make-set-above-configurable.patch new file mode 100644 index 0000000..48a83d4 --- /dev/null +++ b/SOURCES/0005-compositor-Make-set-above-configurable.patch @@ -0,0 +1,81 @@ +From 8a9121bb11f0423aefe5a51252986765e10214b0 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <ofourdan@redhat.com> +Date: Fri, 8 Nov 2024 18:18:32 +0100 +Subject: [PATCH 5/5] compositor: Make set-above configurable + +GNOME Kiosk has heuristics to place windows on the top group. + +However, in some cases, it may desirable to avoid that behavior as that +prevents the windows stacking from being changed by the user. + +Add a new option "set-above" to the configuration file to control that +behaviour. + +If not specified, the existing heuristics will be applied, not breaking +possible existing setups. + +Closes: https://gitlab.gnome.org/GNOME/gnome-kiosk/-/issues/26 +(cherry picked from commit b50c25fe739c00f4a1984919ee93cd351f58dfc1) +--- + CONFIG.md | 3 +++ + compositor/kiosk-compositor.c | 9 +++++++++ + window-config.ini | 2 ++ + 3 files changed, 14 insertions(+) + +diff --git a/CONFIG.md b/CONFIG.md +index b0045ee..652fb71 100644 +--- a/CONFIG.md ++++ b/CONFIG.md +@@ -42,6 +42,7 @@ The following "*set*" keys are supported: + * `set-y` (integer) - the Y position + * `set-width` (integer) - the width + * `set-height` (integer) - the height ++ * `set-above` (boolean) - Whether the window should be placed on a layer above + + # Example + +@@ -51,6 +52,8 @@ The following "*set*" keys are supported: + set-x=0 + set-y=0 + set-fullscreen=false ++ # The following will place all windows on the same layer ++ set-above=false + + # Make all Mozilla windows fullscreen + [mozilla] +diff --git a/compositor/kiosk-compositor.c b/compositor/kiosk-compositor.c +index 650ac50..aa5603d 100644 +--- a/compositor/kiosk-compositor.c ++++ b/compositor/kiosk-compositor.c +@@ -385,6 +385,15 @@ static gboolean + kiosk_compositor_wants_window_above (KioskCompositor *self, + MetaWindow *window) + { ++ gboolean set_above; ++ ++ if (kiosk_window_config_get_boolean_for_window (self->kiosk_window_config, ++ window, ++ "set-above", ++ &set_above)) ++ return set_above; ++ ++ /* If not specified in the config, use the heuristics */ + if (meta_window_is_screen_sized (window)) { + return FALSE; + } +diff --git a/window-config.ini b/window-config.ini +index c4c825e..f4f37b3 100644 +--- a/window-config.ini ++++ b/window-config.ini +@@ -7,6 +7,8 @@ + [all] + set-x=0 + set-y=0 ++# Uncomment the following to have all windows on the same layer ++# set-above=false + + # Make all Mozilla windows fullscreen + [browser] +-- +2.49.0 + diff --git a/SPECS/gnome-kiosk.spec b/SPECS/gnome-kiosk.spec index b43e423..9a71380 100644 --- a/SPECS/gnome-kiosk.spec +++ b/SPECS/gnome-kiosk.spec @@ -2,7 +2,7 @@ ## (rpmautospec version 0.7.3) ## RPMAUTOSPEC: autorelease, autochangelog %define autorelease(e:s:pb:n) %{?-p:0.}%{lua: - release_number = 9; + release_number = 10; base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}")); print(release_number + base_release_number - 1); }%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}} @@ -15,7 +15,7 @@ %global gnome_desktop_version 44.0 %global glib2_version 2.68.0 %global gtk4_version 3.24.27 -%global mutter_version 47~alpha +%global mutter_version 47.5-9 %global gsettings_desktop_schemas_version 40~rc %global ibus_version 1.5.24 %global gnome_settings_daemon_version 40~rc @@ -50,6 +50,7 @@ BuildRequires: pkgconfig(gdk-pixbuf-2.0) Requires: gnome-settings-daemon%{?_isa} >= %{gnome_settings_daemon_version} Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas_version} +Requires: mutter%{?_isa} >= %{mutter_version} Patch: 0001-kiosk-app-Do-not-add-the-window-in-kiosk_app_new_for.patch # https://issues.redhat.com/browse/RHEL-71757 @@ -65,6 +66,12 @@ Patch: 0002-search-app-Update-desktop-file-definition.patch Patch: 0001-search-app-Use-firefox-from-flatpak.patch # https://issues.redhat.com/browse/RHEL-84829 Patch: 0001-input-sources-manager-Do-not-crash-if-there-is-no-X1.patch +# https://issues.redhat.com/browse/RHEL-84697 +Patch: 0001-compositor-Use-the-meta-window-API-for-set-above.patch +Patch: 0002-compositor-Add-a-window-configuration-file.patch +Patch: 0003-compositor-Apply-the-window-configuration.patch +Patch: 0004-compositor-Add-an-API-to-retrieve-a-boolean-setting.patch +Patch: 0005-compositor-Make-set-above-configurable.patch %description GNOME Kiosk provides a desktop enviroment suitable for fixed purpose, or @@ -107,7 +114,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Kiosk.Searc %files %license COPYING -%doc NEWS README.md +%doc NEWS README.md CONFIG.md %{_bindir}/gnome-kiosk %{_datadir}/applications/org.gnome.Kiosk.desktop %{_datadir}/dconf/profile/gnomekiosk @@ -135,6 +142,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Kiosk.Searc %changelog ## START: Generated by rpmautospec +* Thu Apr 03 2025 Olivier Fourdan <ofourdan@redhat.com> - 47.0-10 +- Add window configurability + * Wed Mar 26 2025 Olivier Fourdan <ofourdan@redhat.com> - 47.0-9 - Fix crash on missing systemd files -- GitLab