diff --git a/fileManager1API.js b/fileManager1API.js index 4adc8c19b..3356d170e 100644 --- a/fileManager1API.js +++ b/fileManager1API.js @@ -9,16 +9,17 @@ const Utils = Me.imports.utils; const FileManager1Iface = '\ \ + \ '; 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 @@ -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(); @@ -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. *