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);