summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Berla <corey@berla.me>2022-06-10 09:59:27 -0700
committerAntónio Fernandes <antoniojpfernandes@gmail.com>2022-07-14 22:09:29 +0000
commitd219b85d61eeed8ecc8743dfd9fb689894e04e24 (patch)
tree9d08b6cf0b6e1998200cbb20c997dc92132b34d1
parentc5fd01a8e50098e1cd564e88962b230cba5d0964 (diff)
downloadnautilus-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.json2
-rw-r--r--build-aux/flatpak/org.gnome.Nautilus.yml2
-rw-r--r--src/meson.build2
-rw-r--r--src/nautilus-application.c7
-rw-r--r--src/nautilus-dbus-launcher.c211
-rw-r--r--src/nautilus-dbus-launcher.h37
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);
+