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) {

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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