auto-move-windows: Optionally restrict to startup
Resolves: https://redhat.atlassian.net/browse/RHEL-80282
This commit is contained in:
parent
f804b081bc
commit
ba5d99f3a9
194
0001-auto-move-windows-Optionally-restrict-to-startup.patch
Normal file
194
0001-auto-move-windows-Optionally-restrict-to-startup.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 9272f1ecf3750d1385ea627ebda41edfce3b37eb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Wed, 27 May 2026 19:35:04 +0200
|
||||
Subject: [PATCH] auto-move-windows: Optionally restrict to startup
|
||||
|
||||
It is not uncommon to use a combination of autostart and auto-move-windows
|
||||
to work around missing session saving/restore support. In that case, only
|
||||
autostarted windows should be moved to their configured workspace, while
|
||||
windows that are opened later should behave normally.
|
||||
|
||||
While we cannot detect that a window is autostarted, we can approximate
|
||||
the behavior by only enabling moves for 20 seconds during startup.
|
||||
|
||||
In theory we can improve accuracy further by only moving windows without
|
||||
a startup ID (as gnome-session uses a plain GDesktopAppLaunchContext),
|
||||
but in practice its usefulness is limited given that the activation token
|
||||
of wayland windows is applied too late and not exposed to introspection.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/work_items/322
|
||||
---
|
||||
extensions/auto-move-windows/extension.js | 54 +++++++++++++++++--
|
||||
...l.extensions.auto-move-windows.gschema.xml | 4 ++
|
||||
extensions/auto-move-windows/prefs.js | 43 ++++++++++++++-
|
||||
3 files changed, 97 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js
|
||||
index 34decce7..67381e48 100644
|
||||
--- a/extensions/auto-move-windows/extension.js
|
||||
+++ b/extensions/auto-move-windows/extension.js
|
||||
@@ -4,11 +4,15 @@
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
+import GLib from 'gi://GLib';
|
||||
import Shell from 'gi://Shell';
|
||||
|
||||
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
|
||||
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
|
||||
|
||||
+// time during which windows are moved on startup if startup-only is true
|
||||
+const SESSION_AUTOSTART_TIMEOUT_MS = 20 * 1000;
|
||||
+
|
||||
class WindowMover {
|
||||
constructor(settings) {
|
||||
this._settings = settings;
|
||||
@@ -19,16 +23,50 @@ class WindowMover {
|
||||
this._appSystem.connectObject('installed-changed',
|
||||
() => this._updateAppData(), this);
|
||||
|
||||
- this._settings.connectObject('changed',
|
||||
+ this._settings.connectObject('changed::application-list',
|
||||
this._updateAppConfigs.bind(this), this);
|
||||
+ this._settings.connectObject('changed::startup-only',
|
||||
+ () => this._updateStartupOnly());
|
||||
+ this._updateStartupOnly();
|
||||
+ }
|
||||
+
|
||||
+ _updateStartupOnly() {
|
||||
+ const startupOnly = this._settings.get_boolean('startup-only');
|
||||
+ if (this._startupOnly === startupOnly)
|
||||
+ return;
|
||||
+
|
||||
+ this._startupOnly = startupOnly;
|
||||
+
|
||||
+ if (startupOnly) {
|
||||
+ this._movesEnabled = Main.layoutManager._startingUp;
|
||||
+
|
||||
+ if (this._movesEnabled) {
|
||||
+ this._startupTimeoutId = GLib.timeout_add(
|
||||
+ GLib.PRIORITY_DEFAULT,
|
||||
+ SESSION_AUTOSTART_TIMEOUT_MS,
|
||||
+ () => {
|
||||
+ this._movesEnabled = false;
|
||||
+ this._updateAppConfigs();
|
||||
+
|
||||
+ delete this._startupTimeoutId;
|
||||
+ return GLib.SOURCE_REMOVE;
|
||||
+ });
|
||||
+ }
|
||||
+ } else {
|
||||
+ this._movesEnabled = true;
|
||||
+ }
|
||||
+
|
||||
this._updateAppConfigs();
|
||||
}
|
||||
|
||||
_updateAppConfigs() {
|
||||
this._appConfigs.clear();
|
||||
|
||||
- this._settings.get_strv('application-list').forEach(v => {
|
||||
- let [appId, num] = v.split(':');
|
||||
+ const appList = this._movesEnabled
|
||||
+ ? this._settings.get_strv('application-list')
|
||||
+ : [];
|
||||
+ appList.forEach(v => {
|
||||
+ const [appId, num] = v.split(':');
|
||||
this._appConfigs.set(appId, parseInt(num) - 1);
|
||||
});
|
||||
|
||||
@@ -61,6 +99,10 @@ class WindowMover {
|
||||
|
||||
this._appConfigs.clear();
|
||||
this._updateAppData();
|
||||
+
|
||||
+ if (this._startupTimeoutId)
|
||||
+ GLib.source_remove(this._startupTimeoutId);
|
||||
+ delete this._startupTimeoutId;
|
||||
}
|
||||
|
||||
_moveWindow(window, workspaceNum) {
|
||||
@@ -89,6 +131,12 @@ class WindowMover {
|
||||
return !windows.includes(w) && w.get_compositor_private() !== null;
|
||||
}));
|
||||
|
||||
+ // In startup-only mode, we only want to move auto-started apps;
|
||||
+ // we can't filter for that, but at least we know that windows with
|
||||
+ // a startup ID were launched by the user
|
||||
+ if (this._startupOnly)
|
||||
+ windows = windows.filter(w => w.get_startup_id() === null);
|
||||
+
|
||||
let workspaceNum = this._appConfigs.get(app.id);
|
||||
windows.filter(w => !data.windows.includes(w)).forEach(window => {
|
||||
this._moveWindow(window, workspaceNum);
|
||||
diff --git a/extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml b/extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml
|
||||
index 563f7ee6..a7d5ebb5 100644
|
||||
--- a/extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml
|
||||
+++ b/extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml
|
||||
@@ -12,5 +12,9 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
<summary>Application and workspace list</summary>
|
||||
<description>A list of strings, each containing an application id (desktop file name), followed by a colon and the workspace number</description>
|
||||
</key>
|
||||
+ <key name="startup-only" type="b">
|
||||
+ <default>false</default>
|
||||
+ <summary>Only move windows during startup</summary>
|
||||
+ </key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
diff --git a/extensions/auto-move-windows/prefs.js b/extensions/auto-move-windows/prefs.js
|
||||
index 98e424e0..4e1fa6c5 100644
|
||||
--- a/extensions/auto-move-windows/prefs.js
|
||||
+++ b/extensions/auto-move-windows/prefs.js
|
||||
@@ -140,7 +140,48 @@ class RulesList extends GObject.Object {
|
||||
}
|
||||
}
|
||||
|
||||
-class AutoMoveSettingsWidget extends Adw.PreferencesGroup {
|
||||
+class AutoMoveSettingsWidget extends Adw.PreferencesPage {
|
||||
+ static {
|
||||
+ GObject.registerClass(this);
|
||||
+ }
|
||||
+
|
||||
+ constructor(settings) {
|
||||
+ super();
|
||||
+
|
||||
+ this._settings = settings;
|
||||
+
|
||||
+ const rulesGroup = new WorkspaceRulesGroup(settings);
|
||||
+ this.add(rulesGroup);
|
||||
+
|
||||
+ const optionsGroup = new OptionsGroup(settings);
|
||||
+ this.add(optionsGroup);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+class OptionsGroup extends Adw.PreferencesGroup {
|
||||
+ static {
|
||||
+ GObject.registerClass(this);
|
||||
+ }
|
||||
+
|
||||
+ constructor(settings) {
|
||||
+ super();
|
||||
+
|
||||
+ this._settings = settings;
|
||||
+
|
||||
+ const actionGroup = new Gio.SimpleActionGroup();
|
||||
+ actionGroup.add_action(settings.create_action('startup-only'));
|
||||
+ this.insert_action_group('options', actionGroup);
|
||||
+
|
||||
+ const row = new Adw.SwitchRow({
|
||||
+ title: _('Startup Only'),
|
||||
+ subtitle: _('Only apply rules while the session is starting'),
|
||||
+ action_name: 'options.startup-only',
|
||||
+ });
|
||||
+ this.add(row);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+class WorkspaceRulesGroup extends Adw.PreferencesGroup {
|
||||
static {
|
||||
GObject.registerClass(this);
|
||||
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -40,6 +40,8 @@ Patch: heads-up-display-from-file.patch
|
||||
|
||||
Patch: scrollable-workspace-menu.patch
|
||||
|
||||
Patch: 0001-auto-move-windows-Optionally-restrict-to-startup.patch
|
||||
|
||||
%description
|
||||
GNOME Shell Extensions is a collection of extensions providing additional and
|
||||
optional functionality to GNOME Shell.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user