gnome-shell-extensions/more-ws-previews-0019-window-list-Use-actual-copy-of-workspace-indicator.patch
Florian Müllner e6414d8afc
Re-apply downstream patches
Re-apply rebased and updated version of the RHEL 9 downstream
patches, with some exceptions:

Branding is still TBD, so has been left out for now.

The desktop-icons extension will be replaced by an upstreamed
version of desktop-icons-ng, which is still work-in-progress.

Both dash-to-dock and dash-to-panel will be moved to separate
packages, based on the existing Fedora package.

It was decided to drop the panel-favorites and updates-dialog
extensions.

Resolves: RHEL-34255
2024-05-15 02:56:19 +02:00

590 lines
18 KiB
Diff

From b15212a2d62ff93c1652ef717f778dda3a70f5e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 21 Feb 2024 13:08:52 +0100
Subject: [PATCH 19/28] window-list: Use actual copy of workspace-indicator
We are now at a point where the code from the workspace-indicator
extension is usable from the window-list.
However instead of updating the copy, go one step further and
remove it altogether, and copy the required files at build time.
This ensures that future changes are picked up by both extensions
without duplicating any work.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/307>
---
extensions/window-list/meson.build | 29 +-
extensions/window-list/stylesheet-dark.css | 31 +-
extensions/window-list/stylesheet-light.css | 20 +-
extensions/window-list/workspaceIndicator.js | 435 -------------------
4 files changed, 30 insertions(+), 485 deletions(-)
delete mode 100644 extensions/window-list/workspaceIndicator.js
diff --git a/extensions/window-list/meson.build b/extensions/window-list/meson.build
index 718cdf7a..6fd17007 100644
--- a/extensions/window-list/meson.build
+++ b/extensions/window-list/meson.build
@@ -12,5 +12,32 @@ extension_data += files(
'stylesheet-light.css'
)
-extension_sources += files('prefs.js', 'workspaceIndicator.js')
+transform_stylesheet = [
+ 'sed', '-E',
+ '-e', 's:^\.(workspace-indicator):.window-list-\\1:',
+ '-e', '/^@import/d',
+ '@INPUT@',
+ ]
+
+workspaceIndicatorSources = [
+ configure_file(
+ input: '../workspace-indicator/workspaceIndicator.js',
+ output: '@PLAINNAME@',
+ copy: true,
+ ),
+ configure_file(
+ input: '../workspace-indicator/stylesheet-dark.css',
+ output: 'stylesheet-workspace-switcher-dark.css',
+ command: transform_stylesheet,
+ capture: true,
+ ),
+ configure_file(
+ input: '../workspace-indicator/stylesheet-light.css',
+ output: 'stylesheet-workspace-switcher-light.css',
+ command: transform_stylesheet,
+ capture: true,
+ ),
+]
+
+extension_sources += files('prefs.js') + workspaceIndicatorSources
extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
diff --git a/extensions/window-list/stylesheet-dark.css b/extensions/window-list/stylesheet-dark.css
index fbadf4d0..9e024f2c 100644
--- a/extensions/window-list/stylesheet-dark.css
+++ b/extensions/window-list/stylesheet-dark.css
@@ -4,6 +4,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
+@import url("stylesheet-workspace-switcher-dark.css");
.window-list {
spacing: 2px;
@@ -81,36 +82,6 @@
height: 24px;
}
-.window-list-workspace-indicator .status-label-bin {
- background-color: rgba(200, 200, 200, 0.3);
- padding: 5px;
- margin: 3px;
-}
-
-.window-list-workspace-indicator .workspaces-box {
- spacing: 3px;
- padding: 5px;
-}
-
-.window-list-workspace-indicator .workspace {
- width: 52px;
- border-radius: 4px;
- background-color: #1e1e1e;
-}
-
-.window-list-workspace-indicator .workspace.active {
- background-color: #3f3f3f;
-}
-
-.window-list-workspace-indicator-window-preview {
- background-color: #bebebe;
- border-radius: 1px;
-}
-
-.window-list-workspace-indicator-window-preview.active {
- background-color: #d4d4d4;
-}
-
.notification {
font-weight: normal;
}
diff --git a/extensions/window-list/stylesheet-light.css b/extensions/window-list/stylesheet-light.css
index e9352362..93a96581 100644
--- a/extensions/window-list/stylesheet-light.css
+++ b/extensions/window-list/stylesheet-light.css
@@ -6,6 +6,7 @@
*/
@import url("stylesheet-dark.css");
+@import url("stylesheet-workspace-switcher-light.css");
#panel.bottom-panel {
border-top-width: 1px;
@@ -50,22 +51,3 @@
color: #888;
box-shadow: none;
}
-
-/* workspace switcher */
-.window-list-workspace-indicator .workspace {
- border: 2px solid #f6f5f4;
- background-color: #ccc;
-}
-
-.window-list-workspace-indicator .workspace.active {
- border-color: #888;
-}
-
-.window-list-workspace-indicator-window-preview {
- background-color: #ededed;
- border: 1px solid #ccc;
-}
-
-.window-list-workspace-indicator-window-preview.active {
- background-color: #f6f5f4;
-}
diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js
deleted file mode 100644
index 69167eb6..00000000
--- a/extensions/window-list/workspaceIndicator.js
+++ /dev/null
@@ -1,435 +0,0 @@
-// SPDX-FileCopyrightText: 2019 Florian Müllner <fmuellner@gnome.org>
-//
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-import Clutter from 'gi://Clutter';
-import Gio from 'gi://Gio';
-import GObject from 'gi://GObject';
-import Meta from 'gi://Meta';
-import St from 'gi://St';
-
-import {gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
-
-import * as DND from 'resource:///org/gnome/shell/ui/dnd.js';
-import * as Main from 'resource:///org/gnome/shell/ui/main.js';
-import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
-import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
-
-const TOOLTIP_OFFSET = 6;
-const TOOLTIP_ANIMATION_TIME = 150;
-
-const MAX_THUMBNAILS = 6;
-
-let baseStyleClassName = '';
-
-class WindowPreview extends St.Button {
- static {
- GObject.registerClass(this);
- }
-
- constructor(window) {
- super({
- style_class: `${baseStyleClassName}-window-preview`,
- });
-
- this._delegate = this;
- DND.makeDraggable(this, {restoreOnSuccess: true});
-
- this._window = window;
-
- this._window.connectObject(
- 'size-changed', () => this._checkRelayout(),
- 'position-changed', () => this._checkRelayout(),
- 'notify::minimized', this._updateVisible.bind(this),
- 'notify::window-type', this._updateVisible.bind(this),
- this);
- this._updateVisible();
-
- global.display.connectObject('notify::focus-window',
- this._onFocusChanged.bind(this), this);
- this._onFocusChanged();
- }
-
- // needed for DND
- get metaWindow() {
- return this._window;
- }
-
- _onFocusChanged() {
- if (global.display.focus_window === this._window)
- this.add_style_class_name('active');
- else
- this.remove_style_class_name('active');
- }
-
- _checkRelayout() {
- const monitor = Main.layoutManager.findIndexForActor(this);
- const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
- if (this._window.get_frame_rect().overlap(workArea))
- this.queue_relayout();
- }
-
- _updateVisible() {
- this.visible = this._window.window_type !== Meta.WindowType.DESKTOP &&
- this._window.showing_on_its_workspace();
- }
-}
-
-class WorkspaceLayout extends Clutter.LayoutManager {
- static {
- GObject.registerClass(this);
- }
-
- vfunc_get_preferred_width() {
- return [0, 0];
- }
-
- vfunc_get_preferred_height() {
- return [0, 0];
- }
-
- vfunc_allocate(container, box) {
- const monitor = Main.layoutManager.findIndexForActor(container);
- const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
- const hscale = box.get_width() / workArea.width;
- const vscale = box.get_height() / workArea.height;
-
- for (const child of container) {
- const childBox = new Clutter.ActorBox();
- const frameRect = child.metaWindow.get_frame_rect();
- childBox.set_size(
- Math.round(Math.min(frameRect.width, workArea.width) * hscale),
- Math.round(Math.min(frameRect.height, workArea.height) * vscale));
- childBox.set_origin(
- Math.round((frameRect.x - workArea.x) * hscale),
- Math.round((frameRect.y - workArea.y) * vscale));
- child.allocate(childBox);
- }
- }
-}
-
-class WorkspaceThumbnail extends St.Button {
- static {
- GObject.registerClass(this);
- }
-
- constructor(index) {
- super({
- style_class: 'workspace',
- child: new Clutter.Actor({
- layout_manager: new WorkspaceLayout(),
- clip_to_allocation: true,
- x_expand: true,
- y_expand: true,
- }),
- });
-
- this._tooltip = new St.Label({
- style_class: 'dash-label',
- visible: false,
- });
- Main.uiGroup.add_child(this._tooltip);
-
- this.connect('destroy', this._onDestroy.bind(this));
- this.connect('notify::hover', this._syncTooltip.bind(this));
-
- this._index = index;
- this._delegate = this; // needed for DND
-
- this._windowPreviews = new Map();
-
- let workspaceManager = global.workspace_manager;
- this._workspace = workspaceManager.get_workspace_by_index(index);
-
- this._workspace.connectObject(
- 'window-added', (ws, window) => this._addWindow(window),
- 'window-removed', (ws, window) => this._removeWindow(window),
- this);
-
- global.display.connectObject('restacked',
- this._onRestacked.bind(this), this);
-
- this._workspace.list_windows().forEach(w => this._addWindow(w));
- this._onRestacked();
- }
-
- acceptDrop(source) {
- if (!source.metaWindow)
- return false;
-
- this._moveWindow(source.metaWindow);
- return true;
- }
-
- handleDragOver(source) {
- if (source.metaWindow)
- return DND.DragMotionResult.MOVE_DROP;
- else
- return DND.DragMotionResult.CONTINUE;
- }
-
- _addWindow(window) {
- if (this._windowPreviews.has(window))
- return;
-
- let preview = new WindowPreview(window);
- preview.connect('clicked', (a, btn) => this.emit('clicked', btn));
- this._windowPreviews.set(window, preview);
- this.child.add_child(preview);
- }
-
- _removeWindow(window) {
- let preview = this._windowPreviews.get(window);
- if (!preview)
- return;
-
- this._windowPreviews.delete(window);
- preview.destroy();
- }
-
- _onRestacked() {
- let lastPreview = null;
- let windows = global.get_window_actors().map(a => a.meta_window);
- for (let i = 0; i < windows.length; i++) {
- let preview = this._windowPreviews.get(windows[i]);
- if (!preview)
- continue;
-
- this.child.set_child_above_sibling(preview, lastPreview);
- lastPreview = preview;
- }
- }
-
- _moveWindow(window) {
- let monitorIndex = Main.layoutManager.findIndexForActor(this);
- if (monitorIndex !== window.get_monitor())
- window.move_to_monitor(monitorIndex);
- window.change_workspace_by_index(this._index, false);
- }
-
- on_clicked() {
- let ws = global.workspace_manager.get_workspace_by_index(this._index);
- if (ws)
- ws.activate(global.get_current_time());
- }
-
- _syncTooltip() {
- if (this.hover) {
- this._tooltip.set({
- text: Meta.prefs_get_workspace_name(this._index),
- visible: true,
- opacity: 0,
- });
-
- const [stageX, stageY] = this.get_transformed_position();
- const thumbWidth = this.allocation.get_width();
- const tipWidth = this._tooltip.width;
- const tipHeight = this._tooltip.height;
- const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
- const monitor = Main.layoutManager.findMonitorForActor(this);
- const x = Math.clamp(
- stageX + xOffset,
- monitor.x,
- monitor.x + monitor.width - tipWidth);
- const y = stageY - tipHeight - TOOLTIP_OFFSET;
- this._tooltip.set_position(x, y);
- }
-
- this._tooltip.ease({
- opacity: this.hover ? 255 : 0,
- duration: TOOLTIP_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => (this._tooltip.visible = this.hover),
- });
- }
-
- _onDestroy() {
- this._tooltip.destroy();
- }
-}
-
-export class WorkspaceIndicator extends PanelMenu.Button {
- static {
- GObject.registerClass(this);
- }
-
- constructor(params = {}) {
- super(0.5, _('Workspace Indicator'));
-
- const {
- baseStyleClass = 'workspace-indicator',
- } = params;
-
- baseStyleClassName = baseStyleClass;
- this.add_style_class_name(baseStyleClassName);
-
- let container = new St.Widget({
- layout_manager: new Clutter.BinLayout(),
- x_expand: true,
- y_expand: true,
- });
- this.add_child(container);
-
- let workspaceManager = global.workspace_manager;
-
- this._currentWorkspace = workspaceManager.get_active_workspace_index();
- this._statusLabel = new St.Label({text: this._getStatusText()});
-
- this._statusBin = new St.Bin({
- style_class: 'status-label-bin',
- x_expand: true,
- y_expand: true,
- child: this._statusLabel,
- });
- container.add_child(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_child(this._thumbnailsBox);
-
- this._workspacesItems = [];
-
- workspaceManager.connectObject(
- 'notify::n-workspaces', this._nWorkspacesChanged.bind(this), GObject.ConnectFlags.AFTER,
- 'workspace-switched', this._onWorkspaceSwitched.bind(this), GObject.ConnectFlags.AFTER,
- 'notify::layout-rows', this._updateThumbnailVisibility.bind(this),
- this);
-
- this.connect('scroll-event', this._onScrollEvent.bind(this));
- this._updateMenu();
- this._updateThumbnails();
- this._updateThumbnailVisibility();
-
- this._settings = new Gio.Settings({schema_id: 'org.gnome.desktop.wm.preferences'});
- this._settings.connectObject('changed::workspace-names',
- () => this._updateMenuLabels(), this);
- }
-
- _updateThumbnailVisibility() {
- const {workspaceManager} = global;
- const vertical = workspaceManager.layout_rows === -1;
- const useMenu =
- vertical || workspaceManager.n_workspaces > MAX_THUMBNAILS;
- this.reactive = useMenu;
-
- this._statusBin.visible = useMenu;
- this._thumbnailsBox.visible = !useMenu;
- }
-
- _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();
- this._updateThumbnailVisibility();
- }
-
- _updateMenuOrnament() {
- for (let i = 0; i < this._workspacesItems.length; i++) {
- this._workspacesItems[i].setOrnament(i === this._currentWorkspace
- ? PopupMenu.Ornament.DOT
- : PopupMenu.Ornament.NO_DOT);
- }
- }
-
- _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();
- let total = workspaceManager.n_workspaces;
-
- return '%d / %d'.format(current + 1, total);
- }
-
- _updateMenuLabels() {
- for (let i = 0; i < this._workspacesItems.length; i++) {
- let item = this._workspacesItems[i];
- let name = Meta.prefs_get_workspace_name(i);
- item.label.text = name;
- }
- }
-
- _updateMenu() {
- let workspaceManager = global.workspace_manager;
-
- this.menu.removeAll();
- this._workspacesItems = [];
- this._currentWorkspace = workspaceManager.get_active_workspace_index();
-
- for (let i = 0; i < workspaceManager.n_workspaces; i++) {
- let name = Meta.prefs_get_workspace_name(i);
- let item = new PopupMenu.PopupMenuItem(name);
- item.workspaceId = i;
-
- item.connect('activate', () => {
- this._activate(item.workspaceId);
- });
-
- item.setOrnament(i === this._currentWorkspace
- ? PopupMenu.Ornament.DOT
- : PopupMenu.Ornament.NO_DOT);
-
- this.menu.addMenuItem(item);
- this._workspacesItems[i] = item;
- }
-
- 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_child(thumb);
- }
- this._updateActiveThumbnail();
- }
-
- _activate(index) {
- let workspaceManager = global.workspace_manager;
-
- if (index >= 0 && index < workspaceManager.n_workspaces) {
- let metaWorkspace = workspaceManager.get_workspace_by_index(index);
- metaWorkspace.activate(global.get_current_time());
- }
- }
-
- _onScrollEvent(actor, event) {
- let direction = event.get_scroll_direction();
- let diff = 0;
- if (direction === Clutter.ScrollDirection.DOWN)
- diff = 1;
- else if (direction === Clutter.ScrollDirection.UP)
- diff = -1;
- else
- return;
-
- let newIndex = this._currentWorkspace + diff;
- this._activate(newIndex);
- }
-}
--
2.44.0