Skip to content

Commit

Permalink
fileManager1API: Add support for proposed new location mapping mechanism
Browse files Browse the repository at this point in the history
The original xid based window mapping that was implemented for Unity
cannot be used Wayland because there are no xids and Wayland has no
equivalent window id mechanism.

However, GtkApplications do publish window identiy information over
dbus, and these 'window object paths' are tracked and made available
by mutter.

Fortunately for us, Nautilus is a GtkApplication and has identified
windows.

So, if we update the Nautilus patch to use window object paths
instead of xids, we can maintain a mapping that works under Wayland
too.

This change implements path based tracking alongside xid based
tracking, but it's likely we'd drop xid tracking when merging this
set of changes.
  • Loading branch information
philipl committed May 16, 2018
1 parent 26cacaf commit 1f0f425
Showing 1 changed file with 63 additions and 4 deletions.
67 changes: 63 additions & 4 deletions fileManager1API.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ const Utils = Me.imports.utils;

const FileManager1Iface = '<node><interface name="org.freedesktop.FileManager1">\
<property name="XUbuntuOpenLocationsXids" type="a{uas}" access="read"/>\
<property name="OpenWindowsWithLocations" type="a{sas}" access="read"/>\
</interface></node>';

const FileManager1Proxy = Gio.DBusProxy.makeProxyWrapper(FileManager1Iface);

/**
* This class implements a client for the org.freedesktop.FileManager1 dbus
* interface, and specifically for the XUbuntuOpenLocationsXids property that
* is not an official part of the interface. On Ubuntu, Nautilus has been
* interface, and specifically for the OpenWindowsWithLocations property
* that is not an official part of the interface. On Ubuntu, Nautilus has been
* patched to offer this additional property, and it maps file locations to
* Window XIDs, as the name suggests.
* gtk application window object paths.
*
* When an unpatched Nautilus is running, we will never observe the property
* to contain anything interesting, but there will not be any correctness
Expand Down Expand Up @@ -86,12 +87,52 @@ var FileManager1Client = new Lang.Class({

_onPropertyChanged: function(proxy, changed, invalidated) {
let property = changed.unpack();
if (property && 'XUbuntuOpenLocationsXids' in property) {
if (property &&
('XUbuntuOpenLocationsXids' in property ||
'OpenWindowsWithLocations' in property)) {
this._updateLocationMap();
}
},

_updateLocationMap: function() {
let properties = this._proxy.get_cached_property_names();
if (properties == null) {
// Nothing to check yet.
return;
}

if (properties.includes('OpenWindowsWithLocations')) {
this._updateFromPaths();
} else if (properties.includes('XUbuntuOpenLocationsXids')) {
this._updateFromXids();
}
},

_updateFromPaths: function() {
let pathToLocations = this._proxy.OpenWindowsWithLocations;
let pathToWindow = getPathToWindow();

let locationToWindow = new Map();
for (let path in pathToLocations) {
let locations = pathToLocations[path];
for (let i = 0; i < locations.length; i++) {
let l = locations[i];
// Use a set to deduplicate when a window has a
// location open in multiple tabs.
if (!locationToWindow.has(l)) {
locationToWindow.set(l, new Set());
}
let window = pathToWindow.get(path);
if (window != null) {
locationToWindow.get(l).add(window);
}
}
}
this._locationMap = locationToWindow;
this.emit('windows-changed');
},

_updateFromXids: function() {
let xidToLocations = this._proxy.XUbuntuOpenLocationsXids;
let xidToWindow = getXidToWindow();

Expand All @@ -117,6 +158,24 @@ var FileManager1Client = new Lang.Class({
});
Signals.addSignalMethods(FileManager1Client.prototype);

/**
* Construct a map of gtk application window object paths to MetaWindows.
*/
function getPathToWindow() {
let pathToWindow = new Map();

for (let i = 0; i < global.screen.n_workspaces; i++) {
let ws = global.screen.get_workspace_by_index(i);
ws.list_windows().map(function(w) {
let path = w.get_gtk_window_object_path();
if (path != null) {
pathToWindow.set(path, w);
}
});
}
return pathToWindow;
}

/**
* Construct a map of XIDs to MetaWindows.
*
Expand Down

0 comments on commit 1f0f425

Please sign in to comment.