Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Cinnamon adds "Show all workspaces" setting to Alt-tab appSwitcher

The story

I recently made a pull request to Cinnamon to add the "Show all workspaces" setting to the window list of the panel. To complement this feature, I decided to add the feature to the alt-tab utility. My journey began with trying to find the alt-tab code in the Cinnamon project. It took me quite a while, but eventually I found it in appSwitcher.js. At first I started tinkering with lines 36-39

function matchWorkspace(win) {
    return win.get_workspace() == this && !win.is_skip_taskbar();
}

But this proved to not be the right spot. Later on I realized this was not the correct spot logically, but putting code here would work. It just wouldn't make sense underneath the title "matchWorkspace." You shouldn't even get to the matchWorkspace function if you're just showing all workspaces anyway. So then I found this section of code

            // Switch between windows of same application from all workspaces
            let focused = global.display.focus_window ? global.display.focus_window : windows[0];
            windows = windows.filter( matchWmClass, focused.get_wm_class() );
            break;
        default:
            // Switch between windows of current workspace
            this._showAllWorkspaces = global.settings.get_boolean("alttab-switcher-show-all-workspaces");
            if (!this._showAllWorkspaces) {
                windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
            }
            break;
    }

And that was what I wanted. The snippet above already includes my adjustment. Line 73 is the logic that reads the gsettings schema. And it took me a while to get this part to work. At first I had the read-schema code up beside the other global.settings.get_boolean at line 112 in the AppSwitcher.prototype._init: function(binding). But it took me a while to figure out the scoping of the variable was not correct for my needs. Reading the gsetting schema in the prototype did not set the variable for the function at line 73, function getWindowsForBinding(binding). I also had to learn about the gsettings schema. I've dabbled with dconf before. But apparently adding a new key is a little more complicated that just

dconf load /org/cinnamon <<EOF
[/]
alttab-switcher-show-all-workspaces true

I learned that for gsettings you have to modify the xml-defined schema. I found it at /usr/share/glib-2.0/schemas/org.cinnamon.gschema.xml. My addition is pretty basic, at lines 541-545.

    <key type="b" name="alttab-switcher-show-all-workspaces">
      <default>false</default>
      <_summary>Show all windows from all workspaces<!--_summary-->
    </key>

I also found file /usr/share/cinnamon/cinnamon- settings/modules/cs_windows.py and added the widget for this setting.

            widget = GSettingsSwitch(_("Show windows from all workspaces"), "org.cinnamon", "alttab-switcher-show-all-workspaces")
            settings.add_row(widget)

So I made my changes and then restarted Cinnamon. Still no go. After a lot of searching, I finally found the important part: I needed to run glib-compile- schemas!

pushd /usr/share/glib-2.0/schemas; glib-compile-schemas .; popd;

Now I finally had success! I submitted pull request #6938 and within a day my changes were approved and merged.

The commit as a patch

diff --git a/data/org.cinnamon.gschema.xml.in b/data/org.cinnamon.gschema.xml.in
index 71e09aca..17fe5dc4 100644
--- a/data/org.cinnamon.gschema.xml.in
+++ b/data/org.cinnamon.gschema.xml.in
@@ -538,6 +538,11 @@
       <_description>Duration of the effect (in milliseconds)<!--_description-->
     </key>

+    <key type="b" name="alttab-switcher-show-all-workspaces">
+      <default>false</default>
+      <_summary>Show all windows from all workspaces<!--_summary-->
+    </key>
+
     <key name="bring-windows-to-current-workspace" type="b">
       <default>false</default>
       <summary>Brings windows requiring attention to the current workspace</summary>
diff --git a/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py b/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py
index 4875346e..080026ab 100755
--- a/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py
+++ b/files/usr/share/cinnamon/cinnamon-settings/modules/cs_windows.py
@@ -129,6 +129,9 @@ class Module:
             widget = GSettingsSpinButton(_("Delay before displaying the alt-tab switcher"), "org.cinnamon", "alttab-switcher-delay", units=_("milliseconds"), mini=0, maxi=1000, step=50, page=150)
             settings.add_row(widget)

+            widget = GSettingsSwitch(_("Show windows from all workspaces"), "org.cinnamon", "alttab-switcher-show-all-workspaces")
+            settings.add_row(widget)
+
 class TitleBarButtonsOrderSelector(SettingsBox):
     def __init__(self):
         self.schema = "org.cinnamon.muffin"
diff --git a/js/ui/appSwitcher/appSwitcher.js b/js/ui/appSwitcher/appSwitcher.js
index f161350c..d36d3bf2 100644
--- a/js/ui/appSwitcher/appSwitcher.js
+++ b/js/ui/appSwitcher/appSwitcher.js
@@ -70,7 +70,10 @@ function getWindowsForBinding(binding) {
             break;
         default:
             // Switch between windows of current workspace
-            windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
+            this._showAllWorkspaces = global.settings.get_boolean("alttab-switcher-show-all-workspaces");
+            if (!this._showAllWorkspaces) {
+                windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
+            }
             break;
     }

References

Weblinks

  1. Need to use glib-compile-schemas https://developer.gnome.org/gio/stable/GSettings.html
  2. https://developer.gnome.org/GSettings/

Comments