/* * Copyright (C) 2022 Corey Berla * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "nautilus-dbus-launcher.h" #include #include "nautilus-file.h" #include "nautilus-ui-utilities.h" typedef struct { GDBusProxy *proxy; gchar *error; GCancellable *cancellable; gboolean ping_on_creation; } NautilusDBusLauncherData; struct _NautilusDBusLauncher { GObject parent; NautilusDBusLauncherApp last_app_initialized; 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; g_autoptr (GError) error = NULL; g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (error != NULL) { data->error = g_strdup (error->message); } g_clear_object (&data->cancellable); } 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; g_autoptr (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 = g_strdup (error->message); g_clear_object (&data->cancellable); } 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, data->cancellable, 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, data->cancellable, on_nautilus_dbus_proxy_ready, data); } gboolean nautilus_dbus_launcher_is_available (NautilusDBusLauncher *self, NautilusDBusLauncherApp app) { return self->data[app]->error == NULL && self->data[app]->proxy != 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 = 1; i <= self->last_app_initialized; i++) { g_clear_object (&self->data[i]->proxy); g_free (self->data[i]->error); g_cancellable_cancel (self->data[i]->cancellable); g_clear_object (&self->data[i]->cancellable); 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 void nautilus_dbus_launcher_data_init (NautilusDBusLauncher *self, NautilusDBusLauncherApp app, gboolean ping_on_creation) { NautilusDBusLauncherData *data; g_assert_true (app == self->last_app_initialized + 1); data = g_new0 (NautilusDBusLauncherData, 1); data->proxy = NULL; data->error = NULL; data->ping_on_creation = ping_on_creation; data->cancellable = g_cancellable_new (); self->data[app] = data; self->last_app_initialized = app; } static void nautilus_dbus_launcher_init (NautilusDBusLauncher *self) { nautilus_dbus_launcher_data_init (self, NAUTILUS_DBUS_LAUNCHER_SETTINGS, FALSE); nautilus_dbus_launcher_data_init (self, NAUTILUS_DBUS_LAUNCHER_DISKS, TRUE); nautilus_dbus_launcher_data_init (self, NAUTILUS_DBUS_LAUNCHER_CONSOLE, 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"); nautilus_dbus_launcher_create_proxy (self->data[NAUTILUS_DBUS_LAUNCHER_CONSOLE], "org.gnome.Console", "/org/gnome/Console", "org.freedesktop.Application"); }