Skip to content

swap-<dir>-window keybindings lose to built-in GNOME shortcuts on GNOME 45+ #26

Description

@andrea-reale

On my GNOME Shell (50.3), 4 of the 5 swap-<direction>-window would not work.

With some shallow research it looks like the root cause may be a schema change from GNOME 45+ onwards:

  • toggle-tiled-left/toggle-tiled-right moved from org.gnome.desktop.wm.keybindings to org.gnome.mutter.keybindings.
  • toggle-maximized now exists as a separate action from maximize/unmaximize, so swap-up-window/swap-down-window (<Super>Up/<Super>Down) permanently lose to maximize/unmaximize.

I am attaching a fix that helped me work around this. I am not sure what's the right process to open a PR (or an issue) against the new "live" repository, so I hope these issues are still somehow monitored.

Note that the code is LLM generated, but it looks simple and correct.

Btw, thanks for this great extension!

--- modern.js
+++ extension.js (patched)
@@ -15,6 +15,7 @@
 
 // ── CONST ────────────────────────────────────────────
 const WM_SCHEMA          = 'org.gnome.desktop.wm.keybindings';
+const MUTTER_SCHEMA      = 'org.gnome.mutter.keybindings';
 
 const TILING_DELAY_MS    = 20;   // Change Tiling Window Delay
 const CENTERING_DELAY_MS = 5;    // Change Centered Window Delay
@@ -73,16 +74,17 @@
         this.tiler             = tiler;
         this._settings         = this.tiler.settings;
         this._wmSettings       = new Gio.Settings({ schema: WM_SCHEMA });
+        this._mutterSettings   = new Gio.Settings({ schema: MUTTER_SCHEMA });
         this._wmKeysToDisable  = [];
-        this._savedWmShortcuts = {};
+        this._savedWmShortcuts = [];
     }
 
     enable() {
         this._prepareWmShortcuts();
 
         if (this._wmKeysToDisable.length)
-            this._wmKeysToDisable.forEach(k =>
-                this._wmSettings.set_value(k, new GLib.Variant('as', [])));
+            this._wmKeysToDisable.forEach(({ settings, key }) =>
+                settings.set_value(key, new GLib.Variant('as', [])));
 
         this._bindAllShortcuts();
         this._settings.connectObject(
@@ -100,14 +102,15 @@
 
     disable() {
         if (this._wmKeysToDisable.length)
-            this._wmKeysToDisable.forEach(k =>
-                this._wmSettings.set_value(k, this._savedWmShortcuts[k]));
+            this._wmKeysToDisable.forEach(({ settings, key }, i) =>
+                settings.set_value(key, this._savedWmShortcuts[i]));
 
         this._unbindAllShortcuts();
         this._settings?.disconnectObject(this);
         global.display.disconnectObject(this);
-        this._wmSettings = null;
-        this._settings   = null;
+        this._wmSettings     = null;
+        this._mutterSettings = null;
+        this._settings       = null;
     }
 
     _bind(key, handler) {
@@ -129,30 +132,32 @@
     }
 
     _prepareWmShortcuts() {
-        const schema = this._wmSettings.settings_schema;
-        if (!schema) return;
+        const targets = [];
 
-        const keys = [];
+        const consider = (settings, key) => {
+            const schema = settings.settings_schema;
+            if (schema && schema.has_key(key))
+                targets.push({ settings, key });
+        };
+
+        // Directional tiling: GNOME 45+ moved these to org.gnome.mutter.keybindings;
+        // older GNOME kept 'tile-left'/'tile-right' on org.gnome.desktop.wm.keybindings.
+        consider(this._mutterSettings, 'toggle-tiled-left');
+        consider(this._mutterSettings, 'toggle-tiled-right');
+        consider(this._wmSettings, 'toggle-tiled-left');
+        consider(this._wmSettings, 'toggle-tiled-right');
+        consider(this._wmSettings, 'tile-left');
+        consider(this._wmSettings, 'tile-right');
+
+        // 'toggle-maximized' is a separate action from 'maximize'/'unmaximize' on
+        // current GNOME — all three can hold live bindings at once, so clear
+        // them independently instead of picking just one.
+        consider(this._wmSettings, 'toggle-maximized');
+        consider(this._wmSettings, 'maximize');
+        consider(this._wmSettings, 'unmaximize');
 
-        const add = key => { if (schema.has_key(key)) keys.push(key); };
-
-        if (schema.has_key('toggle-tiled-left'))
-            keys.push('toggle-tiled-left', 'toggle-tiled-right');
-        else {
-            add('tile-left');  add('tile-right');
-        }
-
-        if (schema.has_key('toggle-maximized'))
-            keys.push('toggle-maximized');
-        else {
-            add('maximize');   add('unmaximize');
-        }
-
-        if (keys.length) {
-            this._wmKeysToDisable = keys;
-            keys.forEach(k => this._savedWmShortcuts[k] =
-                             this._wmSettings.get_value(k));
-        }
+        this._wmKeysToDisable  = targets;
+        this._savedWmShortcuts = targets.map(({ settings, key }) => settings.get_value(key));
     }
 
     _focusInDirection(direction) {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions