parent
7a50351fc2
commit
fd5a0af9d7
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@
|
||||
/gnome-kiosk-47.alpha.tar.xz
|
||||
/gnome-kiosk-47.rc.tar.xz
|
||||
/gnome-kiosk-47.0.tar.xz
|
||||
/gnome-kiosk-49.0.tar.xz
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
From 269cf451feb18206f9a8326d8fa36bc36f9b1897 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 19 Mar 2025 14:41:15 +0100
|
||||
Subject: [PATCH] input-sources-manager: Do not crash if there is no X11Layouts
|
||||
|
||||
When queried for the X11Layout property, localed will try to get the
|
||||
configuration from /etc/X11/xorg.conf.d/00-keyboard.conf.
|
||||
|
||||
If for some reason (the system was misconfigured or the installation was
|
||||
altered), that directory is not accessible or not present, localed will
|
||||
return a NULL string instead of the actual X11 layouts or even an empty
|
||||
string if no X11 layout was ever configured.
|
||||
|
||||
In such a case, gnome-kiosk will segfault.
|
||||
|
||||
To avoid that potential problem, check for the X11 layouts to be not
|
||||
NULL or return early if that's not the case.
|
||||
|
||||
Fixes: 38407233 - input-sources-manager: Add APIs for setting keymap
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/gnome-kiosk/-/merge_requests/68>
|
||||
---
|
||||
compositor/kiosk-input-sources-manager.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/compositor/kiosk-input-sources-manager.c b/compositor/kiosk-input-sources-manager.c
|
||||
index 31dab12..6200af5 100644
|
||||
--- a/compositor/kiosk-input-sources-manager.c
|
||||
+++ b/compositor/kiosk-input-sources-manager.c
|
||||
@@ -869,6 +869,10 @@ kiosk_input_sources_manager_set_input_sources_from_system_configuration (KioskIn
|
||||
g_debug ("KioskInputSourcesManager: Setting keymap from system configuration");
|
||||
|
||||
layouts_string = sd_locale1_get_x11_layout (self->locale_proxy);
|
||||
+ if (layouts_string == NULL) {
|
||||
+ g_debug ("KioskInputSourcesManager: No layouts defined");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
g_debug ("KioskInputSourcesManager: System layout is '%s'", layouts_string);
|
||||
|
||||
layouts = g_strsplit (layouts_string, ",", -1);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
From 67cb8748dbc8c237d7b7486c7cec9e7902dcb51f Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Mon, 7 Oct 2024 18:09:32 +0200
|
||||
Subject: [PATCH] kiosk-app: Do not add the window in
|
||||
kiosk_app_new_for_window()
|
||||
|
||||
When a window has no matching application (like, when there is no
|
||||
corresponding desktop file), a KioskApp is created for the window and
|
||||
the window would be added to the newly-created KioskApp.
|
||||
|
||||
However, by doing so, we add the window before the calling window
|
||||
tracker had a change to setup the state notify handler.
|
||||
|
||||
As a result, the window tracker is never notified of the state change
|
||||
and the KioskApp is never added to the list of running applications in
|
||||
the KioskAppState.
|
||||
|
||||
Too bad, since the introspection iterates on the running applications to
|
||||
report the windows.
|
||||
|
||||
To avoid the issue, simply do not add the window so soon in
|
||||
kiosk_app_new_for_window(), it will be added in time in track_window()
|
||||
and the notifications will be correctly triggered.
|
||||
|
||||
Fixes: commit 50ae635dc - kiosk-app: Add a new KioskApp class
|
||||
---
|
||||
compositor/kiosk-app.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/compositor/kiosk-app.c b/compositor/kiosk-app.c
|
||||
index acc9d9e..5b19e4e 100644
|
||||
--- a/compositor/kiosk-app.c
|
||||
+++ b/compositor/kiosk-app.c
|
||||
@@ -441,62 +441,60 @@ kiosk_app_remove_window (KioskApp *app,
|
||||
if (!meta_window_is_skip_taskbar (window))
|
||||
app->running_state->number_of_interesting_windows--;
|
||||
kiosk_app_sync_running_state (app);
|
||||
|
||||
if (app->running_state->windows == NULL)
|
||||
g_clear_pointer (&app->running_state, unref_running_state);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
G_CALLBACK (kiosk_app_on_user_time_changed),
|
||||
app);
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
G_CALLBACK (kiosk_app_on_skip_taskbar_changed),
|
||||
app);
|
||||
|
||||
g_object_unref (window);
|
||||
|
||||
g_signal_emit (app, kiosk_app_signals[WINDOWS_CHANGED], 0);
|
||||
}
|
||||
|
||||
KioskApp *
|
||||
kiosk_app_new_for_window (KioskCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
KioskApp *app;
|
||||
|
||||
app = g_object_new (KIOSK_TYPE_APP, "compositor", compositor, NULL);
|
||||
|
||||
app->window_id_string = g_strdup_printf ("window:%d",
|
||||
meta_window_get_stable_sequence (window));
|
||||
|
||||
- kiosk_app_add_window (app, window);
|
||||
-
|
||||
return app;
|
||||
}
|
||||
|
||||
KioskApp *
|
||||
kiosk_app_new (KioskCompositor *compositor,
|
||||
GDesktopAppInfo *info)
|
||||
{
|
||||
KioskApp *app;
|
||||
|
||||
app = g_object_new (KIOSK_TYPE_APP,
|
||||
"compositor", compositor, "app-info", info, NULL);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
const char *
|
||||
kiosk_app_get_sandbox_id (KioskApp *app)
|
||||
{
|
||||
KioskAppWindowIter iter;
|
||||
MetaWindow *window;
|
||||
|
||||
kiosk_app_window_iter_init (&iter, app);
|
||||
while (kiosk_app_window_iter_next (&iter, &window)) {
|
||||
const char *sandbox_id = meta_window_get_sandboxed_app_id (window);
|
||||
|
||||
if (sandbox_id)
|
||||
return sandbox_id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
--
|
||||
2.46.0
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
From 9497651214baaae6dabe7cc1971a1799633983a6 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Fri, 22 Nov 2024 17:04:09 +0100
|
||||
Subject: [PATCH] kiosk-script: Copy and run the script from XDG_RUNTIME_DIR
|
||||
|
||||
Some setup may enforce the noexec flag on the HOME directories.
|
||||
|
||||
That prevents any executable placed in the HOME directory from running,
|
||||
including the GNOME Kiosk script session.
|
||||
|
||||
To work around such an issue, copy and execute the script from the
|
||||
XDG_RUNTIME_DIR instead.
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
---
|
||||
kiosk-script/gnome-kiosk-script | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/kiosk-script/gnome-kiosk-script b/kiosk-script/gnome-kiosk-script
|
||||
index e45438d..c4ab176 100755
|
||||
--- a/kiosk-script/gnome-kiosk-script
|
||||
+++ b/kiosk-script/gnome-kiosk-script
|
||||
@@ -1,8 +1,10 @@
|
||||
#!/usr/bin/sh
|
||||
|
||||
-if [ ! -e ~/.local/bin/gnome-kiosk-script ]; then
|
||||
- mkdir -p ~/.local/bin ~/.config
|
||||
- cat > ~/.local/bin/gnome-kiosk-script <<- "EOF"
|
||||
+EXECDIR=~/.local/bin
|
||||
+
|
||||
+if [ ! -e $EXECDIR/gnome-kiosk-script ]; then
|
||||
+ mkdir -p $EXECDIR ~/.config
|
||||
+ cat > $EXECDIR/gnome-kiosk-script <<- "EOF"
|
||||
#!/bin/sh
|
||||
# This script is located in ~/.local/bin.
|
||||
# It's provided as an example script to show how
|
||||
@@ -16,8 +18,14 @@ if [ ! -e ~/.local/bin/gnome-kiosk-script ]; then
|
||||
exec "$0" "$@"
|
||||
EOF
|
||||
|
||||
- chmod +x ~/.local/bin/gnome-kiosk-script
|
||||
+ chmod +x $EXECDIR/gnome-kiosk-script
|
||||
touch ~/.config/gnome-initial-setup-done
|
||||
fi
|
||||
|
||||
-exec ~/.local/bin/gnome-kiosk-script "$@"
|
||||
+# Copy and run the script from the XDG_RUNTIME_DIR directory if that exists
|
||||
+if [ -d $XDG_RUNTIME_DIR ]; then
|
||||
+ cp $EXECDIR/gnome-kiosk-script $XDG_RUNTIME_DIR/
|
||||
+ EXECDIR=$XDG_RUNTIME_DIR
|
||||
+fi
|
||||
+
|
||||
+exec $EXECDIR/gnome-kiosk-script "$@"
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
From fea0d74ff155f05e9f1e8e0351562af6c7c15b3c Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Tue, 4 Mar 2025 16:21:30 +0100
|
||||
Subject: [PATCH 1/2] search-app: Add systemd session files
|
||||
|
||||
The search appliance session would fail to start as a systemd session.
|
||||
|
||||
Add the required systemd plumbing to fix the search appliance session.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/gnome-kiosk/-/merge_requests/66>
|
||||
|
||||
(cherry picked from commit a40ac8d8dc132d9c94506419158ec4034eaaf2c8)
|
||||
---
|
||||
meson.build | 12 ++++++++++++
|
||||
.../systemd/org.gnome.Kiosk.SearchApp.service.in | 8 ++++++++
|
||||
search-app/systemd/session.conf | 3 +++
|
||||
3 files changed, 23 insertions(+)
|
||||
create mode 100644 search-app/systemd/org.gnome.Kiosk.SearchApp.service.in
|
||||
create mode 100644 search-app/systemd/session.conf
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index fb9a76d..2024b76 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -350,5 +350,17 @@ i18n.merge_file(
|
||||
type: 'desktop'
|
||||
)
|
||||
|
||||
+configure_file(
|
||||
+ input: 'search-app/systemd/org.gnome.Kiosk.SearchApp.service.in',
|
||||
+ output: '@BASENAME@',
|
||||
+ configuration: systemd_service_config_data,
|
||||
+ install_dir: systemd_user_unit_dir
|
||||
+)
|
||||
+
|
||||
+kiosk_search_appliance_systemd_target_dir = join_paths(systemd_user_unit_dir, 'gnome-session@org.gnome.Kiosk.SearchApp.target.d')
|
||||
+install_data('search-app/systemd/session.conf',
|
||||
+ install_dir: kiosk_search_appliance_systemd_target_dir
|
||||
+)
|
||||
+
|
||||
test('check-format', find_program('scripts/check-format.sh'))
|
||||
|
||||
diff --git a/search-app/systemd/org.gnome.Kiosk.SearchApp.service.in b/search-app/systemd/org.gnome.Kiosk.SearchApp.service.in
|
||||
new file mode 100644
|
||||
index 0000000..29ddcd8
|
||||
--- /dev/null
|
||||
+++ b/search-app/systemd/org.gnome.Kiosk.SearchApp.service.in
|
||||
@@ -0,0 +1,8 @@
|
||||
+[Unit]
|
||||
+Description=Kiosk Search Appliance
|
||||
+BindsTo=gnome-session.target
|
||||
+After=gnome-session.target
|
||||
+
|
||||
+[Service]
|
||||
+ExecStart=@bindir@/firefox --kiosk --private-window --new-instance https://www.google.com
|
||||
+Restart=always
|
||||
diff --git a/search-app/systemd/session.conf b/search-app/systemd/session.conf
|
||||
new file mode 100644
|
||||
index 0000000..1ab41da
|
||||
--- /dev/null
|
||||
+++ b/search-app/systemd/session.conf
|
||||
@@ -0,0 +1,3 @@
|
||||
+[Unit]
|
||||
+Requires=org.gnome.Kiosk.target
|
||||
+Requires=org.gnome.Kiosk.SearchApp.service
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
From bad81e556eca3acad1b97f6dbc00f3788e24d25f Mon Sep 17 00:00:00 2001
|
||||
From c8c4aac6d68bc864fa197d0bef0a747c70dd67f3 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Thu, 12 Dec 2024 14:05:04 +0100
|
||||
Subject: [PATCH] search-app: Use firefox from flatpak
|
||||
@ -37,5 +37,5 @@ index 29ddcd8..d4f5d0f 100644
|
||||
+ExecStart=@bindir@/flatpak run --command=firefox --file-forwarding org.mozilla.firefox --kiosk --private-window --new-instance https://www.google.com
|
||||
Restart=always
|
||||
--
|
||||
2.48.1
|
||||
2.51.1
|
||||
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
From 108aa947aaf8bf14a26756ba078bcf4141b6434b Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 30 Jul 2025 15:15:34 +0200
|
||||
Subject: [PATCH 1/3] shell-service: Fix GrabAccelerators return value
|
||||
|
||||
The DBus definitions expects an array of uint32, not an array of
|
||||
variants.
|
||||
|
||||
(cherry picked from commit e9477c3cbdd81a14888b0b08ef38aa70188f736e)
|
||||
---
|
||||
compositor/kiosk-shell-service.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/compositor/kiosk-shell-service.c b/compositor/kiosk-shell-service.c
|
||||
index a6b4258..4f21ae2 100644
|
||||
--- a/compositor/kiosk-shell-service.c
|
||||
+++ b/compositor/kiosk-shell-service.c
|
||||
@@ -332,8 +332,7 @@ kiosk_shell_service_handle_grab_accelerators (KioskShellDBusService *object,
|
||||
guint action_id;
|
||||
|
||||
action_id = grab_accelerator_for_client (self, accelerator, mode_flags, grab_flags, client_unique_name);
|
||||
-
|
||||
- g_variant_builder_add (&builder, "u", g_variant_new_uint32 (action_id));
|
||||
+ g_variant_builder_add (&builder, "u", action_id);
|
||||
}
|
||||
|
||||
kiosk_shell_dbus_service_complete_grab_accelerators (KIOSK_SHELL_DBUS_SERVICE (self),
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From 9dd06017bf85eb779579342f7f5e7955017aa893 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 16 Jul 2025 11:51:49 +0200
|
||||
Subject: [PATCH] systemd/session: Enable remote session
|
||||
|
||||
To be able to get something on screen when starting a session remotely,
|
||||
using remote login via gdm, the session has to pull in gsd-sharing, i.e.
|
||||
the session wants the SettingsDaemon Sharing target.
|
||||
---
|
||||
kiosk-script/systemd/session.conf | 1 +
|
||||
search-app/systemd/session.conf | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/kiosk-script/systemd/session.conf b/kiosk-script/systemd/session.conf
|
||||
index a948efb..aeb722c 100644
|
||||
--- a/kiosk-script/systemd/session.conf
|
||||
+++ b/kiosk-script/systemd/session.conf
|
||||
@@ -1,3 +1,4 @@
|
||||
[Unit]
|
||||
Requires=org.gnome.Kiosk.target
|
||||
Requires=org.gnome.Kiosk.Script.service
|
||||
+Wants=org.gnome.SettingsDaemon.Sharing.target
|
||||
diff --git a/search-app/systemd/session.conf b/search-app/systemd/session.conf
|
||||
index 1ab41da..d038670 100644
|
||||
--- a/search-app/systemd/session.conf
|
||||
+++ b/search-app/systemd/session.conf
|
||||
@@ -1,3 +1,4 @@
|
||||
[Unit]
|
||||
Requires=org.gnome.Kiosk.target
|
||||
Requires=org.gnome.Kiosk.SearchApp.service
|
||||
+Wants=org.gnome.SettingsDaemon.Sharing.target
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@ -1,892 +0,0 @@
|
||||
From 0ab97a3be415e7cc3937d68fd66a421f96f45417 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Fri, 24 Jan 2025 09:41:04 +0100
|
||||
Subject: [PATCH 2/2] compositor: Add Shell Screenshot support
|
||||
|
||||
Add support for the org.gnome.Shell.Screenshot DBus API which is
|
||||
required by the desktop portals.
|
||||
|
||||
Not all of the org.gnome.Shell.Screenshot API is implemented though,
|
||||
only the non-interactive part which require no UI interaction are
|
||||
currently available. Also missing is the pick-color API.
|
||||
|
||||
To have access to the Shell screenshot API from all other clients,
|
||||
gnome-kiosk needs to be started in unsafe mode (using the command line
|
||||
option "--unsafe-mode").
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/gnome-kiosk/-/merge_requests/61>
|
||||
(cherry picked from commit 5338c8ab454b8cad607e2f696a9a352b375dff0d)
|
||||
---
|
||||
compositor/kiosk-compositor.c | 4 +
|
||||
compositor/kiosk-shell-screenshot-service.c | 599 ++++++++++++++++++
|
||||
compositor/kiosk-shell-screenshot-service.h | 23 +
|
||||
.../org.gnome.Shell.Screenshot.xml | 161 +++++
|
||||
meson.build | 12 +
|
||||
5 files changed, 799 insertions(+)
|
||||
create mode 100644 compositor/kiosk-shell-screenshot-service.c
|
||||
create mode 100644 compositor/kiosk-shell-screenshot-service.h
|
||||
create mode 100644 dbus-interfaces/org.gnome.Shell.Screenshot.xml
|
||||
|
||||
diff --git a/compositor/kiosk-compositor.c b/compositor/kiosk-compositor.c
|
||||
index d5a2b64..8432a24 100644
|
||||
--- a/compositor/kiosk-compositor.c
|
||||
+++ b/compositor/kiosk-compositor.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "kiosk-app-system.h"
|
||||
#include "kiosk-window-tracker.h"
|
||||
#include "kiosk-shell-introspect-service.h"
|
||||
+#include "kiosk-shell-screenshot-service.h"
|
||||
|
||||
#include "org.gnome.DisplayManager.Manager.h"
|
||||
|
||||
@@ -46,6 +47,7 @@ struct _KioskCompositor
|
||||
KioskAppSystem *app_system;
|
||||
KioskWindowTracker *tracker;
|
||||
KioskShellIntrospectService *introspect_service;
|
||||
+ KioskShellScreenshotService *screenshot_service;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -250,6 +252,8 @@ kiosk_compositor_start (MetaPlugin *plugin)
|
||||
self->tracker = kiosk_window_tracker_new (self, self->app_system);
|
||||
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);
|
||||
+ kiosk_shell_screenshot_service_start (self->screenshot_service, &error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_debug ("KioskCompositor: Could not start D-Bus service: %s", error->message);
|
||||
diff --git a/compositor/kiosk-shell-screenshot-service.c b/compositor/kiosk-shell-screenshot-service.c
|
||||
new file mode 100644
|
||||
index 0000000..a961905
|
||||
--- /dev/null
|
||||
+++ b/compositor/kiosk-shell-screenshot-service.c
|
||||
@@ -0,0 +1,599 @@
|
||||
+#include "config.h"
|
||||
+#include "kiosk-shell-screenshot-service.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <meta/display.h>
|
||||
+#include <meta/meta-context.h>
|
||||
+
|
||||
+#include "kiosk-compositor.h"
|
||||
+#include "kiosk-screenshot.h"
|
||||
+
|
||||
+#define KIOSK_SHELL_SCREENSHOT_SERVICE_BUS_NAME "org.gnome.Shell.Screenshot"
|
||||
+#define KIOSK_SHELL_SCREENSHOT_SERVICE_OBJECT_PATH "/org/gnome/Shell/Screenshot"
|
||||
+
|
||||
+struct _KioskShellScreenshotService
|
||||
+{
|
||||
+ KioskShellScreenshotDBusServiceSkeleton parent;
|
||||
+
|
||||
+ /* weak references */
|
||||
+ KioskCompositor *compositor;
|
||||
+ MetaDisplay *display;
|
||||
+ MetaContext *context;
|
||||
+
|
||||
+ /* strong references */
|
||||
+ GCancellable *cancellable;
|
||||
+ KioskScreenshot *screenshot;
|
||||
+
|
||||
+ /* handles */
|
||||
+ guint bus_id;
|
||||
+};
|
||||
+
|
||||
+struct KioskShellScreenshotCompletion
|
||||
+{
|
||||
+ KioskShellScreenshotDBusService *service;
|
||||
+ GDBusMethodInvocation *invocation;
|
||||
+
|
||||
+ gpointer data;
|
||||
+};
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ PROP_COMPOSITOR = 1,
|
||||
+ NUMBER_OF_PROPERTIES
|
||||
+};
|
||||
+
|
||||
+static GParamSpec *kiosk_shell_screenshot_service_properties[NUMBER_OF_PROPERTIES] = { NULL, };
|
||||
+
|
||||
+static void kiosk_shell_screenshot_dbus_service_interface_init (KioskShellScreenshotDBusServiceIface *interface);
|
||||
+
|
||||
+G_DEFINE_TYPE_WITH_CODE (KioskShellScreenshotService,
|
||||
+ kiosk_shell_screenshot_service,
|
||||
+ KIOSK_TYPE_SHELL_SCREENSHOT_DBUS_SERVICE_SKELETON,
|
||||
+ G_IMPLEMENT_INTERFACE (KIOSK_TYPE_SHELL_SCREENSHOT_DBUS_SERVICE,
|
||||
+ kiosk_shell_screenshot_dbus_service_interface_init));
|
||||
+
|
||||
+static void kiosk_shell_screenshot_service_set_property (GObject *object,
|
||||
+ guint property_id,
|
||||
+ const GValue *value,
|
||||
+ GParamSpec *param_spec);
|
||||
+
|
||||
+static void kiosk_shell_screenshot_service_constructed (GObject *object);
|
||||
+static void kiosk_shell_screenshot_service_dispose (GObject *object);
|
||||
+
|
||||
+static void
|
||||
+kiosk_shell_screenshot_service_class_init (KioskShellScreenshotServiceClass *shell_service_class)
|
||||
+{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (shell_service_class);
|
||||
+
|
||||
+ object_class->constructed = kiosk_shell_screenshot_service_constructed;
|
||||
+ object_class->set_property = kiosk_shell_screenshot_service_set_property;
|
||||
+ object_class->dispose = kiosk_shell_screenshot_service_dispose;
|
||||
+
|
||||
+ kiosk_shell_screenshot_service_properties[PROP_COMPOSITOR] =
|
||||
+ g_param_spec_object ("compositor",
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ KIOSK_TYPE_COMPOSITOR,
|
||||
+ G_PARAM_CONSTRUCT_ONLY
|
||||
+ | G_PARAM_WRITABLE
|
||||
+ | G_PARAM_STATIC_NAME);
|
||||
+ g_object_class_install_properties (object_class,
|
||||
+ NUMBER_OF_PROPERTIES,
|
||||
+ kiosk_shell_screenshot_service_properties);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_shell_screenshot_service_set_property (GObject *object,
|
||||
+ guint property_id,
|
||||
+ const GValue *value,
|
||||
+ GParamSpec *param_spec)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+
|
||||
+ switch (property_id) {
|
||||
+ case PROP_COMPOSITOR:
|
||||
+ g_set_weak_pointer (&self->compositor, g_value_get_object (value));
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_shell_screenshot_service_dispose (GObject *object)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+
|
||||
+ kiosk_shell_screenshot_service_stop (self);
|
||||
+
|
||||
+ g_clear_object (&self->screenshot);
|
||||
+ g_clear_weak_pointer (&self->context);
|
||||
+ g_clear_weak_pointer (&self->display);
|
||||
+ g_clear_weak_pointer (&self->compositor);
|
||||
+
|
||||
+ G_OBJECT_CLASS (kiosk_shell_screenshot_service_parent_class)->dispose (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_shell_screenshot_service_constructed (GObject *object)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+
|
||||
+ self->screenshot = kiosk_screenshot_new (self->compositor);
|
||||
+
|
||||
+ g_set_weak_pointer (&self->display, meta_plugin_get_display (META_PLUGIN (self->compositor)));
|
||||
+ g_set_weak_pointer (&self->context, meta_display_get_context (self->display));
|
||||
+
|
||||
+ G_OBJECT_CLASS (kiosk_shell_screenshot_service_parent_class)->constructed (object);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_check_access (KioskShellScreenshotService *self,
|
||||
+ const char *client_unique_name)
|
||||
+{
|
||||
+ GValue value = G_VALUE_INIT;
|
||||
+ gboolean unsafe_mode;
|
||||
+
|
||||
+ g_object_get_property (G_OBJECT (self->context), "unsafe-mode", &value);
|
||||
+ unsafe_mode = g_value_get_boolean (&value);
|
||||
+ g_debug ("KioskShellScreenshotService: unsafe-mode is %s",
|
||||
+ unsafe_mode ? "TRUE" : "FALSE");
|
||||
+
|
||||
+ return unsafe_mode;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+completion_dispose (struct KioskShellScreenshotCompletion *completion)
|
||||
+{
|
||||
+ g_object_unref (completion->service);
|
||||
+ g_object_unref (completion->invocation);
|
||||
+ g_free (completion->data);
|
||||
+
|
||||
+ g_free (completion);
|
||||
+}
|
||||
+
|
||||
+static struct KioskShellScreenshotCompletion *
|
||||
+completion_new (KioskShellScreenshotDBusService *service,
|
||||
+ GDBusMethodInvocation *invocation,
|
||||
+ const char *filename)
|
||||
+{
|
||||
+ struct KioskShellScreenshotCompletion *completion;
|
||||
+
|
||||
+ completion = g_new0 (struct KioskShellScreenshotCompletion, 1);
|
||||
+ completion->service = g_object_ref (service);
|
||||
+ completion->invocation = g_object_ref (invocation);
|
||||
+ completion->data = g_strdup (filename);
|
||||
+
|
||||
+ return completion;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_service_handle_flash_area (KioskShellScreenshotDBusService *object,
|
||||
+ GDBusMethodInvocation *invocation,
|
||||
+ gint arg_x,
|
||||
+ gint arg_y,
|
||||
+ gint arg_width,
|
||||
+ gint arg_height)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+ const char *client_unique_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Handling FlashArea(x=%i, y=%i, w=%i, h=%i) from %s",
|
||||
+ arg_x, arg_y, arg_width, arg_height, client_unique_name);
|
||||
+
|
||||
+ if (!kiosk_shell_screenshot_check_access (self, client_unique_name)) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||
+ "Permission denied");
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
+ "FlashArea is not supported");
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_service_handle_interactive_screenshot (KioskShellScreenshotDBusService *object,
|
||||
+ GDBusMethodInvocation *invocation)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+ const char *client_unique_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Handling InteractiveScreenshot() from %s",
|
||||
+ client_unique_name);
|
||||
+
|
||||
+ if (!kiosk_shell_screenshot_check_access (self, client_unique_name)) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||
+ "Permission denied");
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
+ "InteractiveScreenshot is not supported");
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+screenshot_ready_callback (GObject *source_object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer data)
|
||||
+{
|
||||
+ struct KioskShellScreenshotCompletion *completion = data;
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (completion->service);
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ gboolean success = TRUE;
|
||||
+
|
||||
+ kiosk_screenshot_screenshot_finish (self->screenshot,
|
||||
+ result,
|
||||
+ NULL,
|
||||
+ &error);
|
||||
+
|
||||
+ if (error) {
|
||||
+ g_warning ("Screenshot failed: %s", error->message);
|
||||
+ success = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ kiosk_shell_screenshot_dbus_service_complete_screenshot (completion->service,
|
||||
+ completion->invocation,
|
||||
+ success,
|
||||
+ completion->data);
|
||||
+
|
||||
+ completion_dispose (completion);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_service_handle_screenshot (KioskShellScreenshotDBusService *object,
|
||||
+ GDBusMethodInvocation *invocation,
|
||||
+ gboolean arg_include_cursor,
|
||||
+ gboolean arg_flash,
|
||||
+ const gchar *arg_filename)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+ const char *client_unique_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
+ struct KioskShellScreenshotCompletion *completion;
|
||||
+ g_autoptr (GFile) file = NULL;
|
||||
+ g_autoptr (GFileOutputStream) stream = NULL;
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ g_autoptr (GAsyncResult) result = NULL;
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Handling Screenshot(cursor=%i, flash=%i, file='%s') from %s",
|
||||
+ arg_include_cursor, arg_flash, arg_filename, client_unique_name);
|
||||
+
|
||||
+ if (!kiosk_shell_screenshot_check_access (self, client_unique_name)) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||
+ "Permission denied");
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ file = g_file_new_for_path (arg_filename);
|
||||
+ stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &error);
|
||||
+ if (error) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_FAILED,
|
||||
+ "Error creating file: %s",
|
||||
+ error->message);
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ completion = completion_new (object, invocation, arg_filename);
|
||||
+ kiosk_screenshot_screenshot (self->screenshot,
|
||||
+ arg_include_cursor,
|
||||
+ G_OUTPUT_STREAM (stream),
|
||||
+ screenshot_ready_callback,
|
||||
+ completion);
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+screenshot_area_ready_callback (GObject *source_object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer data)
|
||||
+{
|
||||
+ struct KioskShellScreenshotCompletion *completion = data;
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (completion->service);
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ gboolean success = TRUE;
|
||||
+
|
||||
+ kiosk_screenshot_screenshot_area_finish (self->screenshot,
|
||||
+ result,
|
||||
+ NULL,
|
||||
+ &error);
|
||||
+
|
||||
+ if (error) {
|
||||
+ g_warning ("Screenshot area failed: %s", error->message);
|
||||
+ success = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ kiosk_shell_screenshot_dbus_service_complete_screenshot_area (completion->service,
|
||||
+ completion->invocation,
|
||||
+ success,
|
||||
+ completion->data);
|
||||
+
|
||||
+ completion_dispose (completion);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_service_handle_screenshot_area (KioskShellScreenshotDBusService *object,
|
||||
+ GDBusMethodInvocation *invocation,
|
||||
+ gint arg_x,
|
||||
+ gint arg_y,
|
||||
+ gint arg_width,
|
||||
+ gint arg_height,
|
||||
+ gboolean arg_flash,
|
||||
+ const gchar *arg_filename)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+ const char *client_unique_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
+ struct KioskShellScreenshotCompletion *completion;
|
||||
+ g_autoptr (GFile) file = NULL;
|
||||
+ g_autoptr (GFileOutputStream) stream = NULL;
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ g_autoptr (GAsyncResult) result = NULL;
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Handling ScreenshotArea(x=%i, y=%i, w=%i, h=%i, flash=%i, file='%s') from %s",
|
||||
+ arg_x, arg_y, arg_width, arg_height, arg_flash, arg_filename, client_unique_name);
|
||||
+
|
||||
+ if (!kiosk_shell_screenshot_check_access (self, client_unique_name)) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||
+ "Permission denied");
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ file = g_file_new_for_path (arg_filename);
|
||||
+ stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &error);
|
||||
+ if (error) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_FAILED,
|
||||
+ "Error creating file: %s",
|
||||
+ error->message);
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ completion = completion_new (object, invocation, arg_filename);
|
||||
+ kiosk_screenshot_screenshot_area (self->screenshot,
|
||||
+ arg_x,
|
||||
+ arg_y,
|
||||
+ arg_width,
|
||||
+ arg_height,
|
||||
+ G_OUTPUT_STREAM (stream),
|
||||
+ screenshot_area_ready_callback,
|
||||
+ completion);
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+screenshot_window_ready_callback (GObject *source_object,
|
||||
+ GAsyncResult *result,
|
||||
+ gpointer data)
|
||||
+{
|
||||
+ struct KioskShellScreenshotCompletion *completion = data;
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (completion->service);
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ gboolean success = TRUE;
|
||||
+
|
||||
+ kiosk_screenshot_screenshot_window_finish (self->screenshot,
|
||||
+ result,
|
||||
+ NULL,
|
||||
+ &error);
|
||||
+
|
||||
+ if (error) {
|
||||
+ g_warning ("Screenshot window failed: %s", error->message);
|
||||
+ success = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ kiosk_shell_screenshot_dbus_service_complete_screenshot_window (completion->service,
|
||||
+ completion->invocation,
|
||||
+ success,
|
||||
+ completion->data);
|
||||
+
|
||||
+ completion_dispose (completion);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_service_handle_screenshot_window (KioskShellScreenshotDBusService *object,
|
||||
+ GDBusMethodInvocation *invocation,
|
||||
+ gboolean arg_include_frame,
|
||||
+ gboolean arg_include_cursor,
|
||||
+ gboolean arg_flash,
|
||||
+ const gchar *arg_filename)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+ const char *client_unique_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
+ struct KioskShellScreenshotCompletion *completion;
|
||||
+ g_autoptr (GFile) file = NULL;
|
||||
+ g_autoptr (GFileOutputStream) stream = NULL;
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+ g_autoptr (GAsyncResult) result = NULL;
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Handling ScreenshotWindow(frame=%i, cursor=%i, flash=%i, file='%s') from %s",
|
||||
+ arg_include_frame, arg_include_cursor, arg_flash, arg_filename, client_unique_name);
|
||||
+
|
||||
+ if (!kiosk_shell_screenshot_check_access (self, client_unique_name)) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||
+ "Permission denied");
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ file = g_file_new_for_path (arg_filename);
|
||||
+ stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &error);
|
||||
+ if (error) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_FAILED,
|
||||
+ "Error creating file: %s",
|
||||
+ error->message);
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ completion = completion_new (object, invocation, arg_filename);
|
||||
+ kiosk_screenshot_screenshot_window (self->screenshot,
|
||||
+ arg_include_frame,
|
||||
+ arg_include_cursor,
|
||||
+ G_OUTPUT_STREAM (stream),
|
||||
+ screenshot_window_ready_callback,
|
||||
+ completion);
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+kiosk_shell_screenshot_service_handle_select_area (KioskShellScreenshotDBusService *object,
|
||||
+ GDBusMethodInvocation *invocation)
|
||||
+{
|
||||
+ KioskShellScreenshotService *self = KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+ const char *client_unique_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Handling SelectArea() from %s",
|
||||
+ client_unique_name);
|
||||
+
|
||||
+ if (!kiosk_shell_screenshot_check_access (self, client_unique_name)) {
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||
+ "Permission denied");
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ g_dbus_method_invocation_return_error (invocation,
|
||||
+ G_DBUS_ERROR,
|
||||
+ G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
+ "SelectArea is not supported");
|
||||
+
|
||||
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_shell_screenshot_dbus_service_interface_init (KioskShellScreenshotDBusServiceIface *interface)
|
||||
+{
|
||||
+ interface->handle_flash_area =
|
||||
+ kiosk_shell_screenshot_service_handle_flash_area;
|
||||
+ interface->handle_interactive_screenshot =
|
||||
+ kiosk_shell_screenshot_service_handle_interactive_screenshot;
|
||||
+ interface->handle_screenshot =
|
||||
+ kiosk_shell_screenshot_service_handle_screenshot;
|
||||
+ interface->handle_screenshot_area =
|
||||
+ kiosk_shell_screenshot_service_handle_screenshot_area;
|
||||
+ interface->handle_screenshot_window =
|
||||
+ kiosk_shell_screenshot_service_handle_screenshot_window;
|
||||
+ interface->handle_select_area =
|
||||
+ kiosk_shell_screenshot_service_handle_select_area;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_shell_screenshot_service_init (KioskShellScreenshotService *self)
|
||||
+{
|
||||
+ g_debug ("KioskShellScreenshotService: Initializing");
|
||||
+}
|
||||
+
|
||||
+KioskShellScreenshotService *
|
||||
+kiosk_shell_screenshot_service_new (KioskCompositor *compositor)
|
||||
+{
|
||||
+ GObject *object;
|
||||
+
|
||||
+ object = g_object_new (KIOSK_TYPE_SHELL_SCREENSHOT_SERVICE,
|
||||
+ "compositor", compositor,
|
||||
+ NULL);
|
||||
+
|
||||
+ return KIOSK_SHELL_SCREENSHOT_SERVICE (object);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_user_bus_acquired (GDBusConnection *connection,
|
||||
+ const char *unique_name,
|
||||
+ KioskShellScreenshotService *self)
|
||||
+{
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Connected to user bus");
|
||||
+
|
||||
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self),
|
||||
+ connection,
|
||||
+ KIOSK_SHELL_SCREENSHOT_SERVICE_OBJECT_PATH,
|
||||
+ &error);
|
||||
+
|
||||
+ if (error != NULL) {
|
||||
+ g_debug ("KioskShellScreenshotService: Could not export interface skeleton: %s",
|
||||
+ error->message);
|
||||
+ g_clear_error (&error);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_bus_name_acquired (GDBusConnection *connection,
|
||||
+ const char *name,
|
||||
+ KioskShellScreenshotService *self)
|
||||
+{
|
||||
+ if (g_strcmp0 (name, KIOSK_SHELL_SCREENSHOT_SERVICE_BUS_NAME) != 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Acquired name %s", name);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_bus_name_lost (GDBusConnection *connection,
|
||||
+ const char *name,
|
||||
+ KioskShellScreenshotService *self)
|
||||
+{
|
||||
+ if (g_strcmp0 (name, KIOSK_SHELL_SCREENSHOT_SERVICE_BUS_NAME) != 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Lost name %s", name);
|
||||
+}
|
||||
+
|
||||
+gboolean
|
||||
+kiosk_shell_screenshot_service_start (KioskShellScreenshotService *self,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ g_return_val_if_fail (KIOSK_IS_SHELL_SCREENSHOT_SERVICE (self), FALSE);
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Starting");
|
||||
+ self->bus_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
||||
+ KIOSK_SHELL_SCREENSHOT_SERVICE_BUS_NAME,
|
||||
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
|
||||
+ (GBusAcquiredCallback) on_user_bus_acquired,
|
||||
+ (GBusNameAcquiredCallback) on_bus_name_acquired,
|
||||
+ (GBusNameVanishedCallback) on_bus_name_lost,
|
||||
+ self,
|
||||
+ NULL);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+kiosk_shell_screenshot_service_stop (KioskShellScreenshotService *self)
|
||||
+{
|
||||
+ g_return_if_fail (KIOSK_IS_SHELL_SCREENSHOT_SERVICE (self));
|
||||
+
|
||||
+ g_debug ("KioskShellScreenshotService: Stopping");
|
||||
+
|
||||
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
|
||||
+ g_clear_handle_id (&self->bus_id, g_bus_unown_name);
|
||||
+}
|
||||
diff --git a/compositor/kiosk-shell-screenshot-service.h b/compositor/kiosk-shell-screenshot-service.h
|
||||
new file mode 100644
|
||||
index 0000000..520c319
|
||||
--- /dev/null
|
||||
+++ b/compositor/kiosk-shell-screenshot-service.h
|
||||
@@ -0,0 +1,23 @@
|
||||
+#pragma once
|
||||
+
|
||||
+#include <glib-object.h>
|
||||
+
|
||||
+#include "org.gnome.Shell.Screenshot.h"
|
||||
+
|
||||
+typedef struct _KioskCompositor KioskCompositor;
|
||||
+
|
||||
+G_BEGIN_DECLS
|
||||
+
|
||||
+#define KIOSK_TYPE_SHELL_SCREENSHOT_SERVICE (kiosk_shell_screenshot_service_get_type ())
|
||||
+
|
||||
+G_DECLARE_FINAL_TYPE (KioskShellScreenshotService,
|
||||
+ kiosk_shell_screenshot_service,
|
||||
+ KIOSK, SHELL_SCREENSHOT_SERVICE,
|
||||
+ KioskShellScreenshotDBusServiceSkeleton);
|
||||
+
|
||||
+KioskShellScreenshotService *kiosk_shell_screenshot_service_new (KioskCompositor *compositor);
|
||||
+gboolean kiosk_shell_screenshot_service_start (KioskShellScreenshotService *service,
|
||||
+ GError **error);
|
||||
+void kiosk_shell_screenshot_service_stop (KioskShellScreenshotService *service);
|
||||
+
|
||||
+G_END_DECLS
|
||||
diff --git a/dbus-interfaces/org.gnome.Shell.Screenshot.xml b/dbus-interfaces/org.gnome.Shell.Screenshot.xml
|
||||
new file mode 100644
|
||||
index 0000000..8e16a30
|
||||
--- /dev/null
|
||||
+++ b/dbus-interfaces/org.gnome.Shell.Screenshot.xml
|
||||
@@ -0,0 +1,161 @@
|
||||
+<!DOCTYPE node PUBLIC
|
||||
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||
+<node>
|
||||
+
|
||||
+ <!--
|
||||
+ org.gnome.Shell.Screenshot:
|
||||
+ @short_description: Screenshot interface
|
||||
+
|
||||
+ The interface used to capture pictures of the screen contents.
|
||||
+ -->
|
||||
+ <interface name="org.gnome.Shell.Screenshot">
|
||||
+
|
||||
+ <!--
|
||||
+ InteractiveScreenshot:
|
||||
+ @success: whether the screenshot was captured
|
||||
+ @uri: the file where the screenshot was saved
|
||||
+
|
||||
+ Shows Shell's interactive screenshot dialog, and lets the
|
||||
+ user take an interactive screenshot, which is then returned
|
||||
+ in @filename as png image. It returns a boolean indicating
|
||||
+ whether the operation was successful or not. The URI of the
|
||||
+ screenshot will be returned in @uri.
|
||||
+ -->
|
||||
+ <method name="InteractiveScreenshot">
|
||||
+ <arg type="b" direction="out" name="success"/>
|
||||
+ <arg type="s" direction="out" name="uri"/>
|
||||
+ </method>
|
||||
+
|
||||
+ <!--
|
||||
+ Screenshot:
|
||||
+ @filename: The filename for the screenshot
|
||||
+ @include_cursor: Whether to include the cursor image or not
|
||||
+ @flash: Whether to flash the screen or not
|
||||
+ @success: whether the screenshot was captured
|
||||
+ @filename_used: the file where the screenshot was saved
|
||||
+
|
||||
+ Takes a screenshot of the whole screen and saves it
|
||||
+ in @filename as png image, it returns a boolean
|
||||
+ indicating whether the operation was successful or not.
|
||||
+ @filename can either be an absolute path or a basename, in
|
||||
+ which case the screenshot will be saved in the $XDG_PICTURES_DIR
|
||||
+ or the home directory if it doesn't exist. The filename used
|
||||
+ to save the screenshot will be returned in @filename_used.
|
||||
+ -->
|
||||
+ <method name="Screenshot">
|
||||
+ <arg type="b" direction="in" name="include_cursor"/>
|
||||
+ <arg type="b" direction="in" name="flash"/>
|
||||
+ <arg type="s" direction="in" name="filename"/>
|
||||
+ <arg type="b" direction="out" name="success"/>
|
||||
+ <arg type="s" direction="out" name="filename_used"/>
|
||||
+ </method>
|
||||
+
|
||||
+ <!--
|
||||
+ ScreenshotWindow:
|
||||
+ @include_frame: Whether to include the frame or not
|
||||
+ @include_cursor: Whether to include the cursor image or not
|
||||
+ @flash: Whether to flash the window area or not
|
||||
+ @filename: The filename for the screenshot
|
||||
+ @success: whether the screenshot was captured
|
||||
+ @filename_used: the file where the screenshot was saved
|
||||
+
|
||||
+ Takes a screenshot of the focused window (optionally omitting the frame)
|
||||
+ and saves it in @filename as png image, it returns a boolean
|
||||
+ indicating whether the operation was successful or not.
|
||||
+ @filename can either be an absolute path or a basename, in
|
||||
+ which case the screenshot will be saved in the $XDG_PICTURES_DIR
|
||||
+ or the home directory if it doesn't exist. The filename used
|
||||
+ to save the screenshot will be returned in @filename_used.
|
||||
+ -->
|
||||
+ <method name="ScreenshotWindow">
|
||||
+ <arg type="b" direction="in" name="include_frame"/>
|
||||
+ <arg type="b" direction="in" name="include_cursor"/>
|
||||
+ <arg type="b" direction="in" name="flash"/>
|
||||
+ <arg type="s" direction="in" name="filename"/>
|
||||
+ <arg type="b" direction="out" name="success"/>
|
||||
+ <arg type="s" direction="out" name="filename_used"/>
|
||||
+ </method>
|
||||
+
|
||||
+ <!--
|
||||
+ ScreenshotArea:
|
||||
+ @x: the X coordinate of the area to capture
|
||||
+ @y: the Y coordinate of the area to capture
|
||||
+ @width: the width of the area to capture
|
||||
+ @height: the height of the area to capture
|
||||
+ @flash: whether to flash the area or not
|
||||
+ @filename: the filename for the screenshot
|
||||
+ @success: whether the screenshot was captured
|
||||
+ @filename_used: the file where the screenshot was saved
|
||||
+
|
||||
+ Takes a screenshot of the passed in area and saves it
|
||||
+ in @filename as png image, it returns a boolean
|
||||
+ indicating whether the operation was successful or not.
|
||||
+ @filename can either be an absolute path or a basename, in
|
||||
+ which case the screenshot will be saved in the $XDG_PICTURES_DIR
|
||||
+ or the home directory if it doesn't exist. The filename used
|
||||
+ to save the screenshot will be returned in @filename_used.
|
||||
+ -->
|
||||
+ <method name="ScreenshotArea">
|
||||
+ <arg type="i" direction="in" name="x"/>
|
||||
+ <arg type="i" direction="in" name="y"/>
|
||||
+ <arg type="i" direction="in" name="width"/>
|
||||
+ <arg type="i" direction="in" name="height"/>
|
||||
+ <arg type="b" direction="in" name="flash"/>
|
||||
+ <arg type="s" direction="in" name="filename"/>
|
||||
+ <arg type="b" direction="out" name="success"/>
|
||||
+ <arg type="s" direction="out" name="filename_used"/>
|
||||
+ </method>
|
||||
+
|
||||
+ <!--
|
||||
+ PickColor:
|
||||
+
|
||||
+ Picks a color and returns the result.
|
||||
+
|
||||
+ The @result vardict contains:
|
||||
+ <variablelist>
|
||||
+ <varlistentry>
|
||||
+ <term>color (ddd)</term>
|
||||
+ <listitem><para>The color, RGB values in the range [0,1].</para></listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ -->
|
||||
+ <method name="PickColor">
|
||||
+ <arg type="a{sv}" direction="out" name="result"/>
|
||||
+ </method>
|
||||
+
|
||||
+ <!--
|
||||
+ FlashArea:
|
||||
+ @x: the X coordinate of the area to flash
|
||||
+ @y: the Y coordinate of the area to flash
|
||||
+ @width: the width of the area to flash
|
||||
+ @height: the height of the area to flash
|
||||
+
|
||||
+ Renders a flash spot effect in the specified rectangle of the screen.
|
||||
+ -->
|
||||
+ <method name="FlashArea">
|
||||
+ <arg type="i" direction="in" name="x"/>
|
||||
+ <arg type="i" direction="in" name="y"/>
|
||||
+ <arg type="i" direction="in" name="width"/>
|
||||
+ <arg type="i" direction="in" name="height"/>
|
||||
+ </method>
|
||||
+
|
||||
+ <!--
|
||||
+ SelectArea:
|
||||
+ @x: the X coordinate of the selected area
|
||||
+ @y: the Y coordinate of the selected area
|
||||
+ @width: the width of the selected area
|
||||
+ @height: the height of the selected area
|
||||
+
|
||||
+ Interactively allows the user to select a rectangular area of
|
||||
+ the screen, and returns its coordinates.
|
||||
+ -->
|
||||
+ <method name="SelectArea">
|
||||
+ <arg type="i" direction="out" name="x"/>
|
||||
+ <arg type="i" direction="out" name="y"/>
|
||||
+ <arg type="i" direction="out" name="width"/>
|
||||
+ <arg type="i" direction="out" name="height"/>
|
||||
+ </method>
|
||||
+
|
||||
+ </interface>
|
||||
+</node>
|
||||
diff --git a/meson.build b/meson.build
|
||||
index d1efcab..d5941bf 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -116,6 +116,17 @@ sources = gnome.gdbus_codegen(dbus_interface, dbus_interface_file,
|
||||
)
|
||||
dbus_interface_sources_map += { dbus_interface: sources }
|
||||
|
||||
+dbus_interface = 'org.gnome.Shell.Screenshot'
|
||||
+dbus_interface_file = join_paths('dbus-interfaces', dbus_interface + '.xml')
|
||||
+sources = gnome.gdbus_codegen(dbus_interface, dbus_interface_file,
|
||||
+ namespace: 'Kiosk',
|
||||
+ interface_prefix: 'org.gnome',
|
||||
+ annotations: [
|
||||
+ [ dbus_interface, 'org.gtk.GDBus.C.Name', 'ShellScreenshotDBusService' ]
|
||||
+ ]
|
||||
+)
|
||||
+dbus_interface_sources_map += { dbus_interface: sources }
|
||||
+
|
||||
compositor_dependencies = []
|
||||
compositor_dependencies += c_compiler.find_library('m')
|
||||
compositor_dependencies += dependency('gio-2.0')
|
||||
@@ -154,6 +165,7 @@ compositor_sources += 'compositor/kiosk-input-source-group.c'
|
||||
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-screenshot.c'
|
||||
|
||||
if mutter_have_x11
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@ -1,517 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
From a695282b8da73fe7df50293f177855a9b3c92416 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 30 Jul 2025 15:16:54 +0200
|
||||
Subject: [PATCH 2/3] compositor: Use the Shell service
|
||||
|
||||
The Shell service is used by gnome-settings-daemon to implement media
|
||||
keys.
|
||||
|
||||
That in turn allows to start the screen reader, audio control, etc.
|
||||
|
||||
(cherry picked from commit 722055b88747d5b6cc4de0875f4b9f0169fcf9c2)
|
||||
---
|
||||
compositor/kiosk-compositor.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/compositor/kiosk-compositor.c b/compositor/kiosk-compositor.c
|
||||
index aa5603d..73f5524 100644
|
||||
--- a/compositor/kiosk-compositor.c
|
||||
+++ b/compositor/kiosk-compositor.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "kiosk-service.h"
|
||||
#include "kiosk-app-system.h"
|
||||
#include "kiosk-window-tracker.h"
|
||||
+#include "kiosk-shell-service.h"
|
||||
#include "kiosk-shell-introspect-service.h"
|
||||
#include "kiosk-shell-screenshot-service.h"
|
||||
#include "kiosk-window-config.h"
|
||||
@@ -51,6 +52,7 @@ struct _KioskCompositor
|
||||
KioskShellIntrospectService *introspect_service;
|
||||
KioskShellScreenshotService *screenshot_service;
|
||||
KioskWindowConfig *kiosk_window_config;
|
||||
+ KioskShellService *shell_service;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -84,6 +86,7 @@ kiosk_compositor_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&self->backgrounds);
|
||||
g_clear_object (&self->automount_manager);
|
||||
+ g_clear_object (&self->shell_service);
|
||||
|
||||
G_OBJECT_CLASS (kiosk_compositor_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -293,6 +296,8 @@ kiosk_compositor_start (MetaPlugin *plugin)
|
||||
kiosk_shell_introspect_service_start (self->introspect_service, &error);
|
||||
self->screenshot_service = kiosk_shell_screenshot_service_new (self);
|
||||
kiosk_shell_screenshot_service_start (self->screenshot_service, &error);
|
||||
+ self->shell_service = kiosk_shell_service_new (self);
|
||||
+ kiosk_shell_service_start (self->shell_service, &error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_debug ("KioskCompositor: Could not start D-Bus service: %s", error->message);
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
From 30d48384d2b98dc6ba9534ef41ce445f6da41d7f Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 5 Mar 2025 14:23:49 +0100
|
||||
Subject: [PATCH 2/2] search-app: Update desktop file definition
|
||||
|
||||
Firefox itself has nothing to do with neither Gtk or GNOME, no need to
|
||||
list those in the categories.
|
||||
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/gnome-kiosk/-/merge_requests/66>
|
||||
|
||||
(cherry picked from commit 5441999573a07c3513eeda5150683448bdd71c50)
|
||||
---
|
||||
search-app/org.gnome.Kiosk.SearchApp.desktop.in.in | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/search-app/org.gnome.Kiosk.SearchApp.desktop.in.in b/search-app/org.gnome.Kiosk.SearchApp.desktop.in.in
|
||||
index 360e6df..478b328 100644
|
||||
--- a/search-app/org.gnome.Kiosk.SearchApp.desktop.in.in
|
||||
+++ b/search-app/org.gnome.Kiosk.SearchApp.desktop.in.in
|
||||
@@ -3,7 +3,6 @@ Type=Application
|
||||
Name=Search Appliance
|
||||
Comment=Sample Search Appliance Application for GNOME Kiosk
|
||||
Exec=@bindir@/firefox --kiosk --private-window --new-instance https://www.google.com
|
||||
-Categories=GNOME;GTK;Core;
|
||||
-OnlyShowIn=GNOME;
|
||||
+Categories=Core;System;
|
||||
NoDisplay=true
|
||||
-X-GNOME-AutoRestart=true
|
||||
+X-GNOME-HiddenUnderSystemd=true
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
From 3bec84a57c51906880a1cf25d3255158ed6e9825 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Tue, 29 Jul 2025 18:08:24 +0200
|
||||
Subject: [PATCH 3/3] systemd/sessions: Add Mediakeys support
|
||||
|
||||
That allows to start the screen reader using the default key shortcut.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/gnome-kiosk/-/issues/46
|
||||
(cherry picked from commit eacd8f733cdf8f53923268de43ff09cace758e50)
|
||||
---
|
||||
kiosk-script/systemd/session.conf | 1 +
|
||||
search-app/systemd/session.conf | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/kiosk-script/systemd/session.conf b/kiosk-script/systemd/session.conf
|
||||
index aeb722c..5652e83 100644
|
||||
--- a/kiosk-script/systemd/session.conf
|
||||
+++ b/kiosk-script/systemd/session.conf
|
||||
@@ -2,3 +2,4 @@
|
||||
Requires=org.gnome.Kiosk.target
|
||||
Requires=org.gnome.Kiosk.Script.service
|
||||
Wants=org.gnome.SettingsDaemon.Sharing.target
|
||||
+Wants=org.gnome.SettingsDaemon.MediaKeys.target
|
||||
diff --git a/search-app/systemd/session.conf b/search-app/systemd/session.conf
|
||||
index d038670..e37baf7 100644
|
||||
--- a/search-app/systemd/session.conf
|
||||
+++ b/search-app/systemd/session.conf
|
||||
@@ -2,3 +2,4 @@
|
||||
Requires=org.gnome.Kiosk.target
|
||||
Requires=org.gnome.Kiosk.SearchApp.service
|
||||
Wants=org.gnome.SettingsDaemon.Sharing.target
|
||||
+Wants=org.gnome.SettingsDaemon.MediaKeys.target
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
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
|
||||
|
||||
@ -5,13 +5,13 @@
|
||||
%global gnome_desktop_version 44.0
|
||||
%global glib2_version 2.68.0
|
||||
%global gtk4_version 3.24.27
|
||||
%global mutter_version 47.5-9
|
||||
%global mutter_version 49~beta
|
||||
%global gsettings_desktop_schemas_version 40~rc
|
||||
%global ibus_version 1.5.24
|
||||
%global gnome_settings_daemon_version 40~rc
|
||||
|
||||
Name: gnome-kiosk
|
||||
Version: 47.0
|
||||
Version: 49.0
|
||||
Release: %{autorelease}
|
||||
Summary: Window management and application launching for GNOME
|
||||
|
||||
@ -35,7 +35,7 @@ BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version}
|
||||
BuildRequires: pkgconfig(gnome-desktop-4) >= %{gnome_desktop_version}
|
||||
BuildRequires: pkgconfig(gtk4) >= %{gtk4_version}
|
||||
BuildRequires: pkgconfig(ibus-1.0) >= %{ibus_version}
|
||||
BuildRequires: pkgconfig(libmutter-15) >= %{mutter_version}
|
||||
BuildRequires: pkgconfig(libmutter-17) >= %{mutter_version}
|
||||
BuildRequires: pkgconfig(gdk-pixbuf-2.0)
|
||||
|
||||
Requires: gnome-settings-daemon%{?_isa} >= %{gnome_settings_daemon_version}
|
||||
@ -44,32 +44,8 @@ Requires: mutter%{?_isa} >= %{mutter_version}
|
||||
Recommends: xorg-x11-server-Xwayland
|
||||
Recommends: dbus-daemon
|
||||
|
||||
Patch: 0001-kiosk-app-Do-not-add-the-window-in-kiosk_app_new_for.patch
|
||||
# https://issues.redhat.com/browse/RHEL-71757
|
||||
Patch: 0001-kiosk-script-Copy-and-run-the-script-from-XDG_RUNTIM.patch
|
||||
# https://issues.redhat.com/browse/RHEL-62420
|
||||
Patch: 0001-compositor-Add-screenshot-utilities.patch
|
||||
Patch: 0002-compositor-Add-Shell-Screenshot-support.patch
|
||||
# https://issues.redhat.com/browse/RHEL-82250
|
||||
# https://issues.redhat.com/browse/RHEL-82404
|
||||
Patch: 0001-search-app-Add-systemd-session-files.patch
|
||||
Patch: 0002-search-app-Update-desktop-file-definition.patch
|
||||
# https://issues.redhat.com/browse/RHEL-36521
|
||||
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
|
||||
# https://issues.redhat.com/browse/RHEL-103639
|
||||
Patch: 0001-systemd-session-Enable-remote-session.patch
|
||||
# https://issues.redhat.com/browse/RHEL-106584
|
||||
Patch: 0001-shell-service-Fix-GrabAccelerators-return-value.patch
|
||||
Patch: 0002-compositor-Use-the-Shell-service.patch
|
||||
Patch: 0003-systemd-sessions-Add-Mediakeys-support.patch
|
||||
|
||||
%description
|
||||
GNOME Kiosk provides a desktop enviroment suitable for fixed purpose, or
|
||||
|
||||
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (gnome-kiosk-47.0.tar.xz) = 497b7e3500d4afc38f9d57a4a40c2ea2ad834365989893d71742ce02c1e67cd7976bf884d02248b269a2141ca865845beac97e130bfe1032dbebaa95cfe52e4f
|
||||
SHA512 (gnome-kiosk-49.0.tar.xz) = a2d92b39516b7f70074f4ef210ddf98215820699d717973f4addeafa9e68875d0e8b49913a5f175027878aab5eca7b810abd20c8df1a7b011ac9e573560feacb
|
||||
|
||||
Loading…
Reference in New Issue
Block a user