From c9477dd94d8eb416525e3243d91e9cfd8b6dd26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 02:53:38 +0000 Subject: [PATCH] window-list: Support horizontal workspace layout Unlike in GNOME 2, the workspace indicator we display in the window list isn't a workspace switcher, but a menu button that allows switching workspaces via its menu. The reason for that is that a horizontal in-place switcher would be at odds with the vertical workspace layout used in GNOME 3. However that reasoning doesn't apply when the layout is changed to a horizontal one, so replace the button with a traditional workspace switcher in that case. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/classic.css | 9 +++ extensions/window-list/stylesheet.css | 29 +++++++++ extensions/window-list/workspaceIndicator.js | 65 +++++++++++++++++++- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css index cc967e07..c533473e 100644 --- a/extensions/window-list/classic.css +++ b/extensions/window-list/classic.css @@ -47,3 +47,12 @@ color: #888; box-shadow: none; } + +/* workspace switcher */ +.window-list-workspace-indicator .workspace { + background-color: #ddd; +} + +.window-list-workspace-indicator .workspace.active { + background-color: #ccc; +} diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css index bab8f763..ad5978a0 100644 --- a/extensions/window-list/stylesheet.css +++ b/extensions/window-list/stylesheet.css @@ -92,6 +92,35 @@ margin: 3px 0; } +.window-list-workspace-indicator .workspaces-box { + spacing: 3px; + padding: 3px; +} + +.window-list-workspace-indicator .workspace { + border: 1px solid #cccccc; + width: 52px; +} + +.window-list-workspace-indicator .workspace:first-child:last-child:ltr, +.window-list-workspace-indicator .workspace:first-child:last-child:rtl { + border-radius: 4px; +} + +.window-list-workspace-indicator .workspace:first-child:ltr, +.window-list-workspace-indicator .workspace:last-child:rtl { + border-radius: 4px 0 0 4px; +} + +.window-list-workspace-indicator .workspace:first-child:rtl, +.window-list-workspace-indicator .workspace:last-child:ltr { + border-radius: 0 4px 4px 0; +} + +.window-list-workspace-indicator .workspace.active { + background-color: rgba(200, 200, 200, .3); +} + .notification { font-weight: normal; } diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 78ca97e9..9896a60a 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -7,6 +7,24 @@ const PopupMenu = imports.ui.popupMenu; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; +let WorkspaceThumbnail = GObject.registerClass({ + GTypeName: 'WindowListWorkspaceThumbnail' +}, class WorkspaceThumbnail extends St.Button { + _init(index) { + super._init({ + style_class: 'workspace' + }); + + this._index = index; + } + + on_clicked() { + let ws = global.workspace_manager.get_workspace_by_index(this._index); + if (ws) + ws.activate(global.get_current_time()); + } +}); + var WorkspaceIndicator = GObject.registerClass({ GTypeName: 'WindowListWorkspaceIndicator' }, class WorkspaceIndicator extends PanelMenu.Button { @@ -36,17 +54,30 @@ var WorkspaceIndicator = GObject.registerClass({ }); container.add_actor(this._statusBin); + this._thumbnailsBox = new St.BoxLayout({ + style_class: 'workspaces-box', + y_expand: true, + reactive: true + }); + this._thumbnailsBox.connect('scroll-event', + this._onScrollEvent.bind(this)); + container.add_actor(this._thumbnailsBox); + this._workspacesItems = []; this._workspaceManagerSignals = [ workspaceManager.connect('notify::n-workspaces', this._nWorkspacesChanged.bind(this)), workspaceManager.connect_after('workspace-switched', - this._onWorkspaceSwitched.bind(this)) + this._onWorkspaceSwitched.bind(this)), + workspaceManager.connect('notify::layout-rows', + this._onWorkspaceOrientationChanged.bind(this)) ]; this.connect('scroll-event', this._onScrollEvent.bind(this)); this._updateMenu(); + this._updateThumbnails(); + this._onWorkspaceOrientationChanged(); this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' }); this._settingsChangedId = this._settings.connect( @@ -65,17 +96,27 @@ var WorkspaceIndicator = GObject.registerClass({ super._onDestroy(); } + _onWorkspaceOrientationChanged() { + let vertical = global.workspace_manager.layout_rows == -1; + this.reactive = vertical; + + this._statusBin.visible = vertical; + this._thumbnailsBox.visible = !vertical; + } + _onWorkspaceSwitched() { let workspaceManager = global.workspace_manager; this._currentWorkspace = workspaceManager.get_active_workspace_index(); this._updateMenuOrnament(); + this._updateActiveThumbnail(); this._statusLabel.set_text(this._getStatusText()); } _nWorkspacesChanged() { this._updateMenu(); + this._updateThumbnails(); } _updateMenuOrnament() { @@ -86,6 +127,16 @@ var WorkspaceIndicator = GObject.registerClass({ } } + _updateActiveThumbnail() { + let thumbs = this._thumbnailsBox.get_children(); + for (let i = 0; i < thumbs.length; i++) { + if (i == this._currentWorkspace) + thumbs[i].add_style_class_name('active'); + else + thumbs[i].remove_style_class_name('active'); + } + } + _getStatusText() { let workspaceManager = global.workspace_manager; let current = workspaceManager.get_active_workspace_index(); @@ -128,6 +179,18 @@ var WorkspaceIndicator = GObject.registerClass({ this._statusLabel.set_text(this._getStatusText()); } + _updateThumbnails() { + let workspaceManager = global.workspace_manager; + + this._thumbnailsBox.destroy_all_children(); + + for (let i = 0; i < workspaceManager.n_workspaces; i++) { + let thumb = new WorkspaceThumbnail(i); + this._thumbnailsBox.add_actor(thumb); + } + this._updateActiveThumbnail(); + } + _activate(index) { let workspaceManager = global.workspace_manager;