Skip to content

Commit

Permalink
nautilus-application: Publish window->location mappings
Browse files Browse the repository at this point in the history
This is a reworking of a long standing Ubuntu patch that publishes
the set of locations open in each Nautilus window. The motivation
for this change is that a desktop environment providing special
icons for things like removable devices and the trash can match
windows to those icons for highlighting purposes.

In the original incarnation, Unity provided these icons. In today's
world, I'm maintaining a set of patches for dash-to-dock/ubunut-dock
that provide these icons too.

The original implementation uses Xids to identify windows, but Xids
aren't a thing in Wayland so this mechanism is a dead end. Instead,
we can use the 'gtk application window object paths' which are
published over dbus by GtkApplications, including Nautilus.

Mutter already detects these, and makes them available on MetaWindows.

The original patch added the mapping property to the fileManager1
interface, and I have left that part as-is, but it's likely not to
be the right place to put it. fileManager1 is a generic interface
and a property that assumes a GTK behaviour doesn't seem right.

We could obviously add it to a new interface under org.gnome.Nautilus,
but this would be Nautilus specific - although there isn't a huge
scope for other file managers to implement this property, so perhaps
that's just fine.

dash-to-dock discussion is readable here:

micheleg/dash-to-dock#677
  • Loading branch information
philipl authored and csoriano1618 committed May 18, 2018
1 parent 93fb795 commit 5bb6082
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
8 changes: 8 additions & 0 deletions data/freedesktop-dbus-interfaces.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,13 @@
<arg type='s' name='StartupId' direction='in'/>
</method>
<property name="OpenLocations" type="as" access="read"/>
<!--
An extension to the official FileManager1 interface that allows Nautilus
to publish a mapping of windows to the locations in each window.
This can be used by shell extensions like dash-to-dock/ubuntu-dock to
associate special dock icons with windows where the icon's location is
open.
-->
<property name="OpenWindowsWithLocations" type="a{sas}" access="read"/>
</interface>
</node>
27 changes: 27 additions & 0 deletions src/nautilus-application.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down
46 changes: 46 additions & 0 deletions src/nautilus-freedesktop-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct _NautilusFreedesktopDBus
NautilusFreedesktopFileManager1 *skeleton;

GStrv pending_open_locations;
GVariant *pending_open_windows_with_locations;

gboolean name_lost;
};
Expand Down Expand Up @@ -172,6 +173,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
Expand Down Expand Up @@ -225,6 +235,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
Expand All @@ -249,6 +260,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;
}

Expand All @@ -275,6 +287,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)
Expand Down
2 changes: 2 additions & 0 deletions src/nautilus-freedesktop-dbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit 5bb6082

Please sign in to comment.