diff options
author | Corey Berla <corey@berla.me> | 2022-06-10 09:59:27 -0700 |
---|---|---|
committer | António Fernandes <antoniojpfernandes@gmail.com> | 2022-07-14 22:09:29 +0000 |
commit | d219b85d61eeed8ecc8743dfd9fb689894e04e24 (patch) | |
tree | 9d08b6cf0b6e1998200cbb20c997dc92132b34d1 | |
parent | c5fd01a8e50098e1cd564e88962b230cba5d0964 (diff) | |
download | nautilus-d219b85d61eeed8ecc8743dfd9fb689894e04e24.tar.gz |
dbus-launcher: Launch programs via DBUS
Nautilus launches external programs (i.e. Settings & gnome-disks)
directly via the commandline which doesn't work in flatpaks.
Create new module nautilus-dbus-launcher to allow for launching
these programs via DBus. nautilus-application holds ono a
singleton instance of the dbus launcher (similar to undo manager
and tag manager) so we don't need to create proxies over and over again.
-rw-r--r-- | build-aux/flatpak/org.gnome.Nautilus.json | 2 | ||||
-rw-r--r-- | build-aux/flatpak/org.gnome.Nautilus.yml | 2 | ||||
-rw-r--r-- | src/meson.build | 2 | ||||
-rw-r--r-- | src/nautilus-application.c | 7 | ||||
-rw-r--r-- | src/nautilus-dbus-launcher.c | 211 | ||||
-rw-r--r-- | src/nautilus-dbus-launcher.h | 37 |
6 files changed, 261 insertions, 0 deletions
diff --git a/build-aux/flatpak/org.gnome.Nautilus.json b/build-aux/flatpak/org.gnome.Nautilus.json index 91d05dab7..e3610fe3c 100644 --- a/build-aux/flatpak/org.gnome.Nautilus.json +++ b/build-aux/flatpak/org.gnome.Nautilus.json @@ -22,6 +22,8 @@ "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro", "--talk-name=ca.desrt.dconf", + "--talk-name=org.gnome.DiskUtility", + "--talk-name=org.gnome.Settings", "--env=DCONF_USER_CONFIG_DIR=.config/dconf", "--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:FileSystem;tracker:Documents" ], diff --git a/build-aux/flatpak/org.gnome.Nautilus.yml b/build-aux/flatpak/org.gnome.Nautilus.yml index d4117d3bc..f38144943 100644 --- a/build-aux/flatpak/org.gnome.Nautilus.yml +++ b/build-aux/flatpak/org.gnome.Nautilus.yml @@ -21,6 +21,8 @@ finish-args: - "--filesystem=xdg-run/dconf" - "--filesystem=~/.config/dconf:ro" - "--talk-name=ca.desrt.dconf" +- "--talk-name=org.gnome.DiskUtility" +- "--talk-name=org.gnome.Settings" - "--env=DCONF_USER_CONFIG_DIR=.config/dconf" # Access to host Tracker Miners - "--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:FileSystem;tracker:Documents" diff --git a/src/meson.build b/src/meson.build index edcfe0d91..e76fe7c25 100644 --- a/src/meson.build +++ b/src/meson.build @@ -151,6 +151,8 @@ libnautilus_sources = [ 'nautilus-column-chooser.h', 'nautilus-column-utilities.c', 'nautilus-column-utilities.h', + 'nautilus-dbus-launcher.c', + 'nautilus-dbus-launcher.h', 'nautilus-debug.c', 'nautilus-debug.h', 'nautilus-directory-async.c', diff --git a/src/nautilus-application.c b/src/nautilus-application.c index 05080733e..2898e052c 100644 --- a/src/nautilus-application.c +++ b/src/nautilus-application.c @@ -43,6 +43,7 @@ #include "nautilus-bookmark-list.h" #include "nautilus-clipboard.h" +#include "nautilus-dbus-launcher.h" #include "nautilus-dbus-manager.h" #include "nautilus-directory-private.h" #include "nautilus-file.h" @@ -85,6 +86,8 @@ typedef struct NautilusTagManager *tag_manager; + NautilusDBusLauncher *dbus_launcher; + guint previewer_selection_id; } NautilusApplicationPrivate; @@ -586,6 +589,8 @@ nautilus_application_finalize (GObject *object) g_clear_object (&priv->tag_manager); + g_clear_object (&priv->dbus_launcher); + G_OBJECT_CLASS (nautilus_application_parent_class)->finalize (object); } @@ -1039,6 +1044,8 @@ nautilus_application_init (NautilusApplication *self) priv->undo_manager = nautilus_file_undo_manager_new (); priv->tag_manager = nautilus_tag_manager_new (); + priv->dbus_launcher = nautilus_dbus_launcher_new (); + g_application_add_main_option_entries (G_APPLICATION (self), options); nautilus_ensure_extension_points (); diff --git a/src/nautilus-dbus-launcher.c b/src/nautilus-dbus-launcher.c new file mode 100644 index 000000000..df27bd7ee --- /dev/null +++ b/src/nautilus-dbus-launcher.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2022 Corey Berla <corey@berla.me> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "nautilus-dbus-launcher.h" + +#include <glib/gi18n.h> + +#include "nautilus-file.h" +#include "nautilus-ui-utilities.h" + + +typedef struct +{ + GDBusProxy *proxy; + GError *error; + gboolean ping_on_creation; +} NautilusDBusLauncherData; + +struct _NautilusDBusLauncher +{ + GObject parent; + + NautilusDBusLauncherData *data[NAUTILUS_DBUS_LAUNCHER_N_APPS]; +}; + +G_DEFINE_TYPE (NautilusDBusLauncher, nautilus_dbus_launcher, G_TYPE_OBJECT) + +static NautilusDBusLauncher *launcher = NULL; + +static void +on_nautilus_dbus_launcher_call_finished (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GtkWindow *window = user_data; + g_autoptr (GError) error = NULL; + g_autofree char *message = NULL; + + g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + if (error != NULL) + { + g_warning ("Error calling proxy %s", error->message); + message = g_strdup_printf (_("Details: %s"), error->message); + show_dialog (_("There was an error launching the application."), + message, + window, + GTK_MESSAGE_ERROR); + } +} + +static void +on_nautilus_dbus_launcher_ping_finished (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NautilusDBusLauncherData *data = user_data; + GError *error = NULL; + + g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + + data->error = error; +} + +void +nautilus_dbus_launcher_call (NautilusDBusLauncher *self, + NautilusDBusLauncherApp app, + const gchar *method_name, + GVariant *parameters, + GtkWindow *window) +{ + if (self->data[app]->proxy != NULL) + { + g_dbus_proxy_call (self->data[app]->proxy, + method_name, + parameters, + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + on_nautilus_dbus_launcher_call_finished, + window); + } + else if (window != NULL) + { + show_dialog (_("There was an error launching the application."), + _("Details: The proxy has not been created."), + window, + GTK_MESSAGE_ERROR); + } +} + +static void +on_nautilus_dbus_proxy_ready (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NautilusDBusLauncherData *data = user_data; + GError *error = NULL; + + data->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (error != NULL) + { + g_warning ("Error creating proxy %s", error->message); + data->error = error; + } + else if (data->ping_on_creation) + { + g_dbus_proxy_call (data->proxy, + "org.freedesktop.DBus.Peer.Ping", NULL, + G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, + on_nautilus_dbus_launcher_ping_finished, data); + } +} + +static void +nautilus_dbus_launcher_create_proxy (NautilusDBusLauncherData *data, + const gchar *name, + const gchar *object_path, + const gchar *interface) +{ + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION, + NULL, + name, + object_path, + interface, + NULL, + on_nautilus_dbus_proxy_ready, + data); +} + +gboolean nautilus_dbus_launcher_is_available (NautilusDBusLauncher *self, + NautilusDBusLauncherApp app) +{ + return self->data[app]->error == NULL; +} + +NautilusDBusLauncher * +nautilus_dbus_launcher_get (void) +{ + return launcher; +} + +NautilusDBusLauncher * +nautilus_dbus_launcher_new (void) +{ + if (launcher != NULL) + { + return g_object_ref (launcher); + } + launcher = g_object_new (NAUTILUS_TYPE_DBUS_LAUNCHER, NULL); + g_object_add_weak_pointer (G_OBJECT (launcher), (gpointer) & launcher); + + return launcher; +} + +static void +nautilus_dbus_launcher_finalize (GObject *object) +{ + NautilusDBusLauncher *self = NAUTILUS_DBUS_LAUNCHER (object); + + for (gint i = 0; i < NAUTILUS_DBUS_LAUNCHER_N_APPS - 1; i++) + { + g_clear_object (&self->data[i]->proxy); + g_clear_object (&self->data[i]->error); + g_free (self->data[i]); + } + + G_OBJECT_CLASS (nautilus_dbus_launcher_parent_class)->finalize (object); +} + +static void +nautilus_dbus_launcher_class_init (NautilusDBusLauncherClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = nautilus_dbus_launcher_finalize; +} + +static NautilusDBusLauncherData * +nautilus_dbus_launcher_data_new (gboolean ping_on_creation) +{ + NautilusDBusLauncherData *data; + + data = g_new0 (NautilusDBusLauncherData, 1); + data->proxy = NULL; + data->error = NULL; + data->ping_on_creation = ping_on_creation; + + return data; +} + +static void +nautilus_dbus_launcher_init (NautilusDBusLauncher *self) +{ + self->data[NAUTILUS_DBUS_LAUNCHER_SETTINGS] = nautilus_dbus_launcher_data_new (FALSE); + self->data[NAUTILUS_DBUS_LAUNCHER_DISKS] = nautilus_dbus_launcher_data_new (TRUE); + + nautilus_dbus_launcher_create_proxy (self->data[NAUTILUS_DBUS_LAUNCHER_SETTINGS], + "org.gnome.Settings", "/org/gnome/Settings", + "org.gtk.Actions"); + + nautilus_dbus_launcher_create_proxy (self->data[NAUTILUS_DBUS_LAUNCHER_DISKS], + "org.gnome.DiskUtility", "/org/gnome/DiskUtility", + "org.gtk.Application"); +} diff --git a/src/nautilus-dbus-launcher.h b/src/nautilus-dbus-launcher.h new file mode 100644 index 000000000..60f4233c7 --- /dev/null +++ b/src/nautilus-dbus-launcher.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 Corey Berla <corey@berla.me> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include <glib.h> +#include <gtk/gtk.h> + +#include "nautilus-file.h" + +#define NAUTILUS_TYPE_DBUS_LAUNCHER (nautilus_dbus_launcher_get_type()) + +G_DECLARE_FINAL_TYPE (NautilusDBusLauncher, nautilus_dbus_launcher, NAUTILUS, DBUS_LAUNCHER, GObject) + + +typedef enum { + NAUTILUS_DBUS_LAUNCHER_SETTINGS, + NAUTILUS_DBUS_LAUNCHER_DISKS, + NAUTILUS_DBUS_LAUNCHER_N_APPS +} NautilusDBusLauncherApp; + +NautilusDBusLauncher * nautilus_dbus_launcher_new (void); //to be called on `NautilusApplication::startup` only + +NautilusDBusLauncher * nautilus_dbus_launcher_get (void); //to be called by consumers; doesn't change reference count. + +gboolean nautilus_dbus_launcher_is_available (NautilusDBusLauncher *self, + NautilusDBusLauncherApp app); + +void nautilus_dbus_launcher_call (NautilusDBusLauncher *self, + NautilusDBusLauncherApp app, + const gchar *method_name, + GVariant *parameters, + GtkWindow *window); + |