[gnome-shell-extensions/wip/fmuellner/fix-auto-move] auto-move-windows: Track apps' windows instead of window creation
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell-extensions/wip/fmuellner/fix-auto-move] auto-move-windows: Track apps' windows instead of window creation
- Date: Tue, 16 Jan 2018 19:35:06 +0000 (UTC)
commit ada43caadb17204e22faef54a3258efba70264c6
Author: Florian Müllner <fmuellner gnome org>
Date: Thu Dec 21 21:01:53 2017 +0100
auto-move-windows: Track apps' windows instead of window creation
We currently track window creation to decide whether the new window
should be moved or not. In order for this to work, the window must
already have been matched to the correct application, which is only
the case when the properties used for app matching were supplied
during window creation.
This is usually the case on X11, but never on wayland. To avoid this
issue altogether, stop listening for raw window creations, and instead
track when a window is added to an application we are interested in.
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/33
extensions/auto-move-windows/extension.js | 92 +++++++++++++++++++++----------
1 file changed, 62 insertions(+), 30 deletions(-)
---
diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js
index e193b25..63d32ff 100644
--- a/extensions/auto-move-windows/extension.js
+++ b/extensions/auto-move-windows/extension.js
@@ -1,7 +1,7 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
// Start apps on custom workspaces
-const Glib = imports.gi.GLib;
+const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@@ -17,12 +17,13 @@ const Convenience = Me.imports.convenience;
class WindowMover {
constructor() {
this._settings = Convenience.getSettings();
- this._windowTracker = Shell.WindowTracker.get_default();
+ this._appSystem = Shell.AppSystem.get_default();
this._appConfigs = new Map();
+ this._appData = new Map();
- let display = global.screen.get_display();
- // Connect after so the handler from ShellWindowTracker has already run
- this._windowCreatedId = display.connect_after('window-created', this._findAndMove.bind(this));
+ this._appsChangedId =
+ this._appSystem.connect('installed-changed',
+ this._updateAppData.bind(this));
this._settings.connect('changed', this._updateAppConfigs.bind(this));
this._updateAppConfigs();
@@ -35,50 +36,81 @@ class WindowMover {
let [appId, num] = v.split(':');
this._appConfigs.set(appId, parseInt(num) - 1);
});
+
+ this._updateAppData();
+ }
+
+ _updateAppData() {
+ let ids = [...this._appConfigs.keys()];
+ let removedApps = [...this._appData.keys()].filter(
+ a => !ids.includes(a.id)
+ );
+ removedApps.forEach(app => {
+ app.disconnect(this._appData.get(app).windowsChangedId);
+ this._appData.delete(app);
+ });
+
+ let addedApps = ids.map(id => this._appSystem.lookup_app(id)).filter(
+ app => app != null && !this._appData.has(app)
+ );
+ addedApps.forEach(app => {
+ let data = {
+ windowsChangedId: app.connect('windows-changed',
+ this._appWindowsChanged.bind(this)),
+ moveWindowsId: 0,
+ windows: app.get_windows()
+ }
+ this._appData.set(app, data);
+ });
}
destroy() {
- if (this._windowCreatedId) {
- global.screen.get_display().disconnect(this._windowCreatedId);
- this._windowCreatedId = 0;
+ if (this._appsChangedId) {
+ this._appSystem.disconnect(this._appsChangedId);
+ this._appsChangedId = 0;
}
if (this._settings) {
this._settings.run_dispose();
this._settings = null;
}
+
+ this._appConfigs.clear();
+ this._updateAppData();
}
- _ensureAtLeastWorkspaces(num, window) {
- for (let i = global.screen.n_workspaces; i <= num; i++) {
+ _moveWindow(window, workspaceNum) {
+ if (window.skip_taskbar)
+ return;
+
+ // ensure we have the required number of workspaces
+ for (let i = global.screen.n_workspaces; i <= workspaceNum; i++) {
window.change_workspace_by_index(i - 1, false);
global.screen.append_new_workspace(false, 0);
}
+
+ window.change_workspace_by_index(workspaceNum, false);
}
- _findAndMove(display, window, noRecurse) {
- if (window.skip_taskbar)
+ _appWindowsChanged(app) {
+ let data = this._appData.get(app);
+ if (data.moveWindowsId)
return;
- let app = this._windowTracker.get_window_app(window);
- if (!app) {
- if (!noRecurse) {
- // window is not tracked yet
- Mainloop.idle_add(() => {
- this._findAndMove(display, window, true);
- return false;
- });
- } else
- log ('Cannot find application for window');
- return;
- }
- let workspaceNum = this._appConfigs.get(app.get_id());
- if (workspaceNum !== undefined) {
- if (workspaceNum >= global.screen.n_workspaces)
- this._ensureAtLeastWorkspaces(workspaceNum, window);
+ // Defer to an idle, to guard against windows being removed and
+ // re-added immediately (for example when moving between workspaces)
+ data.moveWindowsId = Mainloop.idle_add(() => {
+ data.moveWindowsId = 0;
- window.change_workspace_by_index(workspaceNum, false);
- }
+ let windows = app.get_windows();
+ let workspaceNum = this._appConfigs.get(app.id);
+ windows.filter(w => !data.windows.includes(w)).forEach(window => {
+ this._moveWindow(window, workspaceNum);
+ });
+ data.windows = windows;
+
+ return GLib.SOURCE_REMOVE;
+ });
}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]