diff options
author | Stefano Karapetsas <[email protected]> | 2013-02-23 22:02:09 +0100 |
---|---|---|
committer | Stefano Karapetsas <[email protected]> | 2013-02-23 22:02:09 +0100 |
commit | d1715e4fdef385cea4eda116090311dcff9fcd18 (patch) | |
tree | 1c86cab85e0e254924edb953560cac3a94626521 | |
parent | e99cd96502845cce688ee4f545eb4a4f2edfb23a (diff) | |
download | caja-d1715e4fdef385cea4eda116090311dcff9fcd18.tar.bz2 caja-d1715e4fdef385cea4eda116090311dcff9fcd18.tar.xz |
Add support for freedesktop.org File Manager DBus Interface
http://www.freedesktop.org/wiki/Specifications/file-manager-interface
Most of code is adapted from Nautilus:
http://git.gnome.org/browse/nautilus/tree/src/nautilus-freedesktop-dbus.c
Closes https://github.com/mate-desktop/mate-file-manager/issues/3
-rw-r--r-- | data/Makefile.am | 9 | ||||
-rw-r--r-- | data/freedesktop-dbus-interfaces.xml | 36 | ||||
-rw-r--r-- | data/org.mate.freedesktop.FileManager1.service.in | 3 | ||||
-rw-r--r-- | src/Makefile.am | 16 | ||||
-rw-r--r-- | src/caja-application.c | 36 | ||||
-rw-r--r-- | src/caja-application.h | 5 | ||||
-rw-r--r-- | src/caja-freedesktop-dbus.c | 245 | ||||
-rw-r--r-- | src/caja-freedesktop-dbus.h | 42 |
8 files changed, 391 insertions, 1 deletions
diff --git a/data/Makefile.am b/data/Makefile.am index 0e8fb977..bee031c1 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -19,6 +19,14 @@ desktop_in_files = \ mimedir = $(datadir)/mime/packages mime_DATA = $(xml_files) +servicedir = $(datadir)/dbus-1/services +service_DATA = $(service_in_files:.service.in=.service) +service_in_files = \ + org.mate.freedesktop.FileManager1.service.in + +org.mate.freedesktop.FileManager1.service: org.mate.freedesktop.FileManager1.service.in Makefile + $(AM_V_GEN) sed -e "s|\@bindir\@|$(bindir)|" $< > $@ + cajadatadir = $(datadir)/caja cajadata_DATA = \ @@ -30,6 +38,7 @@ cajadata_DATA = \ EXTRA_DIST = $(cajadata_DATA) \ caja.desktop \ caja.desktop.in \ + freedesktop-dbus-interfaces.xml \ $(xml_in_files) \ $(desktop_in_files) \ $(NULL) diff --git a/data/freedesktop-dbus-interfaces.xml b/data/freedesktop-dbus-interfaces.xml new file mode 100644 index 00000000..ab135b6a --- /dev/null +++ b/data/freedesktop-dbus-interfaces.xml @@ -0,0 +1,36 @@ +<!DOCTYPE node PUBLIC +"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<!-- + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. +--> +<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> + <interface name='org.freedesktop.FileManager1'> + <method name='ShowFolders'> + <arg type='as' name='URIs' direction='in'/> + <arg type='s' name='StartupId' direction='in'/> + </method> + <method name='ShowItems'> + <arg type='as' name='URIs' direction='in'/> + <arg type='s' name='StartupId' direction='in'/> + </method> + <method name='ShowItemProperties'> + <arg type='as' name='URIs' direction='in'/> + <arg type='s' name='StartupId' direction='in'/> + </method> + </interface> +</node> diff --git a/data/org.mate.freedesktop.FileManager1.service.in b/data/org.mate.freedesktop.FileManager1.service.in new file mode 100644 index 00000000..801361b6 --- /dev/null +++ b/data/org.mate.freedesktop.FileManager1.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.freedesktop.FileManager1 +Exec=@bindir@/caja --no-default-window diff --git a/src/Makefile.am b/src/Makefile.am index 28c97fc1..84ee8b5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,19 @@ LDADD = \ $(POPT_LIBS) \ $(NULL) +dbus_freedesktop_built_sources = \ + caja-freedesktop-generated.c \ + caja-freedesktop-generated.h + +$(dbus_freedesktop_built_sources) : Makefile.am $(top_srcdir)/data/freedesktop-dbus-interfaces.xml + gdbus-codegen \ + --interface-prefix org.freedesktop. \ + --c-namespace CajaFreedesktop \ + --c-generate-object-manager \ + --generate-c-code caja-freedesktop-generated \ + $(top_srcdir)/data/freedesktop-dbus-interfaces.xml \ + $(NULL) + @INTLTOOL_DESKTOP_RULE@ desktop_in_files=mate-network-scheme.desktop.in @@ -55,6 +68,7 @@ scheme_DATA = mate-network-scheme.desktop BUILT_SOURCES = \ caja-src-marshal.c \ caja-src-marshal.h \ + $(dbus_freedesktop_built_sources) \ $(NULL) caja_SOURCES = \ @@ -76,6 +90,8 @@ caja_SOURCES = \ caja-emblem-sidebar.h \ caja-file-management-properties.c \ caja-file-management-properties.h \ + caja-freedesktop-dbus.c \ + caja-freedesktop-dbus.h \ caja-history-sidebar.c \ caja-history-sidebar.h \ caja-image-properties-page.c \ diff --git a/src/caja-application.c b/src/caja-application.c index f70fbae7..b4f180f5 100644 --- a/src/caja-application.c +++ b/src/caja-application.c @@ -55,6 +55,7 @@ #include "libcaja-private/caja-file-operations.h" #include "caja-window-private.h" #include "caja-window-manage-views.h" +#include "caja-freedesktop-dbus.h" #include <unistd.h> #include <libxml/xmlsave.h> #include <glib/gstdio.h> @@ -107,6 +108,9 @@ static GList *caja_application_spatial_window_list; /* The saving of the accelerator map was requested */ static gboolean save_of_accel_map_requested = FALSE; +/* File Manager DBus Interface */ +static CajaFreedesktopDBus *fdb_manager = NULL; + static void desktop_changed_callback (gpointer user_data); static void desktop_location_changed_callback (gpointer user_data); static void mount_removed_callback (GVolumeMonitor *monitor, @@ -370,6 +374,12 @@ caja_application_finalize (GObject *object) application->proxy = NULL; } + if (fdb_manager != NULL) + { + g_object_unref (fdb_manager); + fdb_manager = NULL; + } + G_OBJECT_CLASS (caja_application_parent_class)->finalize (object); } @@ -846,6 +856,29 @@ open_windows (CajaApplication *application, } } +void +caja_application_open_location (CajaApplication *application, + GFile *location, + GFile *selection, + const char *startup_id) +{ + CajaWindow *window; + GList *sel_list = NULL; + + window = caja_application_create_navigation_window (application, startup_id, gdk_screen_get_default ()); + + if (selection != NULL) { + sel_list = g_list_prepend (NULL, g_object_ref (selection)); + } + + caja_window_slot_open_location_full (caja_window_get_active_slot (window), location, + 0, CAJA_WINDOW_OPEN_FLAG_NEW_WINDOW, sel_list, NULL, NULL); + + if (sel_list != NULL) { + caja_file_list_free (sel_list); + } +} + static UniqueResponse message_received_cb (UniqueApp *unique_app, gint command, @@ -985,6 +1018,9 @@ caja_application_startup (CajaApplication *application, g_signal_connect (application->unique_app, "message-received", G_CALLBACK (message_received_cb), application); } + /* Start the File Manager DBus Interface */ + fdb_manager = caja_freedesktop_dbus_new (application); + /* Monitor the preference to show or hide the desktop */ g_signal_connect_swapped (mate_background_preferences, "changed::" MATE_BG_KEY_SHOW_DESKTOP, diff --git a/src/caja-application.h b/src/caja-application.h index 426f2c09..0ad62f07 100644 --- a/src/caja-application.h +++ b/src/caja-application.h @@ -105,6 +105,9 @@ void caja_application_close_all_spatial_windows (void); void caja_application_open_desktop (CajaApplication *application); void caja_application_close_desktop (void); gboolean caja_application_save_accel_map (gpointer data); - +void caja_application_open_location (CajaApplication *application, + GFile *location, + GFile *selection, + const char *startup_id); #endif /* CAJA_APPLICATION_H */ diff --git a/src/caja-freedesktop-dbus.c b/src/caja-freedesktop-dbus.c new file mode 100644 index 00000000..1ce79c8f --- /dev/null +++ b/src/caja-freedesktop-dbus.c @@ -0,0 +1,245 @@ +/* + * caja-freedesktop-dbus: Implementation for the org.freedesktop DBus file-management interfaces + * + * Caja is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Caja is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Authors: Akshay Gupta <[email protected]> + * Federico Mena Quintero <[email protected]> + * Stefano Karapetsas <[email protected]> + */ + +#include <config.h> + +#include "caja-application.h" +#include "caja-freedesktop-dbus.h" +#include "caja-freedesktop-generated.h" + +#include <libcaja-private/caja-debug-log.h> + +#include "file-manager/fm-properties-window.h" + +#include <gio/gio.h> + +struct _CajaFreedesktopDBus { + GObject parent; + + /* Id from g_dbus_own_name() */ + guint owner_id; + + /* DBus paraphernalia */ + GDBusObjectManagerServer *object_manager; + + /* Our DBus implementation skeleton */ + CajaFreedesktopFileManager1 *skeleton; + + /* Caja application */ + CajaApplication *application; +}; + +struct _CajaFreedesktopDBusClass { + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (CajaFreedesktopDBus, caja_freedesktop_dbus, G_TYPE_OBJECT); + +static gboolean +skeleton_handle_show_items_cb (CajaFreedesktopFileManager1 *object, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *startup_id, + CajaFreedesktopDBus *fdb) +{ + CajaApplication *application; + int i; + + application = CAJA_APPLICATION (fdb->application); + + for (i = 0; uris[i] != NULL; i++) { + GFile *file; + GFile *parent; + + file = g_file_new_for_uri (uris[i]); + parent = g_file_get_parent (file); + + if (parent != NULL) { + caja_application_open_location (application, parent, file, startup_id); + g_object_unref (parent); + } else { + caja_application_open_location (application, file, NULL, startup_id); + } + + g_object_unref (file); + } + + caja_freedesktop_file_manager1_complete_show_items (object, invocation); + return TRUE; +} + +static gboolean +skeleton_handle_show_folders_cb (CajaFreedesktopFileManager1 *object, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *startup_id, + CajaFreedesktopDBus *fdb) +{ + CajaApplication *application; + int i; + + application = CAJA_APPLICATION (fdb->application); + + for (i = 0; uris[i] != NULL; i++) { + GFile *file; + + file = g_file_new_for_uri (uris[i]); + + caja_application_open_location (application, file, NULL, startup_id); + + g_object_unref (file); + } + + caja_freedesktop_file_manager1_complete_show_folders (object, invocation); + return TRUE; +} + +static gboolean +skeleton_handle_show_item_properties_cb (CajaFreedesktopFileManager1 *object, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *startup_id, + CajaFreedesktopDBus *fdb) +{ + CajaApplication *application; + CajaWindow *window; + GList *files; + int i; + + application = CAJA_APPLICATION (fdb->application); + files = NULL; + + for (i = 0; uris[i] != NULL; i++) { + files = g_list_prepend (files, caja_file_get_by_uri (uris[i])); + } + + files = g_list_reverse (files); + + if (uris[0] != NULL) { + GFile *file; + file = g_file_new_for_uri (uris[i]); + window = caja_application_get_spatial_window (application, + NULL, + startup_id, + file, + gdk_screen_get_default (), + NULL); + fm_properties_window_present (files, window); + g_object_unref (file); + } + + caja_file_list_free (files); + + caja_freedesktop_file_manager1_complete_show_item_properties (object, invocation); + return TRUE; +} + +static void +bus_acquired_cb (GDBusConnection *conn, + const gchar *name, + CajaFreedesktopDBus *fdb) +{ + caja_debug_log (FALSE, CAJA_DEBUG_LOG_DOMAIN_USER, "Bus acquired at %s", name); + + fdb->object_manager = g_dbus_object_manager_server_new (CAJA_FDO_DBUS_PATH); + + fdb->skeleton = caja_freedesktop_file_manager1_skeleton_new (); + + g_signal_connect (fdb->skeleton, "handle-show-items", + G_CALLBACK (skeleton_handle_show_items_cb), fdb); + g_signal_connect (fdb->skeleton, "handle-show-folders", + G_CALLBACK (skeleton_handle_show_folders_cb), fdb); + g_signal_connect (fdb->skeleton, "handle-show-item-properties", + G_CALLBACK (skeleton_handle_show_item_properties_cb), fdb); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (fdb->skeleton), conn, CAJA_FDO_DBUS_PATH, NULL); + + g_dbus_object_manager_server_set_connection (fdb->object_manager, conn); +} + +static void +name_acquired_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + caja_debug_log (FALSE, CAJA_DEBUG_LOG_DOMAIN_USER, "Acquired the name %s on the session message bus\n", name); +} + +static void +name_lost_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + caja_debug_log (FALSE, CAJA_DEBUG_LOG_DOMAIN_USER, "Lost (or failed to acquire) the name %s on the session message bus\n", name); +} + +static void +caja_freedesktop_dbus_dispose (GObject *object) +{ + CajaFreedesktopDBus *fdb = (CajaFreedesktopDBus *) object; + + if (fdb->owner_id != 0) { + g_bus_unown_name (fdb->owner_id); + fdb->owner_id = 0; + } + + if (fdb->skeleton != NULL) { + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (fdb->skeleton)); + g_object_unref (fdb->skeleton); + fdb->skeleton = NULL; + } + + g_clear_object (&fdb->object_manager); + + G_OBJECT_CLASS (caja_freedesktop_dbus_parent_class)->dispose (object); +} + +static void +caja_freedesktop_dbus_class_init (CajaFreedesktopDBusClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = caja_freedesktop_dbus_dispose; +} + +static void +caja_freedesktop_dbus_init (CajaFreedesktopDBus *fdb) +{ + fdb->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + CAJA_FDO_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_cb, + name_acquired_cb, + name_lost_cb, + fdb, + NULL); +} + +/* Tries to own the org.freedesktop.FileManager1 service name */ +CajaFreedesktopDBus * +caja_freedesktop_dbus_new (CajaApplication *application) +{ + CajaFreedesktopDBus *fdb = g_object_new (caja_freedesktop_dbus_get_type (), NULL); + fdb->application = application; + return fdb; +} diff --git a/src/caja-freedesktop-dbus.h b/src/caja-freedesktop-dbus.h new file mode 100644 index 00000000..a3ac1504 --- /dev/null +++ b/src/caja-freedesktop-dbus.h @@ -0,0 +1,42 @@ +/* + * caja-freedesktop-dbus: Implementation for the org.freedesktop DBus file-management interfaces + * + * Caja is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Caja is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Authors: Akshay Gupta <[email protected]> + * Federico Mena Quintero <[email protected]> + * Stefano Karapetsas <[email protected]> + */ + + +#ifndef __CAJA_FREEDESKTOP_DBUS_H__ +#define __CAJA_FREEDESKTOP_DBUS_H__ + +#include <glib-object.h> + +#include "caja-application.h" + +#define CAJA_FDO_DBUS_IFACE "org.freedesktop.FileManager1" +#define CAJA_FDO_DBUS_NAME "org.freedesktop.FileManager1" +#define CAJA_FDO_DBUS_PATH "/org/freedesktop/FileManager1" + +typedef struct _CajaFreedesktopDBus CajaFreedesktopDBus; +typedef struct _CajaFreedesktopDBusClass CajaFreedesktopDBusClass; + +GType caja_freedesktop_dbus_get_type (void); +CajaFreedesktopDBus * caja_freedesktop_dbus_new (CajaApplication *application); + +#endif /* __CAJA_FREEDESKTOP_DBUS_H__ */ |