From 0ab97a3be415e7cc3937d68fd66a421f96f45417 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan 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: (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 +#include +#include +#include + +#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 + +#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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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