diff --git a/data/freedesktop-dbus-interfaces.xml b/data/freedesktop-dbus-interfaces.xml index da37ca0e00..d648205cff 100644 --- a/data/freedesktop-dbus-interfaces.xml +++ b/data/freedesktop-dbus-interfaces.xml @@ -31,5 +31,13 @@ + + diff --git a/src/nautilus-application.c b/src/nautilus-application.c index f38340e240..6584bd7026 100644 --- a/src/nautilus-application.c +++ b/src/nautilus-application.c @@ -1400,6 +1400,10 @@ update_dbus_opened_locations (NautilusApplication *self) gchar **locations_array; NautilusWindow *window; GFile *location; + const gchar *dbus_object_path = NULL; + + g_autoptr (GVariant) windows_to_locations; + GVariantBuilder windows_to_locations_builder; g_return_if_fail (NAUTILUS_IS_APPLICATION (self)); @@ -1412,10 +1416,22 @@ update_dbus_opened_locations (NautilusApplication *self) return; } + dbus_object_path = g_application_get_dbus_object_path (G_APPLICATION (self)); + + g_return_if_fail (dbus_object_path); + + g_variant_builder_init (&windows_to_locations_builder, G_VARIANT_TYPE ("a{sas}")); + for (l = priv->windows; l != NULL; l = l->next) { + guint32 id; + g_autofree gchar *path = NULL; + GVariantBuilder locations_in_window_builder; + window = l->data; + g_variant_builder_init (&locations_in_window_builder, G_VARIANT_TYPE ("as")); + for (sl = nautilus_window_get_slots (window); sl; sl = sl->next) { NautilusWindowSlot *slot = sl->data; @@ -1426,6 +1442,8 @@ update_dbus_opened_locations (NautilusApplication *self) gchar *uri = g_file_get_uri (location); GList *found = g_list_find_custom (locations, uri, (GCompareFunc) g_strcmp0); + g_variant_builder_add (&locations_in_window_builder, "s", uri); + if (!found) { locations = g_list_prepend (locations, uri); @@ -1437,6 +1455,11 @@ update_dbus_opened_locations (NautilusApplication *self) } } } + + id = gtk_application_window_get_id (GTK_APPLICATION_WINDOW (window)); + path = g_strdup_printf ("%s/window/%u", dbus_object_path, id); + g_variant_builder_add (&windows_to_locations_builder, "{sas}", path, &locations_in_window_builder); + g_variant_builder_clear (&locations_in_window_builder); } locations_array = g_new (gchar *, locations_size + 1); @@ -1452,6 +1475,10 @@ update_dbus_opened_locations (NautilusApplication *self) nautilus_freedesktop_dbus_set_open_locations (priv->fdb_manager, (const gchar **) locations_array); + windows_to_locations = g_variant_ref_sink (g_variant_builder_end (&windows_to_locations_builder)); + nautilus_freedesktop_dbus_set_open_windows_with_locations (priv->fdb_manager, + windows_to_locations); + g_free (locations_array); g_list_free_full (locations, g_free); } diff --git a/src/nautilus-freedesktop-dbus.c b/src/nautilus-freedesktop-dbus.c index 554b1bc3d5..408532f8d3 100644 --- a/src/nautilus-freedesktop-dbus.c +++ b/src/nautilus-freedesktop-dbus.c @@ -43,6 +43,7 @@ struct _NautilusFreedesktopDBus NautilusFreedesktopFileManager1 *skeleton; GStrv pending_open_locations; + GVariant *pending_open_windows_with_locations; gboolean name_lost; }; @@ -173,6 +174,15 @@ bus_acquired_cb (GDBusConnection *conn, nautilus_freedesktop_dbus_set_open_locations (fdb, (const gchar **) locations); } + + if (G_UNLIKELY (fdb->pending_open_windows_with_locations != NULL)) + { + g_autoptr (GVariant) locations = NULL; + + locations = g_steal_pointer (&fdb->pending_open_windows_with_locations); + + nautilus_freedesktop_dbus_set_open_windows_with_locations (fdb, locations); + } } static void @@ -226,6 +236,7 @@ nautilus_freedesktop_dbus_finalize (GObject *object) fdb = NAUTILUS_FREEDESKTOP_DBUS (object); g_clear_pointer (&fdb->pending_open_locations, g_strfreev); + g_clear_pointer (&fdb->pending_open_windows_with_locations, g_variant_unref); } static void @@ -250,6 +261,7 @@ nautilus_freedesktop_dbus_init (NautilusFreedesktopDBus *fdb) NULL); fdb->skeleton = NULL; fdb->pending_open_locations = NULL; + fdb->pending_open_windows_with_locations = NULL; fdb->name_lost = FALSE; } @@ -276,6 +288,40 @@ nautilus_freedesktop_dbus_set_open_locations (NautilusFreedesktopDBus *fdb, } } +/** + * nautilus_freedesktop_dbus_set_open_windows_with_locations: + * fdb: The skeleton for the dbus interface + * locations: Mapping of windows to locations open in each window + * + * This allows the application to publish the locations that are open in each window. + * It is used by shell extensions like dash-to-dock/ubuntu-dock to match special dock + * icons to the windows where the icon's location is open. For example, the Trash or + * a removable device. + */ +void +nautilus_freedesktop_dbus_set_open_windows_with_locations (NautilusFreedesktopDBus *fdb, + GVariant *locations) +{ + g_return_if_fail (NAUTILUS_IS_FREEDESKTOP_DBUS (fdb)); + + if (G_UNLIKELY (fdb->skeleton == NULL)) + { + if (G_LIKELY (fdb->name_lost)) + { + return; + } + + g_clear_pointer (&fdb->pending_open_windows_with_locations, g_variant_unref); + + fdb->pending_open_windows_with_locations = g_variant_ref (locations); + } + else + { + nautilus_freedesktop_file_manager1_set_open_windows_with_locations (fdb->skeleton, + locations); + } +} + /* Tries to own the org.freedesktop.FileManager1 service name */ NautilusFreedesktopDBus * nautilus_freedesktop_dbus_new (void) diff --git a/src/nautilus-freedesktop-dbus.h b/src/nautilus-freedesktop-dbus.h index 57dfef7189..6c54be6c4a 100644 --- a/src/nautilus-freedesktop-dbus.h +++ b/src/nautilus-freedesktop-dbus.h @@ -45,3 +45,5 @@ GType nautilus_freedesktop_dbus_get_type (void); NautilusFreedesktopDBus * nautilus_freedesktop_dbus_new (void); void nautilus_freedesktop_dbus_set_open_locations (NautilusFreedesktopDBus *fdb, const gchar **locations); + +void nautilus_freedesktop_dbus_set_open_windows_with_locations (NautilusFreedesktopDBus *fdb, GVariant *locations);