gnome-shell-extensions/scrollable-workspace-menu.patch
Florian Müllner 8d7157841c
Fix scrollable workspace menu
Children that are scrolled out of view are still visible
to picks. Luckily we can address that without backporting
major pick changes in Clutter/St by clipping the scroll view
to its allocation.

Resolves: https://redhat.atlassian.net/browse/RHEL-171972
2026-06-04 19:37:10 +02:00

149 lines
5.9 KiB
Diff

From dd975bd50c5e9232bf4e1aa17927e085a37cf114 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 3 Mar 2026 12:48:13 +0100
Subject: [PATCH 1/3] workspace-indicator: Use section box to iterate items
Menu items are added to a menu's box, so it is more correct to
use that to access items, even when for menu sections the box
is also used as the menu's actor.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/445>
---
extensions/workspace-indicator/workspaceIndicator.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js
index eb31fc62..af4c69bf 100644
--- a/extensions/workspace-indicator/workspaceIndicator.js
+++ b/extensions/workspace-indicator/workspaceIndicator.js
@@ -595,7 +595,7 @@ class WorkspacesMenu extends PopupMenu.PopupMenu {
const {workspaceManager} = global;
const {nWorkspaces} = workspaceManager;
- const section = this._workspacesSection.actor;
+ const section = this._workspacesSection.box;
while (section.get_n_children() < nWorkspaces) {
const item = new EditableMenuItem();
item.connect('activate', (o, event) => {
@@ -624,7 +624,7 @@ class WorkspacesMenu extends PopupMenu.PopupMenu {
_updateWorkspaceLabels() {
const items =
- this._workspacesSection.actor.get_children().map(c => c._delegate);
+ this._workspacesSection.box.get_children().map(c => c._delegate);
items.forEach(
(item, i) => (item.label.text = Meta.prefs_get_workspace_name(i)));
}
@@ -634,7 +634,7 @@ class WorkspacesMenu extends PopupMenu.PopupMenu {
const active = workspaceManager.get_active_workspace_index();
const items =
- this._workspacesSection.actor.get_children().map(c => c._delegate);
+ this._workspacesSection.box.get_children().map(c => c._delegate);
items.forEach((item, i) => {
item.setOrnament(i === active
? PopupMenu.Ornament.CHECK
--
2.54.0
From 85a1cb3d7e009925cfa17ba4b3dee85296bf2c43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 2 Mar 2026 18:49:16 +0100
Subject: [PATCH 2/3] workspace-indicator: Support scrolling in workspace menu
While we should always have enough screen estate to fit a reasonable
number of workspaces, the number can go up to 36 where we are pretty
much guaranteed to run out of space.
Support those less common cases by making the workspace list scrollable.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/445>
---
.../workspace-indicator/workspaceIndicator.js | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js
index af4c69bf..efa9d8f3 100644
--- a/extensions/workspace-indicator/workspaceIndicator.js
+++ b/extensions/workspace-indicator/workspaceIndicator.js
@@ -6,6 +6,7 @@ const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Tweener = imports.ui.tweener;
+const { ensureActorVisibleInScrollView } = imports.misc.util;
const Signals = imports.signals;
@@ -548,6 +549,17 @@ class WorkspacesMenu extends PopupMenu.PopupMenu {
this.actor.connect('destroy', () => this._onDestroy());
this._workspacesSection = new PopupMenu.PopupMenuSection();
+
+ // make the section scrollable to avoid growing indefinitely
+ const scrollView = new St.ScrollView({
+ style_class: 'vfade',
+ hscrollbar_policy: St.PolicyType.NEVER,
+ clip_to_allocation: true,
+ });
+ scrollView.add_actor(this._workspacesSection.box);
+ scrollView._delegate = this._workspacesSection;
+ this._workspacesSection.actor = scrollView;
+
this.addMenuItem(this._workspacesSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -612,6 +624,11 @@ class WorkspacesMenu extends PopupMenu.PopupMenu {
this._desktopSettings.set_strv('workspace-names',
[...newNames, ...oldNames.slice(nLabels)]);
});
+ item.connect('active-changed', (i, active) => {
+ const view = this._workspacesSection.actor;
+ if (active)
+ ensureActorVisibleInScrollView(view, item.actor);
+ });
this._workspacesSection.addMenuItem(item);
}
--
2.54.0
From 0aee323d5e42a8c4e70b3a32700ee8d9f7ff15b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 18 Mar 2026 14:04:34 +0100
Subject: [PATCH 3/3] window-list: Fix flipping menu arrow
The `updateArrowSide()` method changes the effective arrow side,
but not the "user arrow side" that tracks the explicitly requested
side.
This breaks scrolling the workspaces menu, because when checking
whether the menu needs flipping due to size constraints, it does
not fit on either side and boxpointer reverts to the originally
requested side.
This is a shell issue[0], but we can work around it to fix the
immediate issue without a shell update.
[0] https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4120
---
extensions/window-list/extension.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 37b5ea09..d1342898 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -1243,6 +1243,7 @@ class BottomWorkspaceIndicator extends WorkspaceIndicator {
return;
this.menu.actor.updateArrowSide(St.Side.BOTTOM);
+ this.menu.actor._userArrowSide = St.Side.BOTTOM;
this.menu.actor.remove_style_class_name('panel-menu');
}
});
--
2.54.0