From d94a3500f64049b019f224bb54e1dedf642afd01 Mon Sep 17 00:00:00 2001 From: "Fabian P. Schmidt" Date: Tue, 19 Mar 2019 22:24:44 +0100 Subject: [PATCH 01/78] README: Re-add extension alternate-tab with obsolescence notice This commit adds a short notice about the former extension alternate-tab to the README. This notice should be removed once the traffic of users searching for this obsolete extension settled down. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/62 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 1587a97d..3b84cb18 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,12 @@ Bugs should be reported to the GNOME [bug tracking system][bug-tracker]. ## Extensions + * alternate-tab (**OBSOLETE**) + + Lets you use classic Alt+Tab (window-based instead of app-based) in GNOME Shell. + This extension is obsolete since GNOME 3.30, see [this blogpost][alternatetab-post] + for further details. + * apps-menu Lets you reach an application using gnome 2.x style menu on the panel. @@ -74,3 +80,4 @@ file for details. [shell-page]: https://wiki.gnome.org/Projects/GnomeShell [bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues [license]: COPYING +[alternatetab-post]: https://blogs.gnome.org/fmuellner/2018/10/11/the-future-of-alternatetab-and-why-you-need-not-worry/ From a024d9f0053f7af34b9b0c5c085d6fd939bfb778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 18 Mar 2019 15:07:57 +0000 Subject: [PATCH 02/78] windowsNavigator: Use subclasses instead of injections gnome-shell moved to ES6 classes, which means the constructor is no longer a regular method that we can swap out with an injected version. Instead, do our modifications in subclasses and use them to replace the original classes. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/143 --- extensions/windowsNavigator/extension.js | 224 ++++++++++------------- 1 file changed, 98 insertions(+), 126 deletions(-) diff --git a/extensions/windowsNavigator/extension.js b/extensions/windowsNavigator/extension.js index 7d58ebe2..831258a6 100644 --- a/extensions/windowsNavigator/extension.js +++ b/extensions/windowsNavigator/extension.js @@ -1,50 +1,65 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* exported enable disable */ +/* exported init enable disable */ const { Clutter, St } = imports.gi; const Main = imports.ui.main; const Workspace = imports.ui.workspace; const WorkspacesView = imports.ui.workspacesView; -function injectToFunction(parent, name, func) { - let origin = parent[name]; - parent[name] = function() { - let ret; - ret = origin.apply(this, arguments); - if (ret === undefined) - ret = func.apply(this, arguments); - return ret; - }; - return origin; -} +var MyWindowOverlay = class extends Workspace.WindowOverlay { + constructor(windowClone, parentActor) { + super(windowClone, parentActor); -let winInjections, workspaceInjections, workViewInjections, createdActors, connectedSignals; + this._id = null; + this._text = new St.Label({ + style_class: 'extension-windowsNavigator-window-tooltip', + visible: false + }); + parentActor.add_actor(this._text); + } -function resetState() { - winInjections = {}; - workspaceInjections = {}; - workViewInjections = {}; - createdActors = []; - connectedSignals = []; -} - -function enable() { - resetState(); - - Workspace.WindowOverlay.prototype.showTooltip = function() { + showTooltip() { this._text.raise_top(); this._text.show(); this._text.text = (this._windowClone.slotId + 1).toString(); - }; - winInjections['showTooltip'] = undefined; + } - Workspace.WindowOverlay.prototype.hideTooltip = function() { + hideTooltip() { if (this._text && this._text.visible) this._text.hide(); - }; - winInjections['hideTooltip'] = undefined; + } - Workspace.Workspace.prototype.showTooltip = function() { + relayout(animate) { + super.relayout(animate); + + let [cloneX, cloneY, cloneWidth_, cloneHeight_] = this._windowClone.slot; + + let textX = cloneX - 2; + let textY = cloneY - 2; + this._text.set_position(Math.floor(textX) + 5, Math.floor(textY) + 5); + this._text.raise_top(); + } +}; + +var MyWorkspace = class extends Workspace.Workspace { + constructor(metaWorkspace, monitorIndex) { + super(metaWorkspace, monitorIndex); + + if (metaWorkspace && metaWorkspace.index() < 9) { + this._tip = new St.Label({ + style_class: 'extension-windowsNavigator-window-tooltip', + visible: false + }); + this.actor.add_actor(this._tip); + + this.actor.connect('notify::scale-x', () => { + this._tip.set_scale(1 / this.actor.scale_x, 1 / this.actor.scale_x); + }); + } else + this._tip = null; + } + + showTooltip() { if (this._tip == null || this._actualGeometry == null) return; this._tip.text = (this.metaWorkspace.index() + 1).toString(); @@ -64,61 +79,74 @@ function enable() { this._tip.y = area.y; this._tip.show(); this._tip.raise_top(); - }; - workspaceInjections['showTooltip'] = undefined; + } - Workspace.Workspace.prototype.hideTooltip = function() { + hideTooltip() { if (this._tip == null) return; if (!this._tip.get_parent()) return; this._tip.hide(); - }; - workspaceInjections['hideTooltip'] = undefined; + } - Workspace.Workspace.prototype.getWindowWithTooltip = function(id) { + getWindowWithTooltip(id) { for (let i = 0; i < this._windows.length; i++) { if ((this._windows[i].slotId + 1) == id) return this._windows[i].metaWindow; } return null; - }; - workspaceInjections['getWindowWithTooltip'] = undefined; + } - Workspace.Workspace.prototype.showWindowsTooltips = function() { + showWindowsTooltips() { for (let i in this._windowOverlays) { if (this._windowOverlays[i] != null) this._windowOverlays[i].showTooltip(); } - }; - workspaceInjections['showWindowsTooltips'] = undefined; + } - Workspace.Workspace.prototype.hideWindowsTooltips = function() { + hideWindowsTooltips() { for (let i in this._windowOverlays) { if (this._windowOverlays[i] != null) this._windowOverlays[i].hideTooltip(); } - }; - workspaceInjections['hideWindowsTooltips'] = undefined; + } +}; - WorkspacesView.WorkspacesView.prototype._hideTooltips = function() { +var MyWorkspacesView = class extends WorkspacesView.WorkspacesView { + constructor(width, height, x, y, workspaces) { + super(width, height, x, y, workspaces); + + this._pickWorkspace = false; + this._pickWindow = false; + this._keyPressEventId = + global.stage.connect('key-press-event', this._onKeyPress.bind(this)); + this._keyReleaseEventId = + global.stage.connect('key-release-event', this._onKeyRelease.bind(this)); + } + + _onDestroy() { + super._onDestroy(); + + global.stage.disconnect(this._keyPressEventId); + global.stage.disconnect(this._keyReleaseEventId); + } + + _hideTooltips() { if (global.stage.get_key_focus() == global.stage) global.stage.set_key_focus(this._prevFocusActor); this._pickWindow = false; for (let i = 0; i < this._workspaces.length; i++) this._workspaces[i].hideWindowsTooltips(); - }; - workViewInjections['_hideTooltips'] = undefined; + } - WorkspacesView.WorkspacesView.prototype._hideWorkspacesTooltips = function() { + _hideWorkspacesTooltips() { global.stage.set_key_focus(this._prevFocusActor); this._pickWorkspace = false; for (let i = 0; i < this._workspaces.length; i++) this._workspaces[i].hideTooltip(); - }; - workViewInjections['_hideWorkspacesTooltips'] = undefined; + } - WorkspacesView.WorkspacesView.prototype._onKeyRelease = function(s, o) { + _onKeyRelease(s, o) { if (this._pickWindow && (o.get_key_symbol() == Clutter.KEY_Alt_L || o.get_key_symbol() == Clutter.KEY_Alt_R)) @@ -127,11 +155,11 @@ function enable() { (o.get_key_symbol() == Clutter.KEY_Control_L || o.get_key_symbol() == Clutter.KEY_Control_R)) this._hideWorkspacesTooltips(); - }; - workViewInjections['_onKeyRelease'] = undefined; + } - WorkspacesView.WorkspacesView.prototype._onKeyPress = function(s, o) { - if (Main.overview.viewSelector._activePage != Main.overview.viewSelector._workspacesPage) + _onKeyPress(s, o) { + let viewSelector = Main.overview.viewSelector; + if (viewSelector._activePage != viewSelector._workspacesPage) return false; let workspaceManager = global.workspace_manager; @@ -208,81 +236,25 @@ function enable() { return true; } return false; - }; - workViewInjections['_onKeyPress'] = undefined; + } +}; - winInjections['_init'] = injectToFunction(Workspace.WindowOverlay.prototype, '_init', function(windowClone, parentActor) { - this._id = null; - createdActors.push(this._text = new St.Label({ style_class: 'extension-windowsNavigator-window-tooltip' })); - this._text.hide(); - parentActor.add_actor(this._text); - }); +let origWindowOverlay, origWorkspace, origWorkspacesView; - winInjections['relayout'] = injectToFunction(Workspace.WindowOverlay.prototype, 'relayout', function(_animate) { - let [cloneX, cloneY, cloneWidth_, cloneHeight_] = this._windowClone.slot; - - let textX = cloneX - 2; - let textY = cloneY - 2; - this._text.set_position(Math.floor(textX) + 5, Math.floor(textY) + 5); - this._text.raise_top(); - }); - - workspaceInjections['_init'] = injectToFunction(Workspace.Workspace.prototype, '_init', function(metaWorkspace) { - if (metaWorkspace && metaWorkspace.index() < 9) { - createdActors.push(this._tip = new St.Label({ - style_class: 'extension-windowsNavigator-window-tooltip', - visible: false - })); - - this.actor.add_actor(this._tip); - let signalId = this.actor.connect('notify::scale-x', () => { - this._tip.set_scale(1 / this.actor.scale_x, 1 / this.actor.scale_x); - }); - connectedSignals.push({ obj: this.actor, id: signalId }); - } else - this._tip = null; - }); - - workViewInjections['_init'] = injectToFunction(WorkspacesView.WorkspacesView.prototype, '_init', function(_width, _height, _x, _y, _workspaces) { - this._pickWorkspace = false; - this._pickWindow = false; - this._keyPressEventId = - global.stage.connect('key-press-event', this._onKeyPress.bind(this)); - this._keyReleaseEventId = - global.stage.connect('key-release-event', this._onKeyRelease.bind(this)); - connectedSignals.push({ obj: global.stage, id: this._keyPressEventId }); - connectedSignals.push({ obj: global.stage, id: this._keyReleaseEventId }); - }); - - workViewInjections['_onDestroy'] = injectToFunction(WorkspacesView.WorkspacesView.prototype, '_onDestroy', function() { - global.stage.disconnect(this._keyPressEventId); - global.stage.disconnect(this._keyReleaseEventId); - connectedSignals = []; - }); +function init() { + origWindowOverlay = Workspace.WindowOverlay; + origWorkspace = Workspace.Workspace; + origWorkspacesView = WorkspacesView.WorkspacesView; } -function removeInjection(object, injection, name) { - if (injection[name] === undefined) - delete object[name]; - else - object[name] = injection[name]; +function enable() { + Workspace.WindowOverlay = MyWindowOverlay; + Workspace.Workspace = MyWorkspace; + WorkspacesView.WorkspacesView = MyWorkspacesView; } function disable() { - let i; - - for (i in workspaceInjections) - removeInjection(Workspace.Workspace.prototype, workspaceInjections, i); - for (i in winInjections) - removeInjection(Workspace.WindowOverlay.prototype, winInjections, i); - for (i in workViewInjections) - removeInjection(WorkspacesView.WorkspacesView.prototype, workViewInjections, i); - - for (i of connectedSignals) - i.obj.disconnect(i.id); - - for (i of createdActors) - i.destroy(); - - resetState(); + Workspace.WindowOverlay = origWindowOverlay; + Workspace.Workspace = origWorkspace; + WorkspacesView.WorkspacesView = origWorkspacesView; } From 3671d5a299ca8b42538ce9b09d857b950aa29ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 20 Mar 2019 08:59:09 +0000 Subject: [PATCH 03/78] cleanup: Use an extension object instead of globals https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/143 --- extensions/windowsNavigator/extension.js | 38 +++++++++++++----------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/extensions/windowsNavigator/extension.js b/extensions/windowsNavigator/extension.js index 831258a6..05d29652 100644 --- a/extensions/windowsNavigator/extension.js +++ b/extensions/windowsNavigator/extension.js @@ -1,5 +1,5 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* exported init enable disable */ +/* exported init */ const { Clutter, St } = imports.gi; const Main = imports.ui.main; @@ -239,22 +239,26 @@ var MyWorkspacesView = class extends WorkspacesView.WorkspacesView { } }; -let origWindowOverlay, origWorkspace, origWorkspacesView; +class Extension { + constructor() { + this._origWindowOverlay = Workspace.WindowOverlay; + this._origWorkspace = Workspace.Workspace; + this._origWorkspacesView = WorkspacesView.WorkspacesView; + } + + enable() { + Workspace.WindowOverlay = MyWindowOverlay; + Workspace.Workspace = MyWorkspace; + WorkspacesView.WorkspacesView = MyWorkspacesView; + } + + disable() { + Workspace.WindowOverlay = this._origWindowOverlay; + Workspace.Workspace = this._origWorkspace; + WorkspacesView.WorkspacesView = this._origWorkspacesView; + } +} function init() { - origWindowOverlay = Workspace.WindowOverlay; - origWorkspace = Workspace.Workspace; - origWorkspacesView = WorkspacesView.WorkspacesView; -} - -function enable() { - Workspace.WindowOverlay = MyWindowOverlay; - Workspace.Workspace = MyWorkspace; - WorkspacesView.WorkspacesView = MyWorkspacesView; -} - -function disable() { - Workspace.WindowOverlay = origWindowOverlay; - Workspace.Workspace = origWorkspace; - WorkspacesView.WorkspacesView = origWorkspacesView; + return new Extension(); } From 5b43d4733c6271d8d501895b4f2d79ab2b6ae0ad Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Wed, 10 Apr 2019 10:03:38 +0200 Subject: [PATCH 04/78] screenshot-window-sizer: Add phone screenshot sizes This is going to be convenient to take fake screenshots for phones like the Librem 5. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/65 --- extensions/screenshot-window-sizer/extension.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/screenshot-window-sizer/extension.js b/extensions/screenshot-window-sizer/extension.js index 41c4c853..0db7c83e 100644 --- a/extensions/screenshot-window-sizer/extension.js +++ b/extensions/screenshot-window-sizer/extension.js @@ -63,7 +63,9 @@ let SIZES = [ [800, 450], [1024, 576], [1200, 675], - [1600, 900] + [1600, 900], + [360, 654], // Phone portrait maximized + [720, 360] // Phone landscape fullscreen ]; function cycleScreenshotSizes(display, window, binding) { From ce10ad64c45169f82692f79c5b1c096a9c85c35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 17 Apr 2019 22:06:50 +0200 Subject: [PATCH 05/78] Update sass submodule --- data/gnome-shell-sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gnome-shell-sass b/data/gnome-shell-sass index 1b708a86..1a569565 160000 --- a/data/gnome-shell-sass +++ b/data/gnome-shell-sass @@ -1 +1 @@ -Subproject commit 1b708a862f4526055fc5f5352627490c0f8fbd1f +Subproject commit 1a569565e6a53d912b3216c752d7fddfeaee70b5 From e3a6e8f82c68f6e363ec1043e2a0eaba06b159ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 17 Apr 2019 22:09:40 +0200 Subject: [PATCH 06/78] Bump version to 3.32.1 Update NEWS. --- NEWS | 9 +++++++++ meson.build | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 0dddc214..f1adbcba 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +3.32.1 +====== +* Fix windowsNavigator extension after ES6 port [Florian; #143] +* screenshot-window-sizer: Add phone screenshot sizes [Adrien; !65] +* Misc. bug fixes and cleanups [Fabian; !62] + +Contributors: + Florian Müllner, Adrien Plazas, Fabian P. Schmidt + 3.32.0 ====== diff --git a/meson.build b/meson.build index 7d96d1c8..b987f2d4 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.32.0', + version: '3.32.1', meson_version: '>= 0.44.0', license: 'GPL2+' ) From 7c412ca7d95dfd1096a0134a9922d59738afdd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 5 Mar 2019 12:45:59 +0100 Subject: [PATCH 07/78] window-list: Don't use anchor point It is deprecated and we can easily replace it with a translation. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/64 --- extensions/window-list/extension.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index e1ea742e..2b384f0e 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -1009,8 +1009,8 @@ class WindowList { if (!Main.keyboard.actor) return; - let anchorY = Main.overview.visible ? 0 : this.actor.height; - Main.keyboard.actor.anchor_y = anchorY; + let translationY = Main.overview.visible ? 0 : this.actor.height; + Main.keyboard.actor.translation_y = -translationY; } _onAppStateChanged(appSys, app) { From f11c101878e8ba0e4e5adb489e10fcf5e1835513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 14 May 2019 17:53:56 +0000 Subject: [PATCH 08/78] Bump version to 3.33.1 Update NEWS. --- NEWS | 7 +++++++ meson.build | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f1adbcba..64a40f4f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +3.33.1 +====== +* Misc. bug fixes [Florian; !64] + +Contributors: + Florian Müllner + 3.32.1 ====== * Fix windowsNavigator extension after ES6 port [Florian; #143] diff --git a/meson.build b/meson.build index b987f2d4..057be5f8 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.32.1', + version: '3.33.1', meson_version: '>= 0.44.0', license: 'GPL2+' ) From cdd3fba5932a37729764c70d409fd46b2262f57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 15 Feb 2019 23:35:47 +0100 Subject: [PATCH 09/78] screenshot-window-sizer: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- .../screenshot-window-sizer/extension.js | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/extensions/screenshot-window-sizer/extension.js b/extensions/screenshot-window-sizer/extension.js index 0db7c83e..4d21212a 100644 --- a/extensions/screenshot-window-sizer/extension.js +++ b/extensions/screenshot-window-sizer/extension.js @@ -47,8 +47,9 @@ function flashMessage(message) { text.opacity = 255; let monitor = Main.layoutManager.primaryMonitor; - text.set_position(monitor.x + Math.floor(monitor.width / 2 - text.width / 2), - monitor.y + Math.floor(monitor.height / 2 - text.height / 2)); + text.set_position( + monitor.x + Math.floor(monitor.width / 2 - text.width / 2), + monitor.y + Math.floor(monitor.height / 2 - text.height / 2)); Tweener.addTween(text, { opacity: 0, @@ -137,17 +138,18 @@ function cycleScreenshotSizes(display, window, binding) { } function enable() { - Main.wm.addKeybinding('cycle-screenshot-sizes', - ExtensionUtils.getSettings(), - Meta.KeyBindingFlags.PER_WINDOW, - Shell.ActionMode.NORMAL, - cycleScreenshotSizes); - Main.wm.addKeybinding('cycle-screenshot-sizes-backward', - ExtensionUtils.getSettings(), - Meta.KeyBindingFlags.PER_WINDOW | - Meta.KeyBindingFlags.IS_REVERSED, - Shell.ActionMode.NORMAL, - cycleScreenshotSizes); + Main.wm.addKeybinding( + 'cycle-screenshot-sizes', + ExtensionUtils.getSettings(), + Meta.KeyBindingFlags.PER_WINDOW, + Shell.ActionMode.NORMAL, + cycleScreenshotSizes); + Main.wm.addKeybinding( + 'cycle-screenshot-sizes-backward', + ExtensionUtils.getSettings(), + Meta.KeyBindingFlags.PER_WINDOW | Meta.KeyBindingFlags.IS_REVERSED, + Shell.ActionMode.NORMAL, + cycleScreenshotSizes); } function disable() { From 3d5687ae3c05025d15a0e42949fc1578af53cb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 2 Mar 2019 22:53:05 +0100 Subject: [PATCH 10/78] workspace-indicator: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/workspace-indicator/extension.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 3be12686..7c81cd46 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -34,13 +34,14 @@ class WorkspaceIndicator extends PanelMenu.Button { this._workspaceSection = new PopupMenu.PopupMenuSection(); this.menu.addMenuItem(this._workspaceSection); - this._workspaceManagerSignals = []; - this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-added', - this._createWorkspacesSection.bind(this))); - this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-removed', - this._createWorkspacesSection.bind(this))); - this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-switched', - this._updateIndicator.bind(this))); + this._workspaceManagerSignals = [ + workspaceManager.connect_after('workspace-added', + this._createWorkspacesSection.bind(this)), + workspaceManager.connect_after('workspace-removed', + this._createWorkspacesSection.bind(this)), + workspaceManager.connect_after('workspace-switched', + this._updateIndicator.bind(this)) + ]; this.connect('scroll-event', this._onScrollEvent.bind(this)); this._createWorkspacesSection(); @@ -49,9 +50,9 @@ class WorkspaceIndicator extends PanelMenu.Button { this.statusLabel.add_style_class_name('panel-workspace-indicator'); this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA }); - this._settingsChangedId = - this._settings.connect(`changed::${WORKSPACE_KEY}`, - this._createWorkspacesSection.bind(this)); + this._settingsChangedId = this._settings.connect( + `changed::${WORKSPACE_KEY}`, + this._createWorkspacesSection.bind(this)); } _onDestroy() { From 06f13038348594c7fcb42cd3e4d2535f97583726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 2 Mar 2019 23:12:56 +0100 Subject: [PATCH 11/78] drive-menu: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/drive-menu/extension.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/drive-menu/extension.js b/extensions/drive-menu/extension.js index 7c8e36cf..b759254e 100644 --- a/extensions/drive-menu/extension.js +++ b/extensions/drive-menu/extension.js @@ -73,10 +73,10 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem { if (this.mount.can_eject()) this.mount.eject_with_operation(...unmountArgs, - this._ejectFinish.bind(this)); + this._ejectFinish.bind(this)); else this.mount.unmount_with_operation(...unmountArgs, - this._unmountFinish.bind(this)); + this._unmountFinish.bind(this)); } _unmountFinish(mount, result) { @@ -102,9 +102,9 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem { } activate(event) { + let uri = this.mount.get_root().get_uri(); let context = global.create_app_launch_context(event.get_time(), -1); - Gio.AppInfo.launch_default_for_uri(this.mount.get_root().get_uri(), - context); + Gio.AppInfo.launch_default_for_uri(uri, context); super.activate(event); } From 55c493389a9c39fbaf11238d5b111412c9983665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2019 00:09:49 +0100 Subject: [PATCH 12/78] auto-move-windows: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/auto-move-windows/extension.js | 4 ++-- extensions/auto-move-windows/prefs.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js index 646156aa..07de0084 100644 --- a/extensions/auto-move-windows/extension.js +++ b/extensions/auto-move-windows/extension.js @@ -17,7 +17,7 @@ class WindowMover { this._appsChangedId = this._appSystem.connect('installed-changed', - this._updateAppData.bind(this)); + this._updateAppData.bind(this)); this._settings.connect('changed', this._updateAppConfigs.bind(this)); this._updateAppConfigs(); @@ -50,7 +50,7 @@ class WindowMover { addedApps.forEach(app => { let data = { windowsChangedId: app.connect('windows-changed', - this._appWindowsChanged.bind(this)), + this._appWindowsChanged.bind(this)), moveWindowsId: 0, windows: app.get_windows() }; diff --git a/extensions/auto-move-windows/prefs.js b/extensions/auto-move-windows/prefs.js index f9c4699e..62eeee9f 100644 --- a/extensions/auto-move-windows/prefs.js +++ b/extensions/auto-move-windows/prefs.js @@ -233,8 +233,8 @@ const Widget = GObject.registerClass({ }); let { APPINFO, ICON, DISPLAY_NAME, WORKSPACE, ADJUSTMENT } = Columns; this._store.set(iter, - [APPINFO, ICON, DISPLAY_NAME, WORKSPACE, ADJUSTMENT], - [appInfo, icon, displayName, workspace, adj]); + [APPINFO, ICON, DISPLAY_NAME, WORKSPACE, ADJUSTMENT], + [appInfo, icon, displayName, workspace, adj]); } _checkId(id) { From 6a66cd4fa60ffb11b83a06f8a61252331f4a3bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2019 02:07:00 +0100 Subject: [PATCH 13/78] places-menu: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/places-menu/extension.js | 2 +- extensions/places-menu/placeDisplay.js | 54 ++++++++++++++------------ 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/extensions/places-menu/extension.js b/extensions/places-menu/extension.js index c477a4ac..a648c0a4 100644 --- a/extensions/places-menu/extension.js +++ b/extensions/places-menu/extension.js @@ -42,7 +42,7 @@ class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem { } this._changedId = info.connect('changed', - this._propertiesChanged.bind(this)); + this._propertiesChanged.bind(this)); } destroy() { diff --git a/extensions/places-menu/placeDisplay.js b/extensions/places-menu/placeDisplay.js index e97cef4f..ff41eb07 100644 --- a/extensions/places-menu/placeDisplay.js +++ b/extensions/places-menu/placeDisplay.js @@ -71,18 +71,21 @@ class PlaceInfo { } getIcon() { - this.file.query_info_async('standard::symbolic-icon', 0, 0, null, - (file, result) => { - try { - let info = file.query_info_finish(result); - this.icon = info.get_symbolic_icon(); - this.emit('changed'); - } catch (e) { - if (e instanceof Gio.IOErrorEnum) - return; - throw e; - } - }); + this.file.query_info_async('standard::symbolic-icon', + Gio.FileQueryInfoFlags.NONE, + 0, + null, + (file, result) => { + try { + let info = file.query_info_finish(result); + this.icon = info.get_symbolic_icon(); + this.emit('changed'); + } catch (e) { + if (e instanceof Gio.IOErrorEnum) + return; + throw e; + } + }); // return a generic icon for this kind for now, until we have the // icon from the query info above @@ -152,7 +155,7 @@ class RootInfo extends PlaceInfo { this._proxy = obj; this._proxy.connect('g-properties-changed', - this._propertiesChanged.bind(this)); + this._propertiesChanged.bind(this)); this._propertiesChanged(obj); }); } @@ -203,10 +206,10 @@ class PlaceDeviceInfo extends PlaceInfo { if (this._mount.can_eject()) this._mount.eject_with_operation(...unmountArgs, - this._ejectFinish.bind(this)); + this._ejectFinish.bind(this)); else this._mount.unmount_with_operation(...unmountArgs, - this._unmountFinish.bind(this)); + this._unmountFinish.bind(this)); } _ejectFinish(mount, result) { @@ -275,9 +278,8 @@ var PlacesManager = class { }; this._settings = new Gio.Settings({ schema_id: BACKGROUND_SCHEMA }); - this._showDesktopIconsChangedId = - this._settings.connect('changed::show-desktop-icons', - this._updateSpecials.bind(this)); + this._showDesktopIconsChangedId = this._settings.connect( + 'changed::show-desktop-icons', this._updateSpecials.bind(this)); this._updateSpecials(); /* @@ -350,9 +352,10 @@ var PlacesManager = class { let homePath = GLib.get_home_dir(); - this._places.special.push(new PlaceInfo('special', - Gio.File.new_for_path(homePath), - _('Home'))); + this._places.special.push(new PlaceInfo( + 'special', + Gio.File.new_for_path(homePath), + _('Home'))); let specials = []; let dirs = DEFAULT_DIRECTORIES.slice(); @@ -394,10 +397,11 @@ var PlacesManager = class { /* Add standard places */ this._places.devices.push(new RootInfo()); - this._places.network.push(new PlaceInfo('network', - Gio.File.new_for_uri('network:///'), - _('Browse Network'), - 'network-workgroup-symbolic')); + this._places.network.push(new PlaceInfo( + 'network', + Gio.File.new_for_uri('network:///'), + _('Browse Network'), + 'network-workgroup-symbolic')); /* first go through all connected drives */ let drives = this._volumeMonitor.get_connected_drives(); From e56f1a976ea2aaad73904442acae3edfcc7020ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2019 02:22:54 +0100 Subject: [PATCH 14/78] native-window-placement: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/native-window-placement/extension.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extensions/native-window-placement/extension.js b/extensions/native-window-placement/extension.js index 8a8b0937..608c1f6a 100644 --- a/extensions/native-window-placement/extension.js +++ b/extensions/native-window-placement/extension.js @@ -203,9 +203,10 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy { // Work out scaling by getting the most top-left and most bottom-right window coords. let scale; - scale = Math.min(areaRect.width / bounds.width, - areaRect.height / bounds.height, - 1.0); + scale = Math.min( + areaRect.width / bounds.width, + areaRect.height / bounds.height, + 1.0); // Make bounding rect fill the screen size for later steps bounds.x = bounds.x - (areaRect.width - bounds.width * scale) / 2; From 200d33776921d39749474935e2a972e3f779c558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2019 02:35:15 +0100 Subject: [PATCH 15/78] apps-menu: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/apps-menu/extension.js | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index d7ba570a..515709a2 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -58,7 +58,7 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem { let textureCache = St.TextureCache.get_default(); let iconThemeChangedId = textureCache.connect('icon-theme-changed', - this._updateIcon.bind(this)); + this._updateIcon.bind(this)); this.actor.connect('destroy', () => { textureCache.disconnect(iconThemeChangedId); }); @@ -262,7 +262,7 @@ class DesktopTarget { this._windowAddedId = global.window_group.connect('actor-added', - this._onWindowAdded.bind(this)); + this._onWindowAdded.bind(this)); global.get_window_actors().forEach(a => { this._onWindowAdded(a.get_parent(), a); @@ -322,8 +322,8 @@ class DesktopTarget { // Hack: force nautilus to reload file info info = new Gio.FileInfo(); - info.set_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_ACCESS, - GLib.get_real_time()); + info.set_attribute_uint64( + Gio.FILE_ATTRIBUTE_TIME_ACCESS, GLib.get_real_time()); try { await file.set_attributes_async(info, queryFlags, ioPriority, null); } catch (e) { @@ -411,7 +411,7 @@ class ApplicationsButton extends PanelMenu.Button { this.remove_accessible_state (Atk.StateType.CHECKED); }); Main.layoutManager.connect('startup-complete', - this._setKeybinding.bind(this)); + this._setKeybinding.bind(this)); this._setKeybinding(); this._desktopTarget = new DesktopTarget(); @@ -426,14 +426,14 @@ class ApplicationsButton extends PanelMenu.Button { this._tree = new GMenu.Tree({ menu_basename: 'applications.menu' }); this._treeChangedId = this._tree.connect('changed', - this._onTreeChanged.bind(this)); + this._onTreeChanged.bind(this)); this._applicationsButtons = new Map(); this.reloadFlag = false; this._createLayout(); this._display(); this._installedChangedId = appSys.connect('installed-changed', - this._onTreeChanged.bind(this)); + this._onTreeChanged.bind(this)); } _onTreeChanged() { @@ -465,12 +465,11 @@ class ApplicationsButton extends PanelMenu.Button { this._tree.disconnect(this._treeChangedId); this._tree = null; - let handler = Main.sessionMode.hasOverview ? - Main.overview.toggle.bind(Main.overview) : null; Main.wm.setCustomKeybindingHandler('panel-main-menu', - Shell.ActionMode.NORMAL | - Shell.ActionMode.OVERVIEW, - handler); + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + Main.sessionMode.hasOverview + ? Main.overview.toggle.bind(Main.overview) + : null); this._desktopTarget.destroy(); } @@ -522,9 +521,8 @@ class ApplicationsButton extends PanelMenu.Button { _setKeybinding() { Main.wm.setCustomKeybindingHandler('panel-main-menu', - Shell.ActionMode.NORMAL | - Shell.ActionMode.OVERVIEW, - () => this.menu.toggle()); + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + () => this.menu.toggle()); } _redisplay() { From ad914441a2ab44a03922b93296c22b1966e80336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2019 02:49:19 +0100 Subject: [PATCH 16/78] window-list: Reindent to conform with new style Instead of aligning arguments like we used to do, use a consistent four-space indent as mandated by gjs' current style guide. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- extensions/window-list/extension.js | 229 +++++++++++++--------------- 1 file changed, 104 insertions(+), 125 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 2b384f0e..9a8077d0 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -72,9 +72,8 @@ class WindowContextMenu extends PopupMenu.PopupMenu { }); this.addMenuItem(this._minimizeItem); - this._notifyMinimizedId = - this._metaWindow.connect('notify::minimized', - this._updateMinimizeItem.bind(this)); + this._notifyMinimizedId = this._metaWindow.connect( + 'notify::minimized', this._updateMinimizeItem.bind(this)); this._updateMinimizeItem(); this._maximizeItem = new PopupMenu.PopupMenuItem(''); @@ -86,12 +85,12 @@ class WindowContextMenu extends PopupMenu.PopupMenu { }); this.addMenuItem(this._maximizeItem); - this._notifyMaximizedHId = - this._metaWindow.connect('notify::maximized-horizontally', - this._updateMaximizeItem.bind(this)); - this._notifyMaximizedVId = - this._metaWindow.connect('notify::maximized-vertically', - this._updateMaximizeItem.bind(this)); + this._notifyMaximizedHId = this._metaWindow.connect( + 'notify::maximized-horizontally', + this._updateMaximizeItem.bind(this)); + this._notifyMaximizedVId = this._metaWindow.connect( + 'notify::maximized-vertically', + this._updateMaximizeItem.bind(this)); this._updateMaximizeItem(); this._closeItem = new PopupMenu.PopupMenuItem(_('Close')); @@ -146,25 +145,20 @@ class WindowTitle { this.actor.add(this.label_actor); this._textureCache = St.TextureCache.get_default(); - this._iconThemeChangedId = - this._textureCache.connect('icon-theme-changed', - this._updateIcon.bind(this)); - this._notifyWmClass = - this._metaWindow.connect_after('notify::wm-class', - this._updateIcon.bind(this)); - this._notifyAppId = - this._metaWindow.connect_after('notify::gtk-application-id', - this._updateIcon.bind(this)); + this._iconThemeChangedId = this._textureCache.connect( + 'icon-theme-changed', this._updateIcon.bind(this)); + this._notifyWmClass = this._metaWindow.connect_after( + 'notify::wm-class', this._updateIcon.bind(this)); + this._notifyAppId = this._metaWindow.connect_after( + 'notify::gtk-application-id', this._updateIcon.bind(this)); this._updateIcon(); this.actor.connect('destroy', this._onDestroy.bind(this)); - this._notifyTitleId = - this._metaWindow.connect('notify::title', - this._updateTitle.bind(this)); - this._notifyMinimizedId = - this._metaWindow.connect('notify::minimized', - this._minimizedChanged.bind(this)); + this._notifyTitleId = this._metaWindow.connect( + 'notify::title', this._updateTitle.bind(this)); + this._notifyMinimizedId = this._metaWindow.connect( + 'notify::minimized', this._minimizedChanged.bind(this)); this._minimizedChanged(); } @@ -222,24 +216,23 @@ class BaseButton { this.actor._delegate = this; this.actor.connect('allocation-changed', - this._updateIconGeometry.bind(this)); + this._updateIconGeometry.bind(this)); this.actor.connect('clicked', this._onClicked.bind(this)); this.actor.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('popup-menu', this._onPopupMenu.bind(this)); this._contextMenuManager = new PopupMenu.PopupMenuManager(this); - this._switchWorkspaceId = - global.window_manager.connect('switch-workspace', - this._updateVisibility.bind(this)); + this._switchWorkspaceId = global.window_manager.connect( + 'switch-workspace', this._updateVisibility.bind(this)); if (this._perMonitor) { - this._windowEnteredMonitorId = - global.display.connect('window-entered-monitor', - this._windowEnteredOrLeftMonitor.bind(this)); - this._windowLeftMonitorId = - global.display.connect('window-left-monitor', - this._windowEnteredOrLeftMonitor.bind(this)); + this._windowEnteredMonitorId = global.display.connect( + 'window-entered-monitor', + this._windowEnteredOrLeftMonitor.bind(this)); + this._windowLeftMonitorId = global.display.connect( + 'window-left-monitor', + this._windowEnteredOrLeftMonitor.bind(this)); } } @@ -339,13 +332,11 @@ class WindowButton extends BaseButton { this._contextMenuManager.addMenu(this._contextMenu); Main.uiGroup.add_actor(this._contextMenu.actor); - this._workspaceChangedId = - this.metaWindow.connect('workspace-changed', - this._updateVisibility.bind(this)); + this._workspaceChangedId = this.metaWindow.connect( + 'workspace-changed', this._updateVisibility.bind(this)); - this._notifyFocusId = - global.display.connect('notify::focus-window', - this._updateStyle.bind(this)); + this._notifyFocusId = global.display.connect( + 'notify::focus-window', this._updateStyle.bind(this)); this._updateStyle(); } @@ -509,15 +500,13 @@ class AppButton extends BaseButton { this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); }); - this._windowsChangedId = - this.app.connect('windows-changed', - this._windowsChanged.bind(this)); + this._windowsChangedId = this.app.connect( + 'windows-changed', this._windowsChanged.bind(this)); this._windowsChanged(); this._windowTracker = Shell.WindowTracker.get_default(); - this._notifyFocusId = - this._windowTracker.connect('notify::focus-app', - this._updateStyle.bind(this)); + this._notifyFocusId = this._windowTracker.connect( + 'notify::focus-app', this._updateStyle.bind(this)); this._updateStyle(); } @@ -565,8 +554,8 @@ class AppButton extends BaseButton { this._windowTitle = new WindowTitle(this.metaWindow); this._singleWindowTitle.child = this._windowTitle.actor; this._windowContextMenu = new WindowContextMenu(this.actor, this.metaWindow); - this._windowContextMenu.connect('open-state-changed', - _onMenuStateChanged); + this._windowContextMenu.connect( + 'open-state-changed', _onMenuStateChanged); Main.uiGroup.add_actor(this._windowContextMenu.actor); this._windowContextMenu.actor.hide(); this._contextMenuManager.addMenu(this._windowContextMenu); @@ -671,19 +660,19 @@ class WorkspaceIndicator extends PanelMenu.Button { this.workspacesItems = []; - this._workspaceManagerSignals = []; - this._workspaceManagerSignals.push(workspaceManager.connect('notify::n-workspaces', - this._updateMenu.bind(this))); - this._workspaceManagerSignals.push(workspaceManager.connect_after('workspace-switched', - this._updateIndicator.bind(this))); + this._workspaceManagerSignals = [ + workspaceManager.connect('notify::n-workspaces', + this._updateMenu.bind(this)), + workspaceManager.connect_after('workspace-switched', + this._updateIndicator.bind(this)) + ]; this.connect('scroll-event', this._onScrollEvent.bind(this)); this._updateMenu(); this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' }); - this._settingsChangedId = - this._settings.connect('changed::workspace-names', - this._updateMenu.bind(this)); + this._settingsChangedId = this._settings.connect( + 'changed::workspace-names', this._updateMenu.bind(this)); } _onDestroy() { @@ -812,12 +801,12 @@ class WindowList { indicatorsBox.add(this._workspaceIndicator.container, { expand: false, y_fill: true }); this._mutterSettings = new Gio.Settings({ schema_id: 'org.gnome.mutter' }); - this._workspacesOnlyOnPrimaryChangedId = - this._mutterSettings.connect('changed::workspaces-only-on-primary', - this._updateWorkspaceIndicatorVisibility.bind(this)); - this._dynamicWorkspacesChangedId = - this._mutterSettings.connect('changed::dynamic-workspaces', - this._updateWorkspaceIndicatorVisibility.bind(this)); + this._workspacesOnlyOnPrimaryChangedId = this._mutterSettings.connect( + 'changed::workspaces-only-on-primary', + this._updateWorkspaceIndicatorVisibility.bind(this)); + this._dynamicWorkspacesChangedId = this._mutterSettings.connect( + 'changed::dynamic-workspaces', + this._updateWorkspaceIndicatorVisibility.bind(this)); this._updateWorkspaceIndicatorVisibility(); this._menuManager = new PopupMenu.PopupMenuManager(this); @@ -835,59 +824,54 @@ class WindowList { this._updatePosition(); this._appSystem = Shell.AppSystem.get_default(); - this._appStateChangedId = - this._appSystem.connect('app-state-changed', - this._onAppStateChanged.bind(this)); + this._appStateChangedId = this._appSystem.connect( + 'app-state-changed', this._onAppStateChanged.bind(this)); - this._keyboardVisiblechangedId = - Main.layoutManager.connect('keyboard-visible-changed', - (o, state) => { - Main.layoutManager.keyboardBox.visible = state; - let keyboardBox = Main.layoutManager.keyboardBox; - keyboardBox.visible = state; - if (state) - Main.uiGroup.set_child_above_sibling(this.actor, keyboardBox); - else - Main.uiGroup.set_child_above_sibling(this.actor, - Main.layoutManager.panelBox); - this._updateKeyboardAnchor(); - }); + this._keyboardVisiblechangedId = Main.layoutManager.connect( + 'keyboard-visible-changed', + (o, state) => { + Main.layoutManager.keyboardBox.visible = state; + let keyboardBox = Main.layoutManager.keyboardBox; + keyboardBox.visible = state; + if (state) { + Main.uiGroup.set_child_above_sibling( + this.actor, keyboardBox); + } else { + Main.uiGroup.set_child_above_sibling( + this.actor, Main.layoutManager.panelBox); + } + this._updateKeyboardAnchor(); + }); let workspaceManager = global.workspace_manager; this._workspaceSignals = new Map(); - this._nWorkspacesChangedId = - workspaceManager.connect('notify::n-workspaces', - this._onWorkspacesChanged.bind(this)); + this._nWorkspacesChangedId = workspaceManager.connect( + 'notify::n-workspaces', this._onWorkspacesChanged.bind(this)); this._onWorkspacesChanged(); - this._switchWorkspaceId = - global.window_manager.connect('switch-workspace', - this._checkGrouping.bind(this)); + this._switchWorkspaceId = global.window_manager.connect( + 'switch-workspace', this._checkGrouping.bind(this)); - this._overviewShowingId = - Main.overview.connect('showing', () => { - this.actor.hide(); - this._updateKeyboardAnchor(); - }); + this._overviewShowingId = Main.overview.connect('showing', () => { + this.actor.hide(); + this._updateKeyboardAnchor(); + }); - this._overviewHidingId = - Main.overview.connect('hiding', () => { - this.actor.visible = !Main.layoutManager.primaryMonitor.inFullscreen; - this._updateKeyboardAnchor(); - }); + this._overviewHidingId = Main.overview.connect('hiding', () => { + this.actor.visible = !Main.layoutManager.primaryMonitor.inFullscreen; + this._updateKeyboardAnchor(); + }); this._fullscreenChangedId = global.display.connect('in-fullscreen-changed', () => { this._updateKeyboardAnchor(); }); - this._dragBeginId = - Main.xdndHandler.connect('drag-begin', - this._onDragBegin.bind(this)); - this._dragEndId = - Main.xdndHandler.connect('drag-end', - this._onDragEnd.bind(this)); + this._dragBeginId = Main.xdndHandler.connect('drag-begin', + this._onDragBegin.bind(this)); + this._dragEndId = Main.xdndHandler.connect('drag-end', + this._onDragEnd.bind(this)); this._dragMonitor = { dragMotion: this._onDragMotion.bind(this) }; @@ -896,9 +880,8 @@ class WindowList { this._dndWindow = null; this._settings = ExtensionUtils.getSettings(); - this._groupingModeChangedId = - this._settings.connect('changed::grouping-mode', - this._groupingModeChanged.bind(this)); + this._groupingModeChangedId = this._settings.connect( + 'changed::grouping-mode', this._groupingModeChanged.bind(this)); this._grouped = undefined; this._groupingModeChanged(); } @@ -922,8 +905,9 @@ class WindowList { } _updatePosition() { - this.actor.set_position(this._monitor.x, - this._monitor.y + this._monitor.height - this.actor.height); + this.actor.set_position( + this._monitor.x, + this._monitor.y + this._monitor.height - this.actor.height); } _updateWorkspaceIndicatorVisibility() { @@ -1026,9 +1010,9 @@ class WindowList { _addApp(app) { let button = new AppButton(app, this._perMonitor, this._monitor.index); this._windowList.layout_manager.pack(button.actor, - true, true, true, - Clutter.BoxAlignment.START, - Clutter.BoxAlignment.START); + true, true, true, + Clutter.BoxAlignment.START, + Clutter.BoxAlignment.START); } _removeApp(app) { @@ -1054,9 +1038,9 @@ class WindowList { let button = new WindowButton(win, this._perMonitor, this._monitor.index); this._windowList.layout_manager.pack(button.actor, - true, true, true, - Clutter.BoxAlignment.START, - Clutter.BoxAlignment.START); + true, true, true, + Clutter.BoxAlignment.START, + Clutter.BoxAlignment.START); } _onWindowRemoved(ws, win) { @@ -1085,12 +1069,10 @@ class WindowList { continue; let signals = { windowAddedId: 0, windowRemovedId: 0 }; - signals._windowAddedId = - workspace.connect_after('window-added', - this._onWindowAdded.bind(this)); - signals._windowRemovedId = - workspace.connect('window-removed', - this._onWindowRemoved.bind(this)); + signals._windowAddedId = workspace.connect_after( + 'window-added', this._onWindowAdded.bind(this)); + signals._windowRemovedId = workspace.connect( + 'window-removed', this._onWindowRemoved.bind(this)); this._workspaceSignals.set(workspace, signals); } @@ -1138,8 +1120,7 @@ class WindowList { this._dndWindow = hoveredWindow; this._dndTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, - DND_ACTIVATE_TIMEOUT, - this._activateWindow.bind(this)); + DND_ACTIVATE_TIMEOUT, this._activateWindow.bind(this)); return DND.DragMotionResult.CONTINUE; } @@ -1213,13 +1194,11 @@ class Extension { this._windowLists = []; this._settings = ExtensionUtils.getSettings(); - this._showOnAllMonitorsChangedId = - this._settings.connect('changed::show-on-all-monitors', - this._buildWindowLists.bind(this)); + this._showOnAllMonitorsChangedId = this._settings.connect( + 'changed::show-on-all-monitors', this._buildWindowLists.bind(this)); - this._monitorsChangedId = - Main.layoutManager.connect('monitors-changed', - this._buildWindowLists.bind(this)); + this._monitorsChangedId = Main.layoutManager.connect( + 'monitors-changed', this._buildWindowLists.bind(this)); this._buildWindowLists(); } From 25e43a5d087be73bf00d45fbf49bd15593ae9edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 5 Mar 2019 06:44:59 +0100 Subject: [PATCH 17/78] lint: Remove legacy configuration After the last batch of indentation changes, the whole code base conforms to the new style now, so we can drop the legacy eslint configuration. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/66 --- .gitlab-ci.yml | 2 +- lint/eslintrc-legacy.json | 16 ---------- lint/generate-report.sh | 61 --------------------------------------- 3 files changed, 1 insertion(+), 78 deletions(-) delete mode 100644 lint/eslintrc-legacy.json delete mode 100644 lint/generate-report.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9bd1f9d9..8f6b13ab 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ eslint: image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1 stage: source_check script: - - sh lint/generate-report.sh -o $LINT_LOG || { cat $LINT_LOG; false; } + - eslint -o $LINT_LOG --no-color || { cat $LINT_LOG; false; } <<: *only_default artifacts: paths: diff --git a/lint/eslintrc-legacy.json b/lint/eslintrc-legacy.json deleted file mode 100644 index aca79adf..00000000 --- a/lint/eslintrc-legacy.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "rules": { - "indent": [ - "error", - 4, - { - "ignoredNodes": [ - "CallExpression > ArrowFunctionExpression", - "CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child" - ], - "CallExpression": { "arguments": "first" }, - "MemberExpression": "off" - } - ] - } -} diff --git a/lint/generate-report.sh b/lint/generate-report.sh deleted file mode 100644 index 1d34401e..00000000 --- a/lint/generate-report.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh -SEP=`printf '\t'` -OUTPUT=/dev/stderr -CWD=`pwd` -SRCDIR=`dirname $0` - -run_lint() { - eslint -f unix "$@" . -} - -parse_opts() { - tmp=`getopt -l output: o: "$@"` - [ $? -ne 0 ] && exit 1 - - eval set -- $tmp - while true - do - case $1 in - --output|-o) - OUTPUT=`realpath $2`; shift 2; continue ;; - --) - shift; break ;; - esac - done -} - -# delete lines that don't start with '/', -# replace the first space with tab, sort -process_for_join() { - sed -E "/\//!d; s|(\S+)\s|\1$SEP|" | sort -k 1b,1 -} - -# re-replace tab with space -process_post_join() { - sed -E "s|$SEP| |" -} - -create_report() { - tmp1=`mktemp --tmpdir lint-XXXX` - run_lint | process_for_join > $tmp1 - - tmp2=`mktemp --tmpdir lint-XXXX` - run_lint -c lint/eslintrc-legacy.json | process_for_join > $tmp2 - - join -t"$SEP" -o '0,1.2' $tmp1 $tmp2 | process_post_join - rm $tmp1 $tmp2 -} - - -parse_opts "$@" - -cd $SRCDIR/.. - -create_report | tee $OUTPUT | grep -q . -rv=$(( $? == 0 )) - -cd $CWD - -[ $rv -eq 0 -a -f $OUTPUT ] && rm $OUTPUT - -exit $rv From a36331522f97719c500969c39a8ec3dcae12455a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 22 May 2019 18:58:31 +0000 Subject: [PATCH 18/78] Bump version to 3.33.2 Update NEWS. --- NEWS | 7 +++++++ meson.build | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 64a40f4f..e3f86f5e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +3.33.2 +====== +* Misc. bug fixes and cleanups [Florian; !66] + +Contributors: + Florian Müllner + 3.33.1 ====== * Misc. bug fixes [Florian; !64] diff --git a/meson.build b/meson.build index 057be5f8..4fe9969e 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.33.1', + version: '3.33.2', meson_version: '>= 0.44.0', license: 'GPL2+' ) From f166ca501f383b767485deba9f14cae0803d3e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 08:52:23 +0000 Subject: [PATCH 19/78] window-list: Stop using deprecated actor property Since PanelMenu.Button was changed to inherit from St.Widget, its actor property is deprecated and points to itself. Stop using it to avoid the corresponding warning. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67 --- extensions/window-list/extension.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 9a8077d0..637842e2 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -917,7 +917,7 @@ class WindowList { let workspacesOnMonitor = this._monitor == Main.layoutManager.primaryMonitor || !this._mutterSettings.get_boolean('workspaces-only-on-primary'); - this._workspaceIndicator.actor.visible = hasWorkspaces && workspacesOnMonitor; + this._workspaceIndicator.visible = hasWorkspaces && workspacesOnMonitor; } _getPreferredUngroupedWindowListWidth() { @@ -940,7 +940,7 @@ class WindowList { } _getMaxWindowListWidth() { - let indicatorsBox = this._workspaceIndicator.actor.get_parent(); + let indicatorsBox = this._workspaceIndicator.get_parent(); return this.actor.width - indicatorsBox.get_preferred_width(-1)[1]; } From 8499b0e254d387ac1e41b4107145cec6e6f747e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 08:38:21 +0000 Subject: [PATCH 20/78] apps-menu: Adjust to GObject-ification of menu items https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67 --- extensions/apps-menu/extension.js | 84 ++++++++++++++++--------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index 515709a2..7fada8e7 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -25,11 +25,12 @@ const NAVIGATION_REGION_OVERSHOOT = 50; Gio._promisify(Gio._LocalFilePrototype, 'query_info_async', 'query_info_finish'); Gio._promisify(Gio._LocalFilePrototype, 'set_attributes_async', 'set_attributes_finish'); +var ActivitiesMenuItem = GObject.registerClass( class ActivitiesMenuItem extends PopupMenu.PopupBaseMenuItem { - constructor(button) { - super(); + _init(button) { + super._init(); this._button = button; - this.actor.add_child(new St.Label({ text: _('Activities Overview') })); + this.add_child(new St.Label({ text: _('Activities Overview') })); } activate(event) { @@ -37,35 +38,36 @@ class ActivitiesMenuItem extends PopupMenu.PopupBaseMenuItem { Main.overview.toggle(); super.activate(event); } -} +}); +var ApplicationMenuItem = GObject.registerClass( class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem { - constructor(button, app) { - super(); + _init(button, app) { + super._init(); this._app = app; this._button = button; this._iconBin = new St.Bin(); - this.actor.add_child(this._iconBin); + this.add_child(this._iconBin); let appLabel = new St.Label({ text: app.get_name(), y_expand: true, y_align: Clutter.ActorAlign.CENTER }); - this.actor.add_child(appLabel); - this.actor.label_actor = appLabel; + this.add_child(appLabel); + this.label_actor = appLabel; let textureCache = St.TextureCache.get_default(); let iconThemeChangedId = textureCache.connect('icon-theme-changed', this._updateIcon.bind(this)); - this.actor.connect('destroy', () => { + this.connect('destroy', () => { textureCache.disconnect(iconThemeChangedId); }); this._updateIcon(); - this.actor._delegate = this; - let draggable = DND.makeDraggable(this.actor); + this._delegate = this; + let draggable = DND.makeDraggable(this); let maybeStartDrag = draggable._maybeStartDrag; draggable._maybeStartDrag = (event) => { @@ -103,11 +105,12 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem { _updateIcon() { this._iconBin.set_child(this.getDragActor()); } -} +}); +var CategoryMenuItem = GObject.registerClass( class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { - constructor(button, category) { - super(); + _init(button, category) { + super._init(); this._category = category; this._button = button; @@ -120,8 +123,9 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { else name = _('Favorites'); - this.actor.add_child(new St.Label({ text: name })); - this.actor.connect('motion-event', this._onMotionEvent.bind(this)); + this.add_child(new St.Label({ text: name })); + this.connect('motion-event', this._onMotionEvent.bind(this)); + this.connect('notify::active', this._onActiveChanged.bind(this)); } activate(event) { @@ -131,7 +135,7 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { } _isNavigatingSubmenu([x, y]) { - let [posX, posY] = this.actor.get_transformed_position(); + let [posX, posY] = this.get_transformed_position(); if (this._oldX == -1) { this._oldX = x; @@ -146,11 +150,11 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { this._oldY = y; // If it lies outside the x-coordinates then it is definitely outside. - if (posX > x || posX + this.actor.width < x) + if (posX > x || posX + this.width < x) return false; // If it lies inside the menu item then it is definitely inside. - if (posY <= y && posY + this.actor.height >= y) + if (posY <= y && posY + this.height >= y) return true; // We want the keep-up triangle only if the movement is more @@ -171,17 +175,17 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { // only check for triangle ABC. if (posY > y) { let offset = posY - y; - y = posY + this.actor.height + offset; + y = posY + this.height + offset; } // Ensure that A is (0, 0). x -= posX; - y -= posY + this.actor.height; + y -= posY + this.height; // Check which side of line AB the point P lies on by taking the // cross-product of AB and AP. See: // http://stackoverflow.com/questions/3461453/determine-which-side-of-a-line-a-point-lies - if (((this.actor.width * y) - (NAVIGATION_REGION_OVERSHOOT * x)) <= 0) + if (((this.width * y) - (NAVIGATION_REGION_OVERSHOOT * x)) <= 0) return true; return false; @@ -191,16 +195,16 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { if (!Clutter.get_pointer_grab()) { this._oldX = -1; this._oldY = -1; - Clutter.grab_pointer(this.actor); + Clutter.grab_pointer(this); } - this.actor.hover = true; + this.hover = true; if (this._isNavigatingSubmenu(event.get_coords())) return true; this._oldX = -1; this._oldY = -1; - this.actor.hover = false; + this.hover = false; Clutter.ungrab_pointer(); let source = event.get_source(); @@ -210,14 +214,14 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem { return false; } - setActive(active, params) { - if (active) { - this._button.selectCategory(this._category); - this._button.scrollToCatButton(this); - } - super.setActive(active, params); + _onActiveChanged() { + if (!this.active) + return; + + this._button.selectCategory(this._category); + this._button.scrollToCatButton(this); } -} +}); class ApplicationsMenu extends PopupMenu.PopupMenu { constructor(sourceActor, arrowAlignment, arrowSide, button) { @@ -563,7 +567,7 @@ class ApplicationsButton extends PanelMenu.Button { let appsScrollBoxAlloc = this.applicationsScrollBox.get_allocation_box(); let currentScrollValue = appsScrollBoxAdj.get_value(); let boxHeight = appsScrollBoxAlloc.y2 - appsScrollBoxAlloc.y1; - let buttonAlloc = button.actor.get_allocation_box(); + let buttonAlloc = button.get_allocation_box(); let newScrollValue = currentScrollValue; if (currentScrollValue > buttonAlloc.y1 - 10) newScrollValue = buttonAlloc.y1 - 10; @@ -578,7 +582,7 @@ class ApplicationsButton extends PanelMenu.Button { let catsScrollBoxAlloc = this.categoriesScrollBox.get_allocation_box(); let currentScrollValue = catsScrollBoxAdj.get_value(); let boxHeight = catsScrollBoxAlloc.y2 - catsScrollBoxAlloc.y1; - let buttonAlloc = button.actor.get_allocation_box(); + let buttonAlloc = button.get_allocation_box(); let newScrollValue = currentScrollValue; if (currentScrollValue > buttonAlloc.y1 - 10) newScrollValue = buttonAlloc.y1 - 10; @@ -625,7 +629,7 @@ class ApplicationsButton extends PanelMenu.Button { }); let activities = new ActivitiesMenuItem(this); - this.leftBox.add(activities.actor, { + this.leftBox.add(activities, { expand: false, x_fill: true, y_fill: false, @@ -661,7 +665,7 @@ class ApplicationsButton extends PanelMenu.Button { this._tree.load_sync(); let root = this._tree.get_root_directory(); let categoryMenuItem = new CategoryMenuItem(this, null); - this.categoriesBox.add_actor(categoryMenuItem.actor); + this.categoriesBox.add_actor(categoryMenuItem); let iter = root.iter(); let nextType; while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) { @@ -677,7 +681,7 @@ class ApplicationsButton extends PanelMenu.Button { this._loadCategory(categoryId, dir); if (this.applicationsByCategory[categoryId].length > 0) { let categoryMenuItem = new CategoryMenuItem(this, dir); - this.categoriesBox.add_actor(categoryMenuItem.actor); + this.categoriesBox.add_actor(categoryMenuItem); } } @@ -718,8 +722,8 @@ class ApplicationsButton extends PanelMenu.Button { item.setDragEnabled(this._desktopTarget.hasDesktop); this._applicationsButtons.set(app, item); } - if (!item.actor.get_parent()) - this.applicationsBox.add_actor(item.actor); + if (!item.get_parent()) + this.applicationsBox.add_actor(item); } } From 65191d83b40dd8a10f4833d8e189bdb0e0fa10f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 08:45:47 +0000 Subject: [PATCH 21/78] drive-menu: Adjust to GObject-ification of menu items https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67 --- extensions/drive-menu/extension.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/extensions/drive-menu/extension.js b/extensions/drive-menu/extension.js index b759254e..41e30a39 100644 --- a/extensions/drive-menu/extension.js +++ b/extensions/drive-menu/extension.js @@ -12,29 +12,32 @@ const ShellMountOperation = imports.ui.shellMountOperation; const ExtensionUtils = imports.misc.extensionUtils; +var MountMenuItem = GObject.registerClass( class MountMenuItem extends PopupMenu.PopupBaseMenuItem { - constructor(mount) { - super(); + _init(mount) { + super._init(); this.label = new St.Label({ text: mount.get_name() }); - this.actor.add(this.label, { expand: true }); - this.actor.label_actor = this.label; + this.add(this.label, { expand: true }); + this.label_actor = this.label; this.mount = mount; + this.connect('destroy', this._onDestroy.bind(this)); + let ejectIcon = new St.Icon({ icon_name: 'media-eject-symbolic', style_class: 'popup-menu-icon' }); let ejectButton = new St.Button({ child: ejectIcon }); ejectButton.connect('clicked', this._eject.bind(this)); - this.actor.add(ejectButton); + this.add(ejectButton); this._changedId = mount.connect('changed', this._syncVisibility.bind(this)); this._syncVisibility(); } - destroy() { + _onDestroy() { if (this._changedId) { this.mount.disconnect(this._changedId); this._changedId = 0; @@ -61,7 +64,7 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem { } _syncVisibility() { - this.actor.visible = this._isInteresting(); + this.visible = this._isInteresting(); } _eject() { @@ -108,7 +111,7 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem { super.activate(event); } -} +}); let DriveMenu = GObject.registerClass( class DriveMenu extends PanelMenu.Button { From 3a596054ad11035eae9451868b586e0ee728bb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 08:47:26 +0000 Subject: [PATCH 22/78] places-menu: Adjust to GObject-ification of menu items https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/67 --- extensions/places-menu/extension.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/extensions/places-menu/extension.js b/extensions/places-menu/extension.js index a648c0a4..00aa04d9 100644 --- a/extensions/places-menu/extension.js +++ b/extensions/places-menu/extension.js @@ -17,19 +17,20 @@ const PlaceDisplay = Me.imports.placeDisplay; const PLACE_ICON_SIZE = 16; +var PlaceMenuItem = GObject.registerClass( class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem { - constructor(info) { - super(); + _init(info) { + super._init(); this._info = info; this._icon = new St.Icon({ gicon: info.icon, icon_size: PLACE_ICON_SIZE }); - this.actor.add_child(this._icon); + this.add_child(this._icon); this._label = new St.Label({ text: info.name, x_expand: true }); - this.actor.add_child(this._label); + this.add_child(this._label); if (info.isRemovable()) { this._ejectIcon = new St.Icon({ @@ -38,7 +39,7 @@ class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem { }); this._ejectButton = new St.Button({ child: this._ejectIcon }); this._ejectButton.connect('clicked', info.eject.bind(info)); - this.actor.add_child(this._ejectButton); + this.add_child(this._ejectButton); } this._changedId = info.connect('changed', @@ -64,7 +65,7 @@ class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem { this._icon.gicon = info.icon; this._label.text = info.name; } -} +}); const SECTIONS = [ 'special', From 14859b400986ba4145e66ddda4d346e758076784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 29 May 2019 14:24:55 -0500 Subject: [PATCH 23/78] window-list: Pass the actor as PopupMenuManager owner PopupMenuManager's grabHelper starting from gnome-shell@7bb84da must be an actor, so pass it explicitly instead of expecting the shell to do it for us. This fixes an error during pushModal that was causing a grab not to be released. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/68 --- extensions/window-list/extension.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 637842e2..738da21d 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -221,7 +221,7 @@ class BaseButton { this.actor.connect('destroy', this._onDestroy.bind(this)); this.actor.connect('popup-menu', this._onPopupMenu.bind(this)); - this._contextMenuManager = new PopupMenu.PopupMenuManager(this); + this._contextMenuManager = new PopupMenu.PopupMenuManager(this.actor); this._switchWorkspaceId = global.window_manager.connect( 'switch-workspace', this._updateVisibility.bind(this)); @@ -481,7 +481,7 @@ class AppButton extends BaseButton { this._multiWindowTitle.add(label); this._multiWindowTitle.label_actor = label; - this._menuManager = new PopupMenu.PopupMenuManager(this); + this._menuManager = new PopupMenu.PopupMenuManager(this.actor); this._menu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.BOTTOM); this._menu.connect('open-state-changed', _onMenuStateChanged); this._menu.actor.hide(); @@ -809,7 +809,7 @@ class WindowList { this._updateWorkspaceIndicatorVisibility.bind(this)); this._updateWorkspaceIndicatorVisibility(); - this._menuManager = new PopupMenu.PopupMenuManager(this); + this._menuManager = new PopupMenu.PopupMenuManager(this.actor); this._menuManager.addMenu(this._workspaceIndicator.menu); Main.layoutManager.addChrome(this.actor, { From 829440f546f4f090d9f8f4eb0d1288358f76ff38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 24 Jun 2019 20:02:18 +0200 Subject: [PATCH 24/78] Update sass submodule --- data/gnome-shell-sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gnome-shell-sass b/data/gnome-shell-sass index 1a569565..c5df33dd 160000 --- a/data/gnome-shell-sass +++ b/data/gnome-shell-sass @@ -1 +1 @@ -Subproject commit 1a569565e6a53d912b3216c752d7fddfeaee70b5 +Subproject commit c5df33dda7a8d5ab2341950354f3e41eae3bac93 From b138e218bb5f215293d0b08bca1387fe92cc109f Mon Sep 17 00:00:00 2001 From: Jakub Steiner Date: Mon, 24 Jun 2019 20:28:03 +0200 Subject: [PATCH 25/78] classic: fix a broken build - redesign of the default theme nuked some local variables breaking the build. --- data/gnome-classic.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/gnome-classic.scss b/data/gnome-classic.scss index 9e23506a..410c5f03 100644 --- a/data/gnome-classic.scss +++ b/data/gnome-classic.scss @@ -60,9 +60,9 @@ $variant: 'light'; &.lock-screen, &.unlock-screen, &.login-screen { - background-color: transparentize($_bubble_bg_color, 0.5); - background-gradient-start: transparentize($_bubble_bg_color, 0.5); - background-gradient-end: transparentize($_bubble_bg_color, 0.5); + background-color: transparentize($bg_color, 0.5); + background-gradient-start: transparentize($bg_color, 0.5); + background-gradient-end: transparentize($bg_color, 0.5); border-bottom: none; .panel-button { color: $osd_fg_color; } } From 48ea80d391a71a0df38ddec095f1ae7826f8722b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 24 Jun 2019 20:03:35 +0200 Subject: [PATCH 26/78] Bump version to 3.33.3 Update NEWS. --- NEWS | 7 +++++++ meson.build | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e3f86f5e..bc707b51 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +3.33.3 +====== +* Misc. bug fixes [Florian, Marco; !67, !68] + +Contributors: + Florian Müllner, Marco Trevisan (Treviño) + 3.33.2 ====== * Misc. bug fixes and cleanups [Florian; !66] diff --git a/meson.build b/meson.build index 4fe9969e..1756face 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.33.2', + version: '3.33.3', meson_version: '>= 0.44.0', license: 'GPL2+' ) From dfeb99fc0a37051c33980b97a86c16f2ccdfa2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 27 Jun 2019 03:57:53 +0200 Subject: [PATCH 27/78] apps-menu: Add missing chain-up PanelMenu.Button is a bit weird in that it also "contains" its parent actor. That container is supposed to be destroyed with the button, but as we currently don't chain up to the parent class' _onDestroy(), we leave behind an empty container every time the extension is disabled. Fix this by adding the missing chain-up. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/75 --- extensions/apps-menu/extension.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index 7fada8e7..6828ebc7 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -463,6 +463,8 @@ class ApplicationsButton extends PanelMenu.Button { } _onDestroy() { + super._onDestroy(); + Main.overview.disconnect(this._showingId); Main.overview.disconnect(this._hidingId); appSys.disconnect(this._installedChangedId); From 2db4589dea3a5efe905c69401ec43c79e8429ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 28 Jun 2019 21:33:24 +0200 Subject: [PATCH 28/78] cleanup: Re-order imports They should be grouped between external (GI/gjs) and shell and in alphabetical order. Until commit bab4be1a ExtensionUtils was special as it was required for some imports, but that's no longer the case for most extensions. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/76 --- extensions/apps-menu/extension.js | 6 +++--- extensions/auto-move-windows/extension.js | 3 +-- extensions/drive-menu/extension.js | 3 +-- extensions/native-window-placement/extension.js | 3 +-- extensions/places-menu/extension.js | 2 +- extensions/screenshot-window-sizer/extension.js | 3 +-- extensions/user-theme/extension.js | 4 ++-- extensions/window-list/extension.js | 2 +- extensions/workspace-indicator/extension.js | 7 +++---- 9 files changed, 14 insertions(+), 19 deletions(-) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index 6828ebc7..685e885a 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -4,17 +4,17 @@ const { Atk, Clutter, Gio, GLib, GMenu, GObject, Gtk, Meta, Shell, St } = imports.gi; +const Signals = imports.signals; + const DND = imports.ui.dnd; +const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; -const Signals = imports.signals; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; -const ExtensionUtils = imports.misc.extensionUtils; - const appSys = Shell.AppSystem.get_default(); const APPLICATION_ICON_SIZE = 32; diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js index 07de0084..aec7bc33 100644 --- a/extensions/auto-move-windows/extension.js +++ b/extensions/auto-move-windows/extension.js @@ -4,9 +4,8 @@ const Shell = imports.gi.Shell; -const Main = imports.ui.main; - const ExtensionUtils = imports.misc.extensionUtils; +const Main = imports.ui.main; class WindowMover { constructor() { diff --git a/extensions/drive-menu/extension.js b/extensions/drive-menu/extension.js index 41e30a39..3b17f565 100644 --- a/extensions/drive-menu/extension.js +++ b/extensions/drive-menu/extension.js @@ -5,13 +5,12 @@ const { Gio, GObject, Shell, St } = imports.gi; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; +const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; const ShellMountOperation = imports.ui.shellMountOperation; -const ExtensionUtils = imports.misc.extensionUtils; - var MountMenuItem = GObject.registerClass( class MountMenuItem extends PopupMenu.PopupBaseMenuItem { _init(mount) { diff --git a/extensions/native-window-placement/extension.js b/extensions/native-window-placement/extension.js index 608c1f6a..04ad250d 100644 --- a/extensions/native-window-placement/extension.js +++ b/extensions/native-window-placement/extension.js @@ -1,8 +1,7 @@ // -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- /* exported enable disable */ -const Workspace = imports.ui.workspace; - const ExtensionUtils = imports.misc.extensionUtils; +const Workspace = imports.ui.workspace; // testing settings for natural window placement strategy: const WINDOW_PLACEMENT_NATURAL_ACCURACY = 20; // accuracy of window translate moves (KDE-default: 20) diff --git a/extensions/places-menu/extension.js b/extensions/places-menu/extension.js index 00aa04d9..76be8292 100644 --- a/extensions/places-menu/extension.js +++ b/extensions/places-menu/extension.js @@ -3,6 +3,7 @@ const { Clutter, GObject, St } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; @@ -11,7 +12,6 @@ const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; const N_ = x => x; -const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const PlaceDisplay = Me.imports.placeDisplay; diff --git a/extensions/screenshot-window-sizer/extension.js b/extensions/screenshot-window-sizer/extension.js index 4d21212a..2644ea31 100644 --- a/extensions/screenshot-window-sizer/extension.js +++ b/extensions/screenshot-window-sizer/extension.js @@ -21,11 +21,10 @@ const { Meta, Shell, St } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const Tweener = imports.ui.tweener; -const ExtensionUtils = imports.misc.extensionUtils; - const MESSAGE_FADE_TIME = 2; let text; diff --git a/extensions/user-theme/extension.js b/extensions/user-theme/extension.js index d00c0774..0c316844 100644 --- a/extensions/user-theme/extension.js +++ b/extensions/user-theme/extension.js @@ -3,12 +3,12 @@ /* exported init */ const { Gio, GLib } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const SETTINGS_KEY = 'name'; -const ExtensionUtils = imports.misc.extensionUtils; - class ThemeManager { constructor() { this._settings = ExtensionUtils.getSettings(); diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 738da21d..8a1d9563 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -2,11 +2,11 @@ const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi; const DND = imports.ui.dnd; +const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; -const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const Gettext = imports.gettext.domain('gnome-shell-extensions'); diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 7c81cd46..2c92a4da 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -2,16 +2,15 @@ /* exported init enable disable */ const { Clutter, Gio, GObject, Meta, St } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; -const Main = imports.ui.main; - -const ExtensionUtils = imports.misc.extensionUtils; - const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; const WORKSPACE_KEY = 'workspace-names'; From d1254d9b57c2521c5f68525b0b4d12a8060ce868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 10:17:20 +0000 Subject: [PATCH 29/78] places-menu: Don't hardcode position The extension currently assumes that we have the "Activities" button at the left of the top bar. This is currently true, not only in the regular session, but also in GNOME classic where the button is hidden (but still present). However this is about to change: We will stop taking over the button from the apps-menu extension, and instead disable "Activities" from the session mode definition. Prepare for this by adding the places menu before the application menu instead of assuming a hardcoded position. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69 --- extensions/places-menu/extension.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/places-menu/extension.js b/extensions/places-menu/extension.js index 76be8292..92c6d690 100644 --- a/extensions/places-menu/extension.js +++ b/extensions/places-menu/extension.js @@ -136,9 +136,9 @@ let _indicator; function enable() { _indicator = new PlacesMenu; - let pos = 1; + let pos = Main.sessionMode.panel.left.indexOf('appMenu'); if ('apps-menu' in Main.panel.statusArea) - pos = 2; + pos++; Main.panel.addToStatusArea('places-menu', _indicator, pos, 'left'); } From 6105eecff26030519dbcf22c7e6ff39aecd8dc87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 08:32:03 +0000 Subject: [PATCH 30/78] apps-menu: Stop taking over Activities button We don't want the "Activities" button in GNOME Classic, but the current way of handling it is confusing: - the button is hidden, but the corresponding hot corner sometimes works (when the application menu isn't open) - the button is effectively moved inside the menu, although it's clearly not an app or category - the apps-menu can be used independent from classic mode, in which case removing the "Activities" button may not be wanted Address those points by removing any handling of the activities button from the apps-menu extension. We will remove it again from the classic session via a session mode tweak. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69 --- extensions/apps-menu/extension.js | 59 ++----------------------------- 1 file changed, 2 insertions(+), 57 deletions(-) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index 685e885a..c4d62750 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -25,21 +25,6 @@ const NAVIGATION_REGION_OVERSHOOT = 50; Gio._promisify(Gio._LocalFilePrototype, 'query_info_async', 'query_info_finish'); Gio._promisify(Gio._LocalFilePrototype, 'set_attributes_async', 'set_attributes_finish'); -var ActivitiesMenuItem = GObject.registerClass( -class ActivitiesMenuItem extends PopupMenu.PopupBaseMenuItem { - _init(button) { - super._init(); - this._button = button; - this.add_child(new St.Label({ text: _('Activities Overview') })); - } - - activate(event) { - this._button.menu.toggle(); - Main.overview.toggle(); - super.activate(event); - } -}); - var ApplicationMenuItem = GObject.registerClass( class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem { _init(button, app) { @@ -233,21 +218,6 @@ class ApplicationsMenu extends PopupMenu.PopupMenu { return false; } - open(animate) { - this._button.hotCorner.setBarrierSize(0); - if (this._button.hotCorner.actor) // fallback corner - this._button.hotCorner.actor.hide(); - super.open(animate); - } - - close(animate) { - let size = Main.layoutManager.panelBox.height; - this._button.hotCorner.setBarrierSize(size); - if (this._button.hotCorner.actor) // fallback corner - this._button.hotCorner.actor.show(); - super.close(animate); - } - toggle() { if (this.isOpen) { this._button.selectCategory(null); @@ -406,8 +376,6 @@ class ApplicationsButton extends PanelMenu.Button { this.name = 'panelApplications'; this.label_actor = this._label; - this.connect('captured-event', this._onCapturedEvent.bind(this)); - this._showingId = Main.overview.connect('showing', () => { this.add_accessible_state (Atk.StateType.CHECKED); }); @@ -449,10 +417,6 @@ class ApplicationsButton extends PanelMenu.Button { } } - get hotCorner() { - return Main.layoutManager.hotCorners[Main.layoutManager.primaryIndex]; - } - _createVertSeparator() { let separator = new St.DrawingArea({ style_class: 'calendar-vertical-separator', @@ -480,14 +444,6 @@ class ApplicationsButton extends PanelMenu.Button { this._desktopTarget.destroy(); } - _onCapturedEvent(actor, event) { - if (event.type() == Clutter.EventType.BUTTON_PRESS) { - if (!Main.overview.shouldToggleByCornerOrButton()) - return true; - } - return false; - } - _onMenuKeyPress(actor, event) { let symbol = event.get_key_symbol(); if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) { @@ -630,14 +586,6 @@ class ApplicationsButton extends PanelMenu.Button { y_align: St.Align.START }); - let activities = new ActivitiesMenuItem(this); - this.leftBox.add(activities, { - expand: false, - x_fill: true, - y_fill: false, - y_align: St.Align.START - }); - this.applicationsBox = new St.BoxLayout({ vertical: true }); this.applicationsScrollBox.add_actor(this.applicationsBox); this.categoriesBox = new St.BoxLayout({ vertical: true }); @@ -749,19 +697,16 @@ class ApplicationsButton extends PanelMenu.Button { }); let appsMenuButton; -let activitiesButton; function enable() { - activitiesButton = Main.panel.statusArea['activities']; - activitiesButton.container.hide(); appsMenuButton = new ApplicationsButton(); - Main.panel.addToStatusArea('apps-menu', appsMenuButton, 1, 'left'); + let index = Main.sessionMode.panel.left.indexOf('activities') + 1; + Main.panel.addToStatusArea('apps-menu', appsMenuButton, index, 'left'); } function disable() { Main.panel.menuManager.removeMenu(appsMenuButton.menu); appsMenuButton.destroy(); - activitiesButton.container.show(); } function init() { From d99d0a06bd34d1845dd924ea8db8b454d37278b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 7 Jun 2019 14:30:16 +0000 Subject: [PATCH 31/78] apps-menu: Stop hiding the overview when toggled Now that the extension no longer doubles as the "Activities" button, that behavior is confusing. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69 --- extensions/apps-menu/extension.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index c4d62750..52c6839e 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -219,12 +219,8 @@ class ApplicationsMenu extends PopupMenu.PopupMenu { } toggle() { - if (this.isOpen) { + if (this.isOpen) this._button.selectCategory(null); - } else { - if (Main.overview.visible) - Main.overview.hide(); - } super.toggle(); } } From 545b811562e7cb2aa1e5f91f363b6e8655197e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 7 Jun 2019 20:07:19 +0000 Subject: [PATCH 32/78] apps-menu: Hide overview when launching app Now that we no longer hide the overview when the menu is opened, it is possible to activate menu entries from the overview. Start hiding the overview in that case, which is consistent with app launching elsewhere. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69 --- extensions/apps-menu/extension.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index 52c6839e..342049c4 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -67,6 +67,8 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem { this._button.selectCategory(null); this._button.menu.toggle(); super.activate(event); + + Main.overview.hide(); } setActive(active, params) { From 82d201106177837c706e98f8b33f528204b39fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 May 2019 09:44:30 +0000 Subject: [PATCH 33/78] classic: Disable overview The overview is one of the defining features of GNOME 3, and thus almost by definition at odds with the classic session, which emulates a traditional GNOME 2 desktop. Even with the less prominent placement inside the application menu it never quite fit in - it doesn't help that besides the different UI paradigma, the overview keeps its "normal" styling which differs greatly with classic's normal mode. So besides removing the "Activities" button via the session mode definition, now that the apps-menu extension doesn't replace it anymore, disable the overview completely in the classic session. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/69 --- data/classic.json.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/classic.json.in b/data/classic.json.in index fdb37626..c1c05442 100644 --- a/data/classic.json.in +++ b/data/classic.json.in @@ -1,8 +1,9 @@ { "parentMode": "user", "stylesheetName": "gnome-classic.css", + "hasOverview": false, "enabledExtensions": [@CLASSIC_EXTENSIONS@], - "panel": { "left": ["activities", "appMenu"], + "panel": { "left": ["appMenu"], "center": [], "right": ["a11y", "keyboard", "dateMenu", "aggregateMenu"] } From 92db87f7cbcee2b0a9ca592cf77b381313383f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 14 May 2019 19:51:22 +0200 Subject: [PATCH 34/78] window-list: Add window picker button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the latest changes, GNOME Classic has become so classic that it is bordering dull. Salvage at least a tiny piece of GNOME 3 in form of a window-pick button which toggles an exposé-like reduced overview. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/73 --- extensions/window-list/classic.css | 20 +- extensions/window-list/extension.js | 36 +++- extensions/window-list/meson.build | 2 +- extensions/window-list/stylesheet.css | 27 ++- extensions/window-list/windowPicker.js | 260 +++++++++++++++++++++++++ 5 files changed, 332 insertions(+), 13 deletions(-) create mode 100644 extensions/window-list/windowPicker.js diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css index f3c44a3d..c506bea2 100644 --- a/extensions/window-list/classic.css +++ b/extensions/window-list/classic.css @@ -6,14 +6,13 @@ height: 2.25em ; } - .bottom-panel .window-button > StWidget { + .bottom-panel .window-button > StWidget, + .bottom-panel .window-picker-toggle > StWidget { background-gradient-drection: vertical; background-color: #fff; background-gradient-start: #fff; background-gradient-end: #eee; color: #000; - -st-natural-width: 18.7em; - max-width: 18.75em; color: #2e3436; background-color: #eee; border-radius: 2px; @@ -22,7 +21,17 @@ text-shadow: 0 0 transparent; } - .bottom-panel .window-button:hover > StWidget { + .bottom-panel .window-button > StWidget { + -st-natural-width: 18.7em; + max-width: 18.75em; + } + + .bottom-panel .window-picker-toggle > StWidet { + border: 1px solid rgba(0,0,0,0.3); + } + + .bottom-panel .window-button:hover > StWidget, + .bottom-panel .window-picker-toggle:hover > StWidget { background-color: #f9f9f9; } @@ -31,7 +40,8 @@ box-shadow: inset 1px 1px 2px rgba(0,0,0,0.5); } - .bottom-panel .window-button.focused > StWidget { + .bottom-panel .window-button.focused > StWidget, + .bottom-panel .window-picker-toggle:checked > StWidget { background-color: #ddd; box-shadow: inset 1px 1px 1px rgba(0,0,0,0.5); } diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 8a1d9563..f749078f 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -4,10 +4,13 @@ const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi; const DND = imports.ui.dnd; const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; +const Overview = imports.ui.overview; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; +const Tweener = imports.ui.tweener; const Me = ExtensionUtils.getCurrentExtension(); +const { WindowPicker, WindowPickerToggle } = Me.imports.windowPicker; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; @@ -776,6 +779,12 @@ class WindowList { let box = new St.BoxLayout({ x_expand: true, y_expand: true }); this.actor.add_actor(box); + let toggle = new WindowPickerToggle(); + box.add_actor(toggle); + + toggle.connect('notify::checked', + this._updateWindowListVisibility.bind(this)); + let layout = new Clutter.BoxLayout({ homogeneous: true }); this._windowList = new St.Widget({ style_class: 'window-list', @@ -920,6 +929,19 @@ class WindowList { this._workspaceIndicator.visible = hasWorkspaces && workspacesOnMonitor; } + _updateWindowListVisibility() { + let visible = !Main.windowPicker.visible; + + Tweener.addTween(this._windowList, { + opacity: visible ? 255 : 0, + transition: 'ease-out-quad', + time: Overview.ANIMATION_TIME + }); + + this._windowList.reactive = visible; + this._windowList.get_children().forEach(c => c.reactive = visible); + } + _getPreferredUngroupedWindowListWidth() { if (this._windowList.get_n_children() == 0) return this._windowList.get_preferred_width(-1)[1]; @@ -1187,7 +1209,7 @@ class WindowList { class Extension { constructor() { this._windowLists = null; - this._injections = {}; + this._hideOverviewOrig = Main.overview.hide; } enable() { @@ -1200,6 +1222,13 @@ class Extension { this._monitorsChangedId = Main.layoutManager.connect( 'monitors-changed', this._buildWindowLists.bind(this)); + Main.windowPicker = new WindowPicker(); + + Main.overview.hide = () => { + Main.windowPicker.close(); + this._hideOverviewOrig.call(Main.overview); + }; + this._buildWindowLists(); } @@ -1230,6 +1259,11 @@ class Extension { windowList.actor.destroy(); }); this._windowLists = null; + + Main.windowPicker.actor.destroy(); + delete Main.windowPicker; + + Main.overview.hide = this._hideOverviewOrig; } someWindowListContains(actor) { diff --git a/extensions/window-list/meson.build b/extensions/window-list/meson.build index b4aa4dba..5b1f5f51 100644 --- a/extensions/window-list/meson.build +++ b/extensions/window-list/meson.build @@ -4,7 +4,7 @@ extension_data += configure_file( configuration: metadata_conf ) -extension_sources += files('prefs.js') +extension_sources += files('prefs.js', 'windowPicker.js') extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml') if classic_mode_enabled diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css index f5285cb3..91383ab6 100644 --- a/extensions/window-list/stylesheet.css +++ b/extensions/window-list/stylesheet.css @@ -26,9 +26,8 @@ spacing: 4px; } -.window-button > StWidget { - -st-natural-width: 18.75em; - max-width: 18.75em; +.window-button > StWidget, +.window-picker-toggle > StWidget { color: #bbb; background-color: black; border-radius: 4px; @@ -37,7 +36,21 @@ text-shadow: 1px 1px 4px rgba(0,0,0,0.8); } -.window-button:hover > StWidget { +.window-picker-toggle { + padding: 3px; +} + +.window-picker-toggle > StWidet { + border: 1px solid rgba(255,255,255,0.3); +} + +.window-button > StWidget { + -st-natural-width: 18.75em; + max-width: 18.75em; +} + +.window-button:hover > StWidget, +.window-picker-toggle:hover > StWidget { color: white; background-color: #1f1f1f; } @@ -47,12 +60,14 @@ box-shadow: inset 2px 2px 4px rgba(255,255,255,0.5); } -.window-button.focused > StWidget { +.window-button.focused > StWidget, +.window-picker-toggle:checked > StWidget { color: white; box-shadow: inset 1px 1px 4px rgba(255,255,255,0.7); } -.window-button.focused:active > StWidget { +.window-button.focused:active > StWidget, +.window-picker-toggle:checked:active > StWidget { box-shadow: inset 2px 2px 4px rgba(255,255,255,0.7); } diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js new file mode 100644 index 00000000..024fd802 --- /dev/null +++ b/extensions/window-list/windowPicker.js @@ -0,0 +1,260 @@ +/* exported WindowPicker, WindowPickerToggle */ +const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; +const Signals = imports.signals; + +const Layout = imports.ui.layout; +const Main = imports.ui.main; +const Overview = imports.ui.overview; +const { WorkspacesDisplay } = imports.ui.workspacesView; + +let MyWorkspacesDisplay = class extends WorkspacesDisplay { + constructor() { + super(); + + this.actor.add_constraint( + new Layout.MonitorConstraint({ + primary: true, + work_area: true + })); + + this.actor.connect('destroy', this._onDestroy.bind(this)); + + this._workareasChangedId = global.display.connect('workareas-changed', + this._onWorkAreasChanged.bind(this)); + this._onWorkAreasChanged(); + } + + show(...args) { + if (this._scrollEventId == 0) + this._scrollEventId = Main.windowPicker.connect('scroll-event', + this._onScrollEvent.bind(this)); + + super.show(...args); + } + + hide(...args) { + if (this._scrollEventId > 0) + Main.windowPicker.disconnect(this._scrollEventId); + this._scrollEventId = 0; + + super.hide(...args); + } + + _onWorkAreasChanged() { + let { primaryIndex } = Main.layoutManager; + let workarea = Main.layoutManager.getWorkAreaForMonitor(primaryIndex); + this.setWorkspacesFullGeometry(workarea); + } + + _updateWorkspacesViews() { + super._updateWorkspacesViews(); + + this._workspacesViews.forEach(v => { + Main.layoutManager.overviewGroup.remove_actor(v.actor); + Main.windowPicker.actor.add_actor(v.actor); + }); + } + + _onDestroy() { + if (this._workareasChangedId) + global.display.disconnect(this._workareasChangedId); + this._workareasChangedId = 0; + } +}; + +var WindowPicker = class { + constructor() { + this._visible = false; + this._modal = false; + + this.actor = new Clutter.Actor(); + + this.actor.connect('destroy', this._onDestroy.bind(this)); + + global.bind_property('screen-width', + this.actor, 'width', + GObject.BindingFlags.SYNC_CREATE); + global.bind_property('screen-height', + this.actor, 'height', + GObject.BindingFlags.SYNC_CREATE); + + this._backgroundGroup = new Meta.BackgroundGroup({ reactive: true }); + this.actor.add_child(this._backgroundGroup); + + this._backgroundGroup.connect('scroll-event', (a, ev) => { + this.emit('scroll-event', ev); + }); + + // Trick WorkspacesDisplay constructor into adding actions here + let addActionOrig = Main.overview.addAction; + Main.overview.addAction = a => this._backgroundGroup.add_action(a); + + this._workspacesDisplay = new MyWorkspacesDisplay(); + this.actor.add_child(this._workspacesDisplay.actor); + + Main.overview.addAction = addActionOrig; + + this._bgManagers = []; + + this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', + this._updateBackgrounds.bind(this)); + this._updateBackgrounds(); + + Main.uiGroup.insert_child_below(this.actor, global.window_group); + } + + get visible() { + return this._visible; + } + + open() { + if (this._visible) + return; + + this._visible = true; + + if (!this._syncGrab()) + return; + + this._fakeOverviewVisible(true); + this._shadeBackgrounds(); + this._fakeOverviewAnimation(); + this._workspacesDisplay.show(false); + + this.emit('open-state-changed', this._visible); + } + + close() { + if (!this._visible) + return; + + this._visible = false; + + if (!this._syncGrab()) + return; + + this._workspacesDisplay.animateFromOverview(false); + this._unshadeBackgrounds(); + this._fakeOverviewAnimation(() => { + this._workspacesDisplay.hide(); + this._fakeOverviewVisible(false); + }); + + this.emit('open-state-changed', this._visible); + } + + _fakeOverviewAnimation(onComplete) { + Main.overview.animationInProgress = true; + GLib.timeout_add( + GLib.PRIORITY_DEFAULT, + Overview.ANIMATION_TIME * 1000, + () => { + Main.overview.animationInProgress = false; + if (onComplete) + onComplete(); + }); + } + + _fakeOverviewVisible(visible) { + // Fake overview state for WorkspacesDisplay + Main.overview.visible = visible; + + // Hide real windows + Main.layoutManager._inOverview = visible; + Main.layoutManager._updateVisibility(); + } + + _syncGrab() { + if (this._visible) { + if (this._modal) + return true; + + this._modal = Main.pushModal(this.actor, { + actionMode: Shell.ActionMode.OVERVIEW + }); + + if (!this._modal) { + this.hide(); + return false; + } + } else if (this._modal) { + Main.popModal(this.actor); + this._modal = false; + } + return true; + } + + _onDestroy() { + if (this._monitorsChangedId) + Main.layoutManager.disconnect(this._monitorsChangedId); + this._monitorsChangedId = 0; + } + + _updateBackgrounds() { + Main.overview._updateBackgrounds.call(this); + } + + _shadeBackgrounds() { + Main.overview._shadeBackgrounds.call(this); + } + + _unshadeBackgrounds() { + Main.overview._unshadeBackgrounds.call(this); + } +}; +Signals.addSignalMethods(WindowPicker.prototype); + +var WindowPickerToggle = GObject.registerClass( +class WindowPickerToggle extends St.Button { + _init() { + let iconBin = new St.Widget({ + layout_manager: new Clutter.BinLayout() + }); + iconBin.add_child(new St.Icon({ + icon_name: 'focus-windows-symbolic', + icon_size: 16, + x_expand: true, + y_expand: true, + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER + })); + super._init({ + style_class: 'window-picker-toggle', + child: iconBin, + visible: !Main.sessionMode.hasOverview, + x_fill: true, + y_fill: true, + toggle_mode: true + }); + + this._overlayKeyId = 0; + + this.connect('destroy', this._onDestroy.bind(this)); + + this.connect('notify::checked', () => { + if (this.checked) + Main.windowPicker.open(); + else + Main.windowPicker.close(); + }); + + if (!Main.sessionMode.hasOverview) { + this._overlayKeyId = global.display.connect('overlay-key', () => { + if (!Main.windowPicker.visible) + Main.windowPicker.open(); + else + Main.windowPicker.close(); + }); + } + + Main.windowPicker.connect('open-state-changed', () => { + this.checked = Main.windowPicker.visible; + }); + } + + _onDestroy() { + if (this._overlayKeyId) + global.display.disconnect(this._overlayKeyId); + this._overlayKeyId == 0; + } +}); From 2ef6dba0a58c24c80eea26d4d72ec2f8dbb54c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 29 Jun 2019 02:52:45 +0200 Subject: [PATCH 35/78] window-list: Fix resetting handler ID This is embarrassing, although destroy() is expected to only run once, so the bug shouldn't have an effect in practice. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/78 --- extensions/window-list/windowPicker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js index 024fd802..cd0644d7 100644 --- a/extensions/window-list/windowPicker.js +++ b/extensions/window-list/windowPicker.js @@ -255,6 +255,6 @@ class WindowPickerToggle extends St.Button { _onDestroy() { if (this._overlayKeyId) global.display.disconnect(this._overlayKeyId); - this._overlayKeyId == 0; + this._overlayKeyId = 0; } }); From dc3523a3447956e1fce453d2559dfe3c431d769f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 29 Jun 2019 00:38:54 +0200 Subject: [PATCH 36/78] lint: Remove misleading globals While those are defined by gnome-shell, we generally want to define our own with the correct gettext domain. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/79 --- lint/eslintrc-shell.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lint/eslintrc-shell.json b/lint/eslintrc-shell.json index fc6f5819..b7bef50a 100644 --- a/lint/eslintrc-shell.json +++ b/lint/eslintrc-shell.json @@ -21,10 +21,6 @@ "prefer-arrow-callback": "error" }, "globals": { - "global": false, - "_": false, - "C_": false, - "N_": false, - "ngettext": false + "global": false } } From 6a25971366c2588c353f5bb4238e2abe5b985b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 2 Jul 2019 02:39:17 +0200 Subject: [PATCH 37/78] lint: Also allow camelcase for default signal handlers on_some_signal() is used less than vfunc_some_method(), but it can still be useful. --- lint/eslintrc-shell.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lint/eslintrc-shell.json b/lint/eslintrc-shell.json index b7bef50a..c7be5981 100644 --- a/lint/eslintrc-shell.json +++ b/lint/eslintrc-shell.json @@ -4,7 +4,7 @@ "error", { "properties": "never", - "allow": ["^vfunc_"] + "allow": ["^vfunc_", "^on_"] } ], "no-unused-vars": [ From 6c49ca825c12e3c050719730652ea96bbce5d2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 2 Jul 2019 17:39:55 +0200 Subject: [PATCH 38/78] window-list: Move super-key handling into WindowPicker We have an option to put a window list on each monitor, so we may have more than one window picker toggle. We don't want each of those try to toggle the window picker simultanuously, so move handling of the super key directly into the picker. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/80 --- extensions/window-list/windowPicker.js | 34 ++++++++++++-------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js index cd0644d7..ba0a6973 100644 --- a/extensions/window-list/windowPicker.js +++ b/extensions/window-list/windowPicker.js @@ -67,6 +67,8 @@ var WindowPicker = class { this._visible = false; this._modal = false; + this._overlayKeyId = 0; + this.actor = new Clutter.Actor(); this.actor.connect('destroy', this._onDestroy.bind(this)); @@ -101,6 +103,15 @@ var WindowPicker = class { this._updateBackgrounds(); Main.uiGroup.insert_child_below(this.actor, global.window_group); + + if (!Main.sessionMode.hasOverview) { + this._overlayKeyId = global.display.connect('overlay-key', () => { + if (!this._visible) + this.open(); + else + this.close(); + }); + } } get visible() { @@ -188,6 +199,10 @@ var WindowPicker = class { if (this._monitorsChangedId) Main.layoutManager.disconnect(this._monitorsChangedId); this._monitorsChangedId = 0; + + if (this._overlayKeyId) + global.display.disconnect(this._overlayKeyId); + this._overlayKeyId = 0; } _updateBackgrounds() { @@ -227,10 +242,6 @@ class WindowPickerToggle extends St.Button { toggle_mode: true }); - this._overlayKeyId = 0; - - this.connect('destroy', this._onDestroy.bind(this)); - this.connect('notify::checked', () => { if (this.checked) Main.windowPicker.open(); @@ -238,23 +249,8 @@ class WindowPickerToggle extends St.Button { Main.windowPicker.close(); }); - if (!Main.sessionMode.hasOverview) { - this._overlayKeyId = global.display.connect('overlay-key', () => { - if (!Main.windowPicker.visible) - Main.windowPicker.open(); - else - Main.windowPicker.close(); - }); - } - Main.windowPicker.connect('open-state-changed', () => { this.checked = Main.windowPicker.visible; }); } - - _onDestroy() { - if (this._overlayKeyId) - global.display.disconnect(this._overlayKeyId); - this._overlayKeyId = 0; - } }); From f2b261c5736e4a519e46b8ea2472756f028d9fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 2 Jul 2019 18:12:31 +0200 Subject: [PATCH 39/78] window-list: Handle closing window picker with Escape Just like the overview can be closed with Escape, it makes sense to allow the same for the window picker (in addition to pressing super repeatedly). https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/80 --- extensions/window-list/windowPicker.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js index ba0a6973..12a7627f 100644 --- a/extensions/window-list/windowPicker.js +++ b/extensions/window-list/windowPicker.js @@ -68,6 +68,7 @@ var WindowPicker = class { this._modal = false; this._overlayKeyId = 0; + this._stageKeyPressId = 0; this.actor = new Clutter.Actor(); @@ -132,6 +133,16 @@ var WindowPicker = class { this._fakeOverviewAnimation(); this._workspacesDisplay.show(false); + this._stageKeyPressId = global.stage.connect('key-press-event', + (a, event) => { + let sym = event.get_key_symbol(); + if (sym == Clutter.KEY_Escape) { + this.close(); + return Clutter.EVENT_STOP; + } + return Clutter.EVENT_PROPAGATE; + }); + this.emit('open-state-changed', this._visible); } @@ -151,6 +162,9 @@ var WindowPicker = class { this._fakeOverviewVisible(false); }); + global.stage.disconnect(this._stageKeyPressId); + this._stageKeyPressId = 0; + this.emit('open-state-changed', this._visible); } @@ -203,6 +217,10 @@ var WindowPicker = class { if (this._overlayKeyId) global.display.disconnect(this._overlayKeyId); this._overlayKeyId = 0; + + if (this._stageKeyPressId) + global.stage.disconnect(this._stageKeyPressId); + this._stageKeyPressId = 0; } _updateBackgrounds() { From 80eb29bd51cb31c7bcf73143c918024a3f0b5241 Mon Sep 17 00:00:00 2001 From: Jor Teron Date: Sun, 14 Jul 2019 04:30:50 +0000 Subject: [PATCH 40/78] Add Karbi translation --- po/LINGUAS | 1 + po/mjw.po | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 po/mjw.po diff --git a/po/LINGUAS b/po/LINGUAS index 514d53e4..a6ab394e 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -38,6 +38,7 @@ kn ko lt lv +mjw ml mr ms diff --git a/po/mjw.po b/po/mjw.po new file mode 100644 index 00000000..c9ee24c5 --- /dev/null +++ b/po/mjw.po @@ -0,0 +1,249 @@ +# Karbi (India) translation for gnome-shell-extensions. +# Copyright (C) 2019 gnome-shell-extensions's Free Software Foundation, Inc. +# This file is distributed under the same license as the gnome-shell-extensions package. +# Jor Teron , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: gnome-shell-extensions master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/" +"issues\n" +"POT-Creation-Date: 2019-07-02 19:23+0000\n" +"PO-Revision-Date: 2019-07-14 00:00+0530\n" +"Last-Translator: Jor Teron \n" +"Language-Team: Karbi \n" +"Language: mjw\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: gedit 3.28.1\n" + +#: data/gnome-classic.desktop.in:3 data/gnome-classic.session.desktop.in:3 +msgid "GNOME Classic" +msgstr "GNOME Classic" + +#: data/gnome-classic.desktop.in:4 +msgid "This session logs you into GNOME Classic" +msgstr "" + +#: extensions/apps-menu/extension.js:111 +msgid "Favorites" +msgstr "" + +#: extensions/apps-menu/extension.js:366 +msgid "Applications" +msgstr "" + +#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:6 +msgid "Application and workspace list" +msgstr "" + +#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:7 +msgid "" +"A list of strings, each containing an application id (desktop file name), " +"followed by a colon and the workspace number" +msgstr "" + +#: extensions/auto-move-windows/prefs.js:60 +msgid "Application" +msgstr "" + +#: extensions/auto-move-windows/prefs.js:71 +#: extensions/auto-move-windows/prefs.js:134 +msgid "Workspace" +msgstr "" + +#: extensions/auto-move-windows/prefs.js:89 +msgid "Add Rule" +msgstr "" + +#: extensions/auto-move-windows/prefs.js:111 +msgid "Create new matching rule" +msgstr "" + +#: extensions/auto-move-windows/prefs.js:117 +msgid "Add" +msgstr "" + +#. TRANSLATORS: %s is the filesystem name +#: extensions/drive-menu/extension.js:102 +#: extensions/places-menu/placeDisplay.js:232 +#, javascript-format +msgid "Ejecting drive “%s” failed:" +msgstr "" + +#: extensions/drive-menu/extension.js:118 +msgid "Removable devices" +msgstr "" + +#: extensions/drive-menu/extension.js:145 +msgid "Open Files" +msgstr "Files kangpu" + +#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:5 +msgid "Use more screen for windows" +msgstr "" + +#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:6 +msgid "" +"Try to use more screen for placing window thumbnails by adapting to screen " +"aspect ratio, and consolidating them further to reduce the bounding box. " +"This setting applies only with the natural placement strategy." +msgstr "" + +#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:11 +msgid "Place window captions on top" +msgstr "" + +#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:12 +msgid "" +"If true, place window captions on top the respective thumbnail, overriding " +"shell default of placing it at the bottom. Changing this setting requires " +"restarting the shell to have any effect." +msgstr "" + +#: extensions/places-menu/extension.js:80 +#: extensions/places-menu/extension.js:84 +msgid "Places" +msgstr "" + +#: extensions/places-menu/placeDisplay.js:46 +#, javascript-format +msgid "Failed to launch “%s”" +msgstr "" + +#: extensions/places-menu/placeDisplay.js:61 +#, javascript-format +msgid "Failed to mount volume for “%s”" +msgstr "" + +#: extensions/places-menu/placeDisplay.js:148 +#: extensions/places-menu/placeDisplay.js:171 +msgid "Computer" +msgstr "Computer" + +#: extensions/places-menu/placeDisplay.js:358 +msgid "Home" +msgstr "Home" + +#: extensions/places-menu/placeDisplay.js:403 +msgid "Browse Network" +msgstr "" + +#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:7 +msgid "Cycle Screenshot Sizes" +msgstr "" + +#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:11 +msgid "Cycle Screenshot Sizes Backward" +msgstr "" + +#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:5 +msgid "Theme name" +msgstr "Theme amen" + +#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:6 +msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell" +msgstr "Theme amem, kewan ji pen ~/.themes/name/gnome-shell" + +#: extensions/window-list/extension.js:99 +msgid "Close" +msgstr "Kanghap" + +#: extensions/window-list/extension.js:119 +msgid "Unminimize" +msgstr "Pabi-thuthe" + +#: extensions/window-list/extension.js:119 +msgid "Minimize" +msgstr "Pabi" + +#: extensions/window-list/extension.js:126 +msgid "Unmaximize" +msgstr "Pathe-thuthe" + +#: extensions/window-list/extension.js:126 +msgid "Maximize" +msgstr "Pathe" + +#: extensions/window-list/extension.js:399 +msgid "Minimize all" +msgstr "Kado-kawe pabi" + +#: extensions/window-list/extension.js:405 +msgid "Unminimize all" +msgstr "Kado-kawe pabi-thuthe" + +#: extensions/window-list/extension.js:411 +msgid "Maximize all" +msgstr "Kathe-kawe pathe" + +#: extensions/window-list/extension.js:419 +msgid "Unmaximize all" +msgstr "Kado-kawe pathe-thuthe" + +#: extensions/window-list/extension.js:427 +msgid "Close all" +msgstr "Kado-kawe kanghap" + +#: extensions/window-list/extension.js:642 +#: extensions/workspace-indicator/extension.js:20 +msgid "Workspace Indicator" +msgstr "" + +#: extensions/window-list/extension.js:829 +msgid "Window List" +msgstr "" + +#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:12 +msgid "When to group windows" +msgstr "Mentu hutsi windows muluk nangji" + +#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:13 +msgid "" +"Decides when to group windows from the same application on the window list. " +"Possible values are “never”, “auto” and “always”." +msgstr "" + +#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20 +msgid "Show the window list on all monitors" +msgstr "" + +#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:21 +msgid "" +"Whether to show the window list on all connected monitors or only on the " +"primary one." +msgstr "" + +#: extensions/window-list/prefs.js:25 +msgid "Window Grouping" +msgstr "Windows muluk" + +#: extensions/window-list/prefs.js:47 +msgid "Never group windows" +msgstr "Windows muluk ri" + +#: extensions/window-list/prefs.js:48 +msgid "Group windows when space is limited" +msgstr "Adim bihek te windows muluk noi" + +#: extensions/window-list/prefs.js:49 +msgid "Always group windows" +msgstr "Windows muluk vek nangji" + +#: extensions/window-list/prefs.js:75 +msgid "Show on all monitors" +msgstr "" + +#: extensions/workspace-indicator/prefs.js:131 +msgid "Workspace Names" +msgstr "Workspace amen hai" + +#: extensions/workspace-indicator/prefs.js:151 +msgid "Name" +msgstr "Amen" + +#: extensions/workspace-indicator/prefs.js:191 +#, javascript-format +msgid "Workspace %d" +msgstr "Workspace amen %d" From 167f0be6b4ed3500051cbade553038bb9ae5c363 Mon Sep 17 00:00:00 2001 From: Jor Teron Date: Tue, 16 Jul 2019 02:51:57 +0000 Subject: [PATCH 41/78] Update Karbi translation --- po/mjw.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/po/mjw.po b/po/mjw.po index c9ee24c5..0bb0df8e 100644 --- a/po/mjw.po +++ b/po/mjw.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: gnome-shell-extensions master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/" "issues\n" -"POT-Creation-Date: 2019-07-02 19:23+0000\n" -"PO-Revision-Date: 2019-07-14 00:00+0530\n" +"POT-Creation-Date: 2019-07-14 04:31+0000\n" +"PO-Revision-Date: 2019-07-16 08:19+0530\n" "Last-Translator: Jor Teron \n" "Language-Team: Karbi \n" "Language: mjw\n" @@ -105,12 +105,12 @@ msgstr "" #: extensions/places-menu/extension.js:80 #: extensions/places-menu/extension.js:84 msgid "Places" -msgstr "" +msgstr "Places" #: extensions/places-menu/placeDisplay.js:46 #, javascript-format msgid "Failed to launch “%s”" -msgstr "" +msgstr "“%s” ingpu un-eh" #: extensions/places-menu/placeDisplay.js:61 #, javascript-format @@ -217,7 +217,7 @@ msgstr "" #: extensions/window-list/prefs.js:25 msgid "Window Grouping" -msgstr "Windows muluk" +msgstr "Window muluk" #: extensions/window-list/prefs.js:47 msgid "Never group windows" From 56e2a570e38f6a580846ebfc1da6728fae964c85 Mon Sep 17 00:00:00 2001 From: Jakub Steiner Date: Mon, 15 Jul 2019 23:40:09 +0200 Subject: [PATCH 42/78] classic: hover state for panel buttons - prelight before active - lighten up slightly, similar to what the default does (inverted) Fixes https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/169 --- data/gnome-classic.scss | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/data/gnome-classic.scss b/data/gnome-classic.scss index 410c5f03..5b29df1b 100644 --- a/data/gnome-classic.scss +++ b/data/gnome-classic.scss @@ -32,18 +32,20 @@ $variant: 'light'; font-weight: normal; color: $fg_color; text-shadow: none; - &:active, &:overview, &:focus, &:checked { - // Trick due to St limitations. It needs a background to draw - // a box-shadow - background-color: $selected_bg_color !important; - color: $selected_fg_color !important; - box-shadow: none; - & > .system-status-icon { icon-shadow: none; } - } &:hover { + color: lighten($fg_color,10%); text-shadow: none; & .system-status-icon { icon-shadow: none; } } + &:active, &:overview, &:focus, &:checked { + // Trick due to St limitations. It needs a background to draw + // a box-shadow + background-color: $selected_bg_color; + color: $selected_fg_color; + box-shadow: none; + & > .system-status-icon { icon-shadow: none; } + } + .app-menu-icon { width: 0; height: 0; margin: 0; } // shell's display:none; :D .system-status-icon { From 3fa750ce1745badefd0f04cebd5ac99c80a4c22c Mon Sep 17 00:00:00 2001 From: Jakub Steiner Date: Wed, 3 Jul 2019 14:58:53 +0200 Subject: [PATCH 43/78] classic: No special casing of notifications The default already handles light variant. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/82 --- data/gnome-classic.scss | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/data/gnome-classic.scss b/data/gnome-classic.scss index 5b29df1b..edf24d66 100644 --- a/data/gnome-classic.scss +++ b/data/gnome-classic.scss @@ -93,15 +93,3 @@ $variant: 'light'; background-image: url("calendar-today.svg"); } -.message-list-clear-button.button { - color: $fg_color -} - -.notification-banner { - background-color: $bg_color !important; - color: $fg_color; - .notification-button { - background-color: darken($bg_color,5%); - &:hover, &focus { background-color: darken($bg_color,2%); } - } -} From ae1b17d29c2e20eebddabd3cabad335e0093dba4 Mon Sep 17 00:00:00 2001 From: Jakub Steiner Date: Mon, 15 Jul 2019 23:03:41 +0200 Subject: [PATCH 44/78] classic: Update window-list styling Make buttons flatter, rounder to match default styling. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/82 --- extensions/window-list/classic.css | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css index c506bea2..cc967e07 100644 --- a/extensions/window-list/classic.css +++ b/extensions/window-list/classic.css @@ -4,21 +4,18 @@ border-top-width: 1px; border-bottom-width: 0px; height: 2.25em ; + padding: 2px; } .bottom-panel .window-button > StWidget, .bottom-panel .window-picker-toggle > StWidget { - background-gradient-drection: vertical; - background-color: #fff; - background-gradient-start: #fff; - background-gradient-end: #eee; - color: #000; color: #2e3436; background-color: #eee; - border-radius: 2px; + border-radius: 3px; padding: 3px 6px 1px; - box-shadow: inset -1px -1px 1px rgba(0,0,0,0.5); - text-shadow: 0 0 transparent; + box-shadow: none; + text-shadow: none; + border: 1px solid rgba(0,0,0,0.2); } .bottom-panel .window-button > StWidget { @@ -26,10 +23,6 @@ max-width: 18.75em; } - .bottom-panel .window-picker-toggle > StWidet { - border: 1px solid rgba(0,0,0,0.3); - } - .bottom-panel .window-button:hover > StWidget, .bottom-panel .window-picker-toggle:hover > StWidget { background-color: #f9f9f9; @@ -37,13 +30,13 @@ .bottom-panel .window-button:active > StWidget, .bottom-panel .window-button:focus > StWidget { - box-shadow: inset 1px 1px 2px rgba(0,0,0,0.5); + box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); } .bottom-panel .window-button.focused > StWidget, .bottom-panel .window-picker-toggle:checked > StWidget { - background-color: #ddd; - box-shadow: inset 1px 1px 1px rgba(0,0,0,0.5); + background-color: #ccc; + box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); } .bottom-panel .window-button.focused:hover > StWidget { @@ -52,5 +45,5 @@ .bottom-panel .window-button.minimized > StWidget { color: #888; - box-shadow: inset -1px -1px 1px rgba(0,0,0,0.5); + box-shadow: none; } From 1f6f22010ed583dc3ce07e8ca8ef67e6d814f66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 18 Jul 2019 12:23:53 +0200 Subject: [PATCH 45/78] Update sass submodule --- data/gnome-shell-sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gnome-shell-sass b/data/gnome-shell-sass index c5df33dd..8a1f4ee7 160000 --- a/data/gnome-shell-sass +++ b/data/gnome-shell-sass @@ -1 +1 @@ -Subproject commit c5df33dda7a8d5ab2341950354f3e41eae3bac93 +Subproject commit 8a1f4ee7e571f3763f88e19c37c240be5eef2c12 From 0469fc6aa960f6d0c17d37daa2d839da4b8062e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 18 Jul 2019 12:31:58 +0200 Subject: [PATCH 46/78] Update sass submodule (again) --- data/gnome-shell-sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gnome-shell-sass b/data/gnome-shell-sass index 8a1f4ee7..478d47a1 160000 --- a/data/gnome-shell-sass +++ b/data/gnome-shell-sass @@ -1 +1 @@ -Subproject commit 8a1f4ee7e571f3763f88e19c37c240be5eef2c12 +Subproject commit 478d47a177b4a55f4805e737436b6ae427238b5c From 6eb3a62e2b307d0b8d3175238d88c4b12e15913b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 18 Jul 2019 00:39:49 +0200 Subject: [PATCH 47/78] apps-menu: Add drop-shadow to application icons ... to make sure they are readable on light backgrounds. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/168 --- extensions/apps-menu/extension.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js index 342049c4..9667d3f2 100644 --- a/extensions/apps-menu/extension.js +++ b/extensions/apps-menu/extension.js @@ -90,7 +90,9 @@ class ApplicationMenuItem extends PopupMenu.PopupBaseMenuItem { } _updateIcon() { - this._iconBin.set_child(this.getDragActor()); + let icon = this.getDragActor(); + icon.style_class = 'icon-dropshadow'; + this._iconBin.set_child(icon); } }); From 4b9c53ff2ec3c57525a104642bfeafdb21592d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 00:23:13 +0000 Subject: [PATCH 48/78] window-list: Split out workspaceIndicator The extension has grown unwieldily big, so before starting to improve on the workspace indicator, move it to its own source file. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/extension.js | 130 +----------------- extensions/window-list/meson.build | 2 +- extensions/window-list/workspaceIndicator.js | 135 +++++++++++++++++++ 3 files changed, 138 insertions(+), 129 deletions(-) create mode 100644 extensions/window-list/workspaceIndicator.js diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index f749078f..6af96344 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -1,16 +1,16 @@ /* exported init */ -const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi; +const { Clutter, Gio, GLib, Gtk, Meta, Shell, St } = imports.gi; const DND = imports.ui.dnd; const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const Overview = imports.ui.overview; -const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; const Tweener = imports.ui.tweener; const Me = ExtensionUtils.getCurrentExtension(); const { WindowPicker, WindowPickerToggle } = Me.imports.windowPicker; +const { WorkspaceIndicator } = Me.imports.workspaceIndicator; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; @@ -636,132 +636,6 @@ class AppButton extends BaseButton { } -let WorkspaceIndicator = GObject.registerClass( -class WorkspaceIndicator extends PanelMenu.Button { - _init() { - super._init(0.0, _('Workspace Indicator'), true); - this.setMenu(new PopupMenu.PopupMenu(this, 0.0, St.Side.BOTTOM)); - this.add_style_class_name('window-list-workspace-indicator'); - this.menu.actor.remove_style_class_name('panel-menu'); - - let container = new St.Widget({ - layout_manager: new Clutter.BinLayout(), - x_expand: true, - y_expand: true - }); - this.add_actor(container); - - let workspaceManager = global.workspace_manager; - - this._currentWorkspace = workspaceManager.get_active_workspace().index(); - this.statusLabel = new St.Label({ - text: this._getStatusText(), - x_align: Clutter.ActorAlign.CENTER, - y_align: Clutter.ActorAlign.CENTER - }); - container.add_actor(this.statusLabel); - - this.workspacesItems = []; - - this._workspaceManagerSignals = [ - workspaceManager.connect('notify::n-workspaces', - this._updateMenu.bind(this)), - workspaceManager.connect_after('workspace-switched', - this._updateIndicator.bind(this)) - ]; - - this.connect('scroll-event', this._onScrollEvent.bind(this)); - this._updateMenu(); - - this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' }); - this._settingsChangedId = this._settings.connect( - 'changed::workspace-names', this._updateMenu.bind(this)); - } - - _onDestroy() { - for (let i = 0; i < this._workspaceManagerSignals.length; i++) - global.workspace_manager.disconnect(this._workspaceManagerSignals[i]); - - if (this._settingsChangedId) { - this._settings.disconnect(this._settingsChangedId); - this._settingsChangedId = 0; - } - - super._onDestroy(); - } - - _updateIndicator() { - this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); - this._currentWorkspace = global.workspace_manager.get_active_workspace().index(); - this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); - - this.statusLabel.set_text(this._getStatusText()); - } - - _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); - } - - _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', (item, _event) => { - this._activate(item.workspaceId); - }); - - if (i == this._currentWorkspace) - item.setOrnament(PopupMenu.Ornament.DOT); - - this.menu.addMenuItem(item); - this.workspacesItems[i] = item; - } - - this.statusLabel.set_text(this._getStatusText()); - } - - _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); - } - - _allocate(actor, box, flags) { - if (actor.get_n_children() > 0) - actor.get_first_child().allocate(box, flags); - } -}); - class WindowList { constructor(perMonitor, monitor) { this._perMonitor = perMonitor; diff --git a/extensions/window-list/meson.build b/extensions/window-list/meson.build index 5b1f5f51..34d7c3fd 100644 --- a/extensions/window-list/meson.build +++ b/extensions/window-list/meson.build @@ -4,7 +4,7 @@ extension_data += configure_file( configuration: metadata_conf ) -extension_sources += files('prefs.js', 'windowPicker.js') +extension_sources += files('prefs.js', 'windowPicker.js', 'workspaceIndicator.js') extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml') if classic_mode_enabled diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js new file mode 100644 index 00000000..fb3ffe70 --- /dev/null +++ b/extensions/window-list/workspaceIndicator.js @@ -0,0 +1,135 @@ +/* exported WorkspaceIndicator */ +const { Clutter, Gio, GObject, Meta, St } = imports.gi; + +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; + +const Gettext = imports.gettext.domain('gnome-shell-extensions'); +const _ = Gettext.gettext; + +var WorkspaceIndicator = GObject.registerClass( +class WorkspaceIndicator extends PanelMenu.Button { + _init() { + super._init(0.0, _('Workspace Indicator'), true); + this.setMenu(new PopupMenu.PopupMenu(this, 0.0, St.Side.BOTTOM)); + this.add_style_class_name('window-list-workspace-indicator'); + this.menu.actor.remove_style_class_name('panel-menu'); + + let container = new St.Widget({ + layout_manager: new Clutter.BinLayout(), + x_expand: true, + y_expand: true + }); + this.add_actor(container); + + let workspaceManager = global.workspace_manager; + + this._currentWorkspace = workspaceManager.get_active_workspace().index(); + this.statusLabel = new St.Label({ + text: this._getStatusText(), + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER + }); + container.add_actor(this.statusLabel); + + this.workspacesItems = []; + + this._workspaceManagerSignals = [ + workspaceManager.connect('notify::n-workspaces', + this._updateMenu.bind(this)), + workspaceManager.connect_after('workspace-switched', + this._updateIndicator.bind(this)) + ]; + + this.connect('scroll-event', this._onScrollEvent.bind(this)); + this._updateMenu(); + + this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' }); + this._settingsChangedId = this._settings.connect( + 'changed::workspace-names', this._updateMenu.bind(this)); + } + + _onDestroy() { + for (let i = 0; i < this._workspaceManagerSignals.length; i++) + global.workspace_manager.disconnect(this._workspaceManagerSignals[i]); + + if (this._settingsChangedId) { + this._settings.disconnect(this._settingsChangedId); + this._settingsChangedId = 0; + } + + super._onDestroy(); + } + + _updateIndicator() { + this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); + this._currentWorkspace = global.workspace_manager.get_active_workspace().index(); + this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); + + this.statusLabel.set_text(this._getStatusText()); + } + + _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); + } + + _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', (item, _event) => { + this._activate(item.workspaceId); + }); + + if (i == this._currentWorkspace) + item.setOrnament(PopupMenu.Ornament.DOT); + + this.menu.addMenuItem(item); + this.workspacesItems[i] = item; + } + + this.statusLabel.set_text(this._getStatusText()); + } + + _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); + } + + _allocate(actor, box, flags) { + if (actor.get_n_children() > 0) + actor.get_first_child().allocate(box, flags); + } +}); + From cbd1b7d9831831fc7eed984eb2c86603ee0fcdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 17:39:53 +0000 Subject: [PATCH 49/78] window-list: Use a more specific GTypeName for workspace indicator Now that the class inherits from GObject, the generic name easily conflicts with other classes otherwise, for example with the one from the workspace-indicator extension. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/workspaceIndicator.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index fb3ffe70..8ac43eb4 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -7,8 +7,9 @@ const PopupMenu = imports.ui.popupMenu; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; -var WorkspaceIndicator = GObject.registerClass( -class WorkspaceIndicator extends PanelMenu.Button { +var WorkspaceIndicator = GObject.registerClass({ + GTypeName: 'WindowListWorkspaceIndicator' +}, class WorkspaceIndicator extends PanelMenu.Button { _init() { super._init(0.0, _('Workspace Indicator'), true); this.setMenu(new PopupMenu.PopupMenu(this, 0.0, St.Side.BOTTOM)); From 1532c153252749c7b3075328808885af0ad2d370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 04:54:50 +0200 Subject: [PATCH 50/78] window-list: Make some properties private There's no reason why they should be public. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/workspaceIndicator.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 8ac43eb4..7c0360a2 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -26,14 +26,14 @@ var WorkspaceIndicator = GObject.registerClass({ let workspaceManager = global.workspace_manager; this._currentWorkspace = workspaceManager.get_active_workspace().index(); - this.statusLabel = new St.Label({ + this._statusLabel = new St.Label({ text: this._getStatusText(), x_align: Clutter.ActorAlign.CENTER, y_align: Clutter.ActorAlign.CENTER }); - container.add_actor(this.statusLabel); + container.add_actor(this._statusLabel); - this.workspacesItems = []; + this._workspacesItems = []; this._workspaceManagerSignals = [ workspaceManager.connect('notify::n-workspaces', @@ -63,11 +63,11 @@ var WorkspaceIndicator = GObject.registerClass({ } _updateIndicator() { - this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); + this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); this._currentWorkspace = global.workspace_manager.get_active_workspace().index(); - this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); + this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); - this.statusLabel.set_text(this._getStatusText()); + this._statusLabel.set_text(this._getStatusText()); } _getStatusText() { @@ -82,7 +82,7 @@ var WorkspaceIndicator = GObject.registerClass({ let workspaceManager = global.workspace_manager; this.menu.removeAll(); - this.workspacesItems = []; + this._workspacesItems = []; this._currentWorkspace = workspaceManager.get_active_workspace().index(); for (let i = 0; i < workspaceManager.n_workspaces; i++) { @@ -98,10 +98,10 @@ var WorkspaceIndicator = GObject.registerClass({ item.setOrnament(PopupMenu.Ornament.DOT); this.menu.addMenuItem(item); - this.workspacesItems[i] = item; + this._workspacesItems[i] = item; } - this.statusLabel.set_text(this._getStatusText()); + this._statusLabel.set_text(this._getStatusText()); } _activate(index) { From bdf6af3ee3c96855fbc9846b6580ba6f7638c47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 04:57:39 +0200 Subject: [PATCH 51/78] window-list: Update workspace names in-place There's no good reason to rebuild the entire menu on workspace names changes, we can simply update the labels in-place. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/workspaceIndicator.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 7c0360a2..98888384 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -47,7 +47,7 @@ var WorkspaceIndicator = GObject.registerClass({ this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' }); this._settingsChangedId = this._settings.connect( - 'changed::workspace-names', this._updateMenu.bind(this)); + 'changed::workspace-names', this._updateMenuLabels.bind(this)); } _onDestroy() { @@ -78,6 +78,14 @@ var WorkspaceIndicator = GObject.registerClass({ 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; From dab326c17ee3be159dc73feca4c7c99eaf3eff21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 04:59:19 +0200 Subject: [PATCH 52/78] window-list: Minor cleanup Mutter has a dedicated method for getting the index of the active workspace, use that instead of getting first the active workspace and then its index. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/workspaceIndicator.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 98888384..1f2e1c18 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -25,7 +25,7 @@ var WorkspaceIndicator = GObject.registerClass({ let workspaceManager = global.workspace_manager; - this._currentWorkspace = workspaceManager.get_active_workspace().index(); + this._currentWorkspace = workspaceManager.get_active_workspace_index(); this._statusLabel = new St.Label({ text: this._getStatusText(), x_align: Clutter.ActorAlign.CENTER, @@ -64,7 +64,7 @@ var WorkspaceIndicator = GObject.registerClass({ _updateIndicator() { this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); - this._currentWorkspace = global.workspace_manager.get_active_workspace().index(); + this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); this._statusLabel.set_text(this._getStatusText()); @@ -72,7 +72,7 @@ var WorkspaceIndicator = GObject.registerClass({ _getStatusText() { let workspaceManager = global.workspace_manager; - let current = workspaceManager.get_active_workspace().index(); + let current = workspaceManager.get_active_workspace_index(); let total = workspaceManager.n_workspaces; return '%d / %d'.format(current + 1, total); @@ -91,7 +91,7 @@ var WorkspaceIndicator = GObject.registerClass({ this.menu.removeAll(); this._workspacesItems = []; - this._currentWorkspace = workspaceManager.get_active_workspace().index(); + this._currentWorkspace = workspaceManager.get_active_workspace_index(); for (let i = 0; i < workspaceManager.n_workspaces; i++) { let name = Meta.prefs_get_workspace_name(i); From a5f347ba10408a30d1a2ffeff020f3a63c2784f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 05:11:34 +0200 Subject: [PATCH 53/78] window-list: Improve workspace label styling The border currently looks off - it extends all the way vertically and leaves zero spacing to the label horizontally. Fix both issues by setting appropriate padding/margins. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/stylesheet.css | 8 +++----- extensions/window-list/workspaceIndicator.js | 13 ++++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css index 91383ab6..bab8f763 100644 --- a/extensions/window-list/stylesheet.css +++ b/extensions/window-list/stylesheet.css @@ -85,13 +85,11 @@ height: 24px; } -.window-list-workspace-indicator { - padding: 3px; -} - -.window-list-workspace-indicator > StWidget { +.window-list-workspace-indicator .status-label-bin { background-color: rgba(200, 200, 200, .3); border: 1px solid #cccccc; + padding: 0 3px; + margin: 3px 0; } .notification { diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 1f2e1c18..598c5165 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -26,12 +26,15 @@ var WorkspaceIndicator = GObject.registerClass({ let workspaceManager = global.workspace_manager; this._currentWorkspace = workspaceManager.get_active_workspace_index(); - this._statusLabel = new St.Label({ - text: this._getStatusText(), - x_align: Clutter.ActorAlign.CENTER, - y_align: Clutter.ActorAlign.CENTER + 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_actor(this._statusLabel); + container.add_actor(this._statusBin); this._workspacesItems = []; From 5a30ebe403c4e97d810c2a16ec148b4cf064ceb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 05:08:31 +0200 Subject: [PATCH 54/78] window-list: Refactor workspace signal handlers We are about to support a separate representation if horizontal workspaces are used. To prepare for that, rename the handlers to something more generic and split out menu-specific bits into a dedicated helper function. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/70 --- extensions/window-list/workspaceIndicator.js | 25 +++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 598c5165..78ca97e9 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -40,9 +40,9 @@ var WorkspaceIndicator = GObject.registerClass({ this._workspaceManagerSignals = [ workspaceManager.connect('notify::n-workspaces', - this._updateMenu.bind(this)), + this._nWorkspacesChanged.bind(this)), workspaceManager.connect_after('workspace-switched', - this._updateIndicator.bind(this)) + this._onWorkspaceSwitched.bind(this)) ]; this.connect('scroll-event', this._onScrollEvent.bind(this)); @@ -65,14 +65,27 @@ var WorkspaceIndicator = GObject.registerClass({ super._onDestroy(); } - _updateIndicator() { - this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); - this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); - this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); + _onWorkspaceSwitched() { + let workspaceManager = global.workspace_manager; + this._currentWorkspace = workspaceManager.get_active_workspace_index(); + + this._updateMenuOrnament(); this._statusLabel.set_text(this._getStatusText()); } + _nWorkspacesChanged() { + this._updateMenu(); + } + + _updateMenuOrnament() { + for (let i = 0; i < this._workspacesItems.length; i++) { + this._workspacesItems[i].setOrnament(i == this._currentWorkspace + ? PopupMenu.Ornament.DOT + : PopupMenu.Ornament.NONE); + } + } + _getStatusText() { let workspaceManager = global.workspace_manager; let current = workspaceManager.get_active_workspace_index(); 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 55/78] 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; From 9f9dbd579b1432cbc863d4de44571db42a22b6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 11 Jun 2019 23:01:20 +0000 Subject: [PATCH 56/78] window-list: Turn workspace thumbs into drop targets It makes some sense to allow using the workspace indicator for moving windows between workspaces as well as for workspace switching. This applies particularly in GNOME classic after we disabled the overview there, so that there is again a non-shortcut way of moving windows between workspaces. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/74 --- extensions/window-list/workspaceIndicator.js | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index 9896a60a..d6695079 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -1,6 +1,8 @@ /* exported WorkspaceIndicator */ const { Clutter, Gio, GObject, Meta, St } = imports.gi; +const DND = imports.ui.dnd; +const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; @@ -16,6 +18,31 @@ let WorkspaceThumbnail = GObject.registerClass({ }); this._index = index; + this._delegate = this; // needed for DND + } + + acceptDrop(source) { + if (!source.realWindow) + return false; + + let window = source.realWindow.get_meta_window(); + this._moveWindow(window); + return true; + } + + handleDragOver(source) { + if (source.realWindow) + return DND.DragMotionResult.MOVE_DROP; + else + return DND.DragMotionResult.CONTINUE; + } + + + _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() { From 5b07dfded9842c75dc5b7ef80d5c30f6abd65029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 26 Jun 2019 23:55:58 +0000 Subject: [PATCH 57/78] window-list: Show previews in workspace switcher Currently the new horizontal workspace switcher only shows a series of buttons, with no indication of the workspaces' contents. Go full GNOME 2 and add tiny draggable preview rectangles that represent the windows on a particular workspace. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/74 --- extensions/window-list/classic.css | 10 ++ extensions/window-list/stylesheet.css | 10 ++ extensions/window-list/workspaceIndicator.js | 154 ++++++++++++++++++- 3 files changed, 173 insertions(+), 1 deletion(-) diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css index c533473e..7079d3ef 100644 --- a/extensions/window-list/classic.css +++ b/extensions/window-list/classic.css @@ -56,3 +56,13 @@ .window-list-workspace-indicator .workspace.active { background-color: #ccc; } + +.window-list-window-preview { + background-color: #ededed; + border: 1px solid #ccc; +} + +.window-list-window-preview.active { + background-color: #f6f5f4; + border: 2px solid #888; +} diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css index ad5978a0..79d56bad 100644 --- a/extensions/window-list/stylesheet.css +++ b/extensions/window-list/stylesheet.css @@ -121,6 +121,16 @@ background-color: rgba(200, 200, 200, .3); } +.window-list-window-preview { + background-color: #252525; + border: 1px solid #ccc; +} + +.window-list-window-preview.active { + background-color: #353535; + border: 2px solid #ccc; +} + .notification { font-weight: normal; } diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index d6695079..84dccacc 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -9,16 +9,131 @@ const PopupMenu = imports.ui.popupMenu; const Gettext = imports.gettext.domain('gnome-shell-extensions'); const _ = Gettext.gettext; +let WindowPreview = GObject.registerClass({ + GTypeName: 'WindowListWindowPreview' +}, class WindowPreview extends St.Button { + _init(window) { + super._init({ + style_class: 'window-list-window-preview' + }); + + this._delegate = this; + DND.makeDraggable(this, { restoreOnSuccess: true }); + + this._window = window; + + this.connect('destroy', this._onDestroy.bind(this)); + + this._sizeChangedId = this._window.connect('size-changed', + this._relayout.bind(this)); + this._positionChangedId = this._window.connect('position-changed', + this._relayout.bind(this)); + this._minimizedChangedId = this._window.connect('notify::minimized', + this._relayout.bind(this)); + this._monitorEnteredId = global.display.connect('window-entered-monitor', + this._relayout.bind(this)); + this._monitorLeftId = global.display.connect('window-left-monitor', + this._relayout.bind(this)); + + // Do initial layout when we get a parent + let id = this.connect('parent-set', () => { + this.disconnect(id); + if (!this.get_parent()) + return; + this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { + this._laterId = 0; + this._relayout(); + return false; + }); + }); + + this._focusChangedId = global.display.connect('notify::focus-window', + this._onFocusChanged.bind(this)); + this._onFocusChanged(); + } + + // needed for DND + get realWindow() { + return this._window.get_compositor_private(); + } + + _onDestroy() { + this._window.disconnect(this._sizeChangedId); + this._window.disconnect(this._positionChangedId); + this._window.disconnect(this._minimizedChangedId); + global.display.disconnect(this._monitorEnteredId); + global.display.disconnect(this._monitorLeftId); + global.display.disconnect(this._focusChangedId); + if (this._laterId) + Meta.later_remove(this._laterId); + } + + _onFocusChanged() { + if (global.display.focus_window == this._window) + this.add_style_class_name('active'); + else + this.remove_style_class_name('active'); + } + + _relayout() { + let monitor = Main.layoutManager.findIndexForActor(this); + this.visible = monitor == this._window.get_monitor() && + this._window.showing_on_its_workspace(); + + if (!this.visible) + return; + + let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + let hscale = this.get_parent().allocation.get_width() / workArea.width; + let vscale = this.get_parent().allocation.get_height() / workArea.height; + + let frameRect = this._window.get_frame_rect(); + this.set_size( + Math.round(Math.min(frameRect.width, workArea.width) * hscale), + Math.round(Math.min(frameRect.height, workArea.height) * vscale)); + this.set_position( + Math.round(frameRect.x * hscale), + Math.round(frameRect.y * vscale)); + } +}); + let WorkspaceThumbnail = GObject.registerClass({ GTypeName: 'WindowListWorkspaceThumbnail' }, class WorkspaceThumbnail extends St.Button { _init(index) { super._init({ - style_class: 'workspace' + style_class: 'workspace', + child: new Clutter.Actor({ + layout_manager: new Clutter.BinLayout(), + clip_to_allocation: true + }), + x_fill: true, + y_fill: true }); + this.connect('destroy', this._onDestroy.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._windowAddedId = this._workspace.connect('window-added', + (ws, window) => { + this._addWindow(window); + }); + this._windowRemovedId = this._workspace.connect('window-removed', + (ws, window) => { + this._removeWindow(window); + }); + this._restackedId = global.display.connect('restacked', + this._onRestacked.bind(this)); + + this._workspace.list_windows().forEach(w => this._addWindow(w)); + this._onRestacked(); } acceptDrop(source) { @@ -37,6 +152,37 @@ let WorkspaceThumbnail = GObject.registerClass({ 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); @@ -50,6 +196,12 @@ let WorkspaceThumbnail = GObject.registerClass({ if (ws) ws.activate(global.get_current_time()); } + + _onDestroy() { + this._workspace.disconnect(this._windowAddedId); + this._workspace.disconnect(this._windowRemovedId); + global.display.disconnect(this._restackedId); + } }); var WorkspaceIndicator = GObject.registerClass({ From f1a154207fca53a218f89ff6eef88a739256e76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 29 Jun 2019 01:24:54 +0200 Subject: [PATCH 58/78] workspace-indicator: Fix whitespace error We only want a single space before and after operators, not at least one. Unfortunately eslint only enforces the latter ... https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 2c92a4da..e0fef273 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -109,7 +109,7 @@ class WorkspaceIndicator extends PanelMenu.Button { _activate(index) { let workspaceManager = global.workspace_manager; - if (index >= 0 && index < workspaceManager.n_workspaces) { + if (index >= 0 && index < workspaceManager.n_workspaces) { let metaWorkspace = workspaceManager.get_workspace_by_index(index); metaWorkspace.activate(global.get_current_time()); } From 9fa283877ceea3c2251115ed4f3e79ddc39e637a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 9 Jun 2019 22:58:29 +0000 Subject: [PATCH 59/78] workspace-indicator: Make some properties private There's no reason why they should be public. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index e0fef273..f443c3f4 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -22,14 +22,14 @@ class WorkspaceIndicator extends PanelMenu.Button { let workspaceManager = global.workspace_manager; this._currentWorkspace = workspaceManager.get_active_workspace().index(); - this.statusLabel = new St.Label({ + this._statusLabel = new St.Label({ y_align: Clutter.ActorAlign.CENTER, text: this._labelText() }); - this.add_actor(this.statusLabel); + this.add_actor(this._statusLabel); - this.workspacesItems = []; + this._workspacesItems = []; this._workspaceSection = new PopupMenu.PopupMenuSection(); this.menu.addMenuItem(this._workspaceSection); @@ -46,7 +46,7 @@ class WorkspaceIndicator extends PanelMenu.Button { this._createWorkspacesSection(); //styling - this.statusLabel.add_style_class_name('panel-workspace-indicator'); + this._statusLabel.add_style_class_name('panel-workspace-indicator'); this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA }); this._settingsChangedId = this._settings.connect( @@ -67,11 +67,11 @@ class WorkspaceIndicator extends PanelMenu.Button { } _updateIndicator() { - this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); + this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); this._currentWorkspace = global.workspace_manager.get_active_workspace().index(); - this.workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); + this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); - this.statusLabel.set_text(this._labelText()); + this._statusLabel.set_text(this._labelText()); } _labelText(workspaceIndex) { @@ -86,24 +86,24 @@ class WorkspaceIndicator extends PanelMenu.Button { let workspaceManager = global.workspace_manager; this._workspaceSection.removeAll(); - this.workspacesItems = []; + this._workspacesItems = []; this._currentWorkspace = workspaceManager.get_active_workspace().index(); let i = 0; for (; i < workspaceManager.n_workspaces; i++) { - this.workspacesItems[i] = new PopupMenu.PopupMenuItem(this._labelText(i)); - this._workspaceSection.addMenuItem(this.workspacesItems[i]); - this.workspacesItems[i].workspaceId = i; - this.workspacesItems[i].label_actor = this.statusLabel; - this.workspacesItems[i].connect('activate', (actor, _event) => { + this._workspacesItems[i] = new PopupMenu.PopupMenuItem(this._labelText(i)); + this._workspaceSection.addMenuItem(this._workspacesItems[i]); + this._workspacesItems[i].workspaceId = i; + this._workspacesItems[i].label_actor = this._statusLabel; + this._workspacesItems[i].connect('activate', (actor, _event) => { this._activate(actor.workspaceId); }); if (i == this._currentWorkspace) - this.workspacesItems[i].setOrnament(PopupMenu.Ornament.DOT); + this._workspacesItems[i].setOrnament(PopupMenu.Ornament.DOT); } - this.statusLabel.set_text(this._labelText()); + this._statusLabel.set_text(this._labelText()); } _activate(index) { From d1674c5f75b5c229c5e668cdd2880117201f8dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 9 Jun 2019 23:03:55 +0000 Subject: [PATCH 60/78] workspace-indicator: Update workspace names in-place There's no good reason to rebuild the entire menu on workspace names changes, we can simply update the labels in-place. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index f443c3f4..ef10d8fe 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -51,7 +51,7 @@ class WorkspaceIndicator extends PanelMenu.Button { this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA }); this._settingsChangedId = this._settings.connect( `changed::${WORKSPACE_KEY}`, - this._createWorkspacesSection.bind(this)); + this._updateMenuLabels.bind(this)); } _onDestroy() { @@ -82,6 +82,11 @@ class WorkspaceIndicator extends PanelMenu.Button { return Meta.prefs_get_workspace_name(workspaceIndex); } + _updateMenuLabels() { + for (let i = 0; i < this._workspacesItems.length; i++) + this._workspacesItems[i].label.text = this._labelText(i); + } + _createWorkspacesSection() { let workspaceManager = global.workspace_manager; From e836a9e5e0319a22a49871099cd7464d268347d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 9 Jun 2019 23:05:00 +0000 Subject: [PATCH 61/78] workspace-indicator: Minor cleanup Mutter has a dedicated method for getting the index of the active workspace, use that instead of getting first the active workspace and then its index. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index ef10d8fe..3f21685d 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -21,7 +21,7 @@ class WorkspaceIndicator extends PanelMenu.Button { let workspaceManager = global.workspace_manager; - this._currentWorkspace = workspaceManager.get_active_workspace().index(); + this._currentWorkspace = workspaceManager.get_active_workspace_index(); this._statusLabel = new St.Label({ y_align: Clutter.ActorAlign.CENTER, text: this._labelText() @@ -68,7 +68,7 @@ class WorkspaceIndicator extends PanelMenu.Button { _updateIndicator() { this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); - this._currentWorkspace = global.workspace_manager.get_active_workspace().index(); + this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); this._statusLabel.set_text(this._labelText()); @@ -92,7 +92,7 @@ class WorkspaceIndicator extends PanelMenu.Button { this._workspaceSection.removeAll(); this._workspacesItems = []; - this._currentWorkspace = workspaceManager.get_active_workspace().index(); + this._currentWorkspace = workspaceManager.get_active_workspace_index(); let i = 0; for (; i < workspaceManager.n_workspaces; i++) { @@ -131,7 +131,7 @@ class WorkspaceIndicator extends PanelMenu.Button { return; } - let newIndex = global.workspace_manager.get_active_workspace().index() + diff; + let newIndex = global.workspace_manager.get_active_workspace_index() + diff; this._activate(newIndex); } }); From c516f059272dbc3cdbfcd91e31a4eacfe91ed15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 9 Jun 2019 23:09:12 +0000 Subject: [PATCH 62/78] workspace-indicator: Refactor workspace signal handlers We are about to support a separate representation if horizontal workspaces are used. To prepare for that, rename the handlers to something more generic and split out menu-specific bits into a dedicated helper function. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 26 ++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 3f21685d..00959cb0 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -34,12 +34,10 @@ class WorkspaceIndicator extends PanelMenu.Button { this.menu.addMenuItem(this._workspaceSection); this._workspaceManagerSignals = [ - workspaceManager.connect_after('workspace-added', - this._createWorkspacesSection.bind(this)), - workspaceManager.connect_after('workspace-removed', - this._createWorkspacesSection.bind(this)), + workspaceManager.connect_after('notify::n-workspaces', + this._nWorkspacesChanged.bind(this)), workspaceManager.connect_after('workspace-switched', - this._updateIndicator.bind(this)) + this._onWorkspaceSwitched.bind(this)) ]; this.connect('scroll-event', this._onScrollEvent.bind(this)); @@ -66,14 +64,26 @@ class WorkspaceIndicator extends PanelMenu.Button { super._onDestroy(); } - _updateIndicator() { - this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.NONE); + _onWorkspaceSwitched() { this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); - this._workspacesItems[this._currentWorkspace].setOrnament(PopupMenu.Ornament.DOT); + + this._updateMenuOrnament(); this._statusLabel.set_text(this._labelText()); } + _nWorkspacesChanged() { + this._createWorkspacesSection(); + } + + _updateMenuOrnament() { + for (let i = 0; i < this._workspacesItems.length; i++) { + this._workspacesItems[i].setOrnament(i == this._currentWorkspace + ? PopupMenu.Ornament.DOT + : PopupMenu.Ornament.NONE); + } + } + _labelText(workspaceIndex) { if (workspaceIndex == undefined) { workspaceIndex = this._currentWorkspace; From 283a1ec5c22ecf9c10470649430ab1db811366f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 9 Jun 2019 23:17:35 +0000 Subject: [PATCH 63/78] workspace-indicator: Minor cleanup Pass the style class at construction time instead of setting it later. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 00959cb0..82700b03 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -23,6 +23,7 @@ class WorkspaceIndicator extends PanelMenu.Button { this._currentWorkspace = workspaceManager.get_active_workspace_index(); this._statusLabel = new St.Label({ + style_class: 'panel-workspace-indicator', y_align: Clutter.ActorAlign.CENTER, text: this._labelText() }); @@ -43,9 +44,6 @@ class WorkspaceIndicator extends PanelMenu.Button { this.connect('scroll-event', this._onScrollEvent.bind(this)); this._createWorkspacesSection(); - //styling - this._statusLabel.add_style_class_name('panel-workspace-indicator'); - this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA }); this._settingsChangedId = this._settings.connect( `changed::${WORKSPACE_KEY}`, From 52f373fb70163e564726cf0ca0d0d3b95195562d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 9 Jun 2019 23:45:24 +0000 Subject: [PATCH 64/78] workspace-indicator: Support horizontal workspace layout Just like we did for the workspace indicator in the window-list, improve the handling of horizontal workspace layouts by showing the switcher in-place instead of delegating the functionality to a menu. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/71 --- extensions/workspace-indicator/extension.js | 75 ++++++++++++++++++- extensions/workspace-indicator/stylesheet.css | 27 ++++++- 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 82700b03..3e6e939b 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -14,11 +14,37 @@ const _ = Gettext.gettext; const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; const WORKSPACE_KEY = 'workspace-names'; +let WorkspaceThumbnail = GObject.registerClass({ + GTypeName: 'WorkspaceIndicatorWorkspaceThumbnail' +}, 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()); + } +}); + + let WorkspaceIndicator = GObject.registerClass( class WorkspaceIndicator extends PanelMenu.Button { _init() { super._init(0.0, _('Workspace Indicator')); + let container = new St.Widget({ + layout_manager: new Clutter.BinLayout(), + x_expand: true, + y_expand: true + }); + this.add_actor(container); + let workspaceManager = global.workspace_manager; this._currentWorkspace = workspaceManager.get_active_workspace_index(); @@ -28,7 +54,15 @@ class WorkspaceIndicator extends PanelMenu.Button { text: this._labelText() }); - this.add_actor(this._statusLabel); + container.add_actor(this._statusLabel); + + this._thumbnailsBox = new St.BoxLayout({ + style_class: 'panel-workspace-indicator-box', + y_expand: true, + reactive: true + }); + + container.add_actor(this._thumbnailsBox); this._workspacesItems = []; this._workspaceSection = new PopupMenu.PopupMenuSection(); @@ -38,11 +72,16 @@ class WorkspaceIndicator extends PanelMenu.Button { workspaceManager.connect_after('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._thumbnailsBox.connect('scroll-event', this._onScrollEvent.bind(this)); this._createWorkspacesSection(); + this._updateThumbnails(); + this._onWorkspaceOrientationChanged(); this._settings = new Gio.Settings({ schema_id: WORKSPACE_SCHEMA }); this._settingsChangedId = this._settings.connect( @@ -62,16 +101,26 @@ class WorkspaceIndicator extends PanelMenu.Button { super._onDestroy(); } + _onWorkspaceOrientationChanged() { + let vertical = global.workspace_manager.layout_rows == -1; + this.reactive = vertical; + + this._statusLabel.visible = vertical; + this._thumbnailsBox.visible = !vertical; + } + _onWorkspaceSwitched() { this._currentWorkspace = global.workspace_manager.get_active_workspace_index(); this._updateMenuOrnament(); + this._updateActiveThumbnail(); this._statusLabel.set_text(this._labelText()); } _nWorkspacesChanged() { this._createWorkspacesSection(); + this._updateThumbnails(); } _updateMenuOrnament() { @@ -82,6 +131,16 @@ class WorkspaceIndicator extends PanelMenu.Button { } } + _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'); + } + } + _labelText(workspaceIndex) { if (workspaceIndex == undefined) { workspaceIndex = this._currentWorkspace; @@ -119,6 +178,18 @@ class WorkspaceIndicator extends PanelMenu.Button { this._statusLabel.set_text(this._labelText()); } + _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; diff --git a/extensions/workspace-indicator/stylesheet.css b/extensions/workspace-indicator/stylesheet.css index 1271f1ce..51181948 100644 --- a/extensions/workspace-indicator/stylesheet.css +++ b/extensions/workspace-indicator/stylesheet.css @@ -1,5 +1,30 @@ .panel-workspace-indicator { padding: 0 8px; - background-color: rgba(200, 200, 200, .5); +} + +.panel-workspace-indicator-box { + padding: 2px 0; +} + +.panel-workspace-indicator-box .workspace { + width: 40px; +} + +.panel-workspace-indicator, +.panel-workspace-indicator-box .workspace { border: 1px solid #cccccc; } + +.panel-workspace-indicator, +.panel-workspace-indicator-box .workspace.active { + background-color: rgba(200, 200, 200, .5); +} + +.panel-workspace-indicator-box .workspace { + background-color: rgba(200, 200, 200, .3); + border-left-width: 0; +} + +.panel-workspace-indicator-box .workspace:first-child { + border-left-width: 1px; +} From c6d2063f4df19d384bfe60179a6339f10462cff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 28 Jun 2019 11:33:16 +0200 Subject: [PATCH 65/78] workspace-indicator: Show previews in workspace switcher Currently the new horizontal workspace switcher only shows a series of buttons, with no indication of the workspaces' contents. Go full GNOME 2 and add tiny draggable preview rectangles that represent the windows on a particular workspace. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/77 --- extensions/workspace-indicator/extension.js | 187 +++++++++++++++++- extensions/workspace-indicator/stylesheet.css | 10 + 2 files changed, 196 insertions(+), 1 deletion(-) diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 3e6e939b..4a9e5c19 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -3,6 +3,7 @@ const { Clutter, Gio, GObject, Meta, St } = imports.gi; +const DND = imports.ui.dnd; const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; @@ -14,15 +15,186 @@ const _ = Gettext.gettext; const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; const WORKSPACE_KEY = 'workspace-names'; +let WindowPreview = GObject.registerClass({ + GTypeName: 'WorkspaceIndicatorWindowPreview' +}, class WindowPreview extends St.Button { + _init(window) { + super._init({ + style_class: 'workspace-indicator-window-preview' + }); + + this._delegate = this; + DND.makeDraggable(this, { restoreOnSuccess: true }); + + this._window = window; + + this.connect('destroy', this._onDestroy.bind(this)); + + this._sizeChangedId = this._window.connect('size-changed', + this._relayout.bind(this)); + this._positionChangedId = this._window.connect('position-changed', + this._relayout.bind(this)); + this._minimizedChangedId = this._window.connect('notify::minimized', + this._relayout.bind(this)); + this._monitorEnteredId = global.display.connect('window-entered-monitor', + this._relayout.bind(this)); + this._monitorLeftId = global.display.connect('window-left-monitor', + this._relayout.bind(this)); + + // Do initial layout when we get a parent + let id = this.connect('parent-set', () => { + this.disconnect(id); + if (!this.get_parent()) + return; + this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { + this._laterId = 0; + this._relayout(); + return false; + }); + }); + + this._focusChangedId = global.display.connect('notify::focus-window', + this._onFocusChanged.bind(this)); + this._onFocusChanged(); + } + + // needed for DND + get realWindow() { + return this._window.get_compositor_private(); + } + + _onDestroy() { + this._window.disconnect(this._sizeChangedId); + this._window.disconnect(this._positionChangedId); + this._window.disconnect(this._minimizedChangedId); + global.display.disconnect(this._monitorEnteredId); + global.display.disconnect(this._monitorLeftId); + global.display.disconnect(this._focusChangedId); + if (this._laterId) + Meta.later_remove(this._laterId); + } + + _onFocusChanged() { + if (global.display.focus_window == this._window) + this.add_style_class_name('active'); + else + this.remove_style_class_name('active'); + } + + _relayout() { + let monitor = Main.layoutManager.findIndexForActor(this); + this.visible = monitor == this._window.get_monitor() && + this._window.showing_on_its_workspace(); + + if (!this.visible) + return; + + let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + let hscale = this.get_parent().allocation.get_width() / workArea.width; + let vscale = this.get_parent().allocation.get_height() / workArea.height; + + let frameRect = this._window.get_frame_rect(); + this.set_size( + Math.round(Math.min(frameRect.width, workArea.width) * hscale), + Math.round(Math.min(frameRect.height, workArea.height) * vscale)); + this.set_position( + Math.round(frameRect.x * hscale), + Math.round(frameRect.y * vscale)); + } +}); + let WorkspaceThumbnail = GObject.registerClass({ GTypeName: 'WorkspaceIndicatorWorkspaceThumbnail' }, class WorkspaceThumbnail extends St.Button { _init(index) { super._init({ style_class: 'workspace', + child: new Clutter.Actor({ + layout_manager: new Clutter.BinLayout(), + clip_to_allocation: true + }), + x_fill: true, + y_fill: true }); + this.connect('destroy', this._onDestroy.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._windowAddedId = this._workspace.connect('window-added', + (ws, window) => { + this._addWindow(window); + }); + this._windowRemovedId = this._workspace.connect('window-removed', + (ws, window) => { + this._removeWindow(window); + }); + this._restackedId = global.display.connect('restacked', + this._onRestacked.bind(this)); + + this._workspace.list_windows().forEach(w => this._addWindow(w)); + this._onRestacked(); + } + + acceptDrop(source) { + if (!source.realWindow) + return false; + + let window = source.realWindow.get_meta_window(); + this._moveWindow(window); + return true; + } + + handleDragOver(source) { + if (source.realWindow) + 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() { @@ -30,8 +202,13 @@ let WorkspaceThumbnail = GObject.registerClass({ if (ws) ws.activate(global.get_current_time()); } -}); + _onDestroy() { + this._workspace.disconnect(this._windowAddedId); + this._workspace.disconnect(this._windowRemovedId); + global.display.disconnect(this._restackedId); + } +}); let WorkspaceIndicator = GObject.registerClass( class WorkspaceIndicator extends PanelMenu.Button { @@ -98,6 +275,8 @@ class WorkspaceIndicator extends PanelMenu.Button { this._settingsChangedId = 0; } + Main.panel.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); + super._onDestroy(); } @@ -107,6 +286,12 @@ class WorkspaceIndicator extends PanelMenu.Button { this._statusLabel.visible = vertical; this._thumbnailsBox.visible = !vertical; + + // Disable offscreen-redirect when showing the workspace switcher + // so that clip-to-allocation works + Main.panel.set_offscreen_redirect(vertical + ? Clutter.OffscreenRedirect.ALWAYS + : Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY); } _onWorkspaceSwitched() { diff --git a/extensions/workspace-indicator/stylesheet.css b/extensions/workspace-indicator/stylesheet.css index 51181948..8601c3e5 100644 --- a/extensions/workspace-indicator/stylesheet.css +++ b/extensions/workspace-indicator/stylesheet.css @@ -28,3 +28,13 @@ .panel-workspace-indicator-box .workspace:first-child { border-left-width: 1px; } + +.workspace-indicator-window-preview { + background-color: #252525; + border: 1px solid #ccc; +} + +.workspace-indicator-window-preview.active { + background-color: #353535; + border: 2px solid #ccc; +} From 60c75e5fcfda19a66d4dcf8c5135b4c56fb7beba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 5 Jun 2019 03:31:16 +0000 Subject: [PATCH 66/78] classic: Add 'horizontal-workspaces' extension Vertical workspaces are another defining characteristics of GNOME 3, and thus rather un-classic. That switch was driven by the overall layout of the overview, and now that we disable the overview in GNOME Classic, we can just return to the traditional workspace layout as well. Add a small extension that does just that. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/72 --- extensions/horizontal-workspaces/extension.js | 38 +++++++++++++++++++ extensions/horizontal-workspaces/meson.build | 5 +++ .../horizontal-workspaces/metadata.json.in | 10 +++++ .../horizontal-workspaces/stylesheet.css | 1 + meson.build | 1 + 5 files changed, 55 insertions(+) create mode 100644 extensions/horizontal-workspaces/extension.js create mode 100644 extensions/horizontal-workspaces/meson.build create mode 100644 extensions/horizontal-workspaces/metadata.json.in create mode 100644 extensions/horizontal-workspaces/stylesheet.css diff --git a/extensions/horizontal-workspaces/extension.js b/extensions/horizontal-workspaces/extension.js new file mode 100644 index 00000000..b5f04355 --- /dev/null +++ b/extensions/horizontal-workspaces/extension.js @@ -0,0 +1,38 @@ +/* exported init */ +const { Meta } = imports.gi; + +const { ThumbnailsBox } = imports.ui.workspaceThumbnail; + +class Extension { + constructor() { + this._origUpdateSwitcherVisibility = + ThumbnailsBox.prototype._updateSwitcherVisibility; + } + + enable() { + global.workspace_manager.override_workspace_layout( + Meta.DisplayCorner.TOPLEFT, + false, + 1, + -1); + + ThumbnailsBox.prototype._updateSwitcherVisibility = function() { + this.hide(); + }; + } + + disable() { + global.workspace_manager.override_workspace_layout( + Meta.DisplayCorner.TOPLEFT, + false, + -1, + 1); + + ThumbnailsBox.prototype._updateSwitcherVisibility = + this._origUpdateSwitcherVisibility; + } +} + +function init() { + return new Extension(); +} diff --git a/extensions/horizontal-workspaces/meson.build b/extensions/horizontal-workspaces/meson.build new file mode 100644 index 00000000..48504f63 --- /dev/null +++ b/extensions/horizontal-workspaces/meson.build @@ -0,0 +1,5 @@ +extension_data += configure_file( + input: metadata_name + '.in', + output: metadata_name, + configuration: metadata_conf +) diff --git a/extensions/horizontal-workspaces/metadata.json.in b/extensions/horizontal-workspaces/metadata.json.in new file mode 100644 index 00000000..f109e068 --- /dev/null +++ b/extensions/horizontal-workspaces/metadata.json.in @@ -0,0 +1,10 @@ +{ +"extension-id": "@extension_id@", +"uuid": "@uuid@", +"settings-schema": "@gschemaname@", +"gettext-domain": "@gettext_domain@", +"name": "Horizontal workspaces", +"description": "Use a horizontal workspace layout", +"shell-version": [ "@shell_current@" ], +"url": "@url@" +} diff --git a/extensions/horizontal-workspaces/stylesheet.css b/extensions/horizontal-workspaces/stylesheet.css new file mode 100644 index 00000000..25134b65 --- /dev/null +++ b/extensions/horizontal-workspaces/stylesheet.css @@ -0,0 +1 @@ +/* This extensions requires no special styling */ diff --git a/meson.build b/meson.build index 1756face..16a48cf3 100644 --- a/meson.build +++ b/meson.build @@ -33,6 +33,7 @@ uuid_suffix = '@gnome-shell-extensions.gcampax.github.com' classic_extensions = [ 'apps-menu', + 'horizontal-workspaces', 'places-menu', 'launch-new-instance', 'window-list' From f8bae050368408df285b6471121528b4c1a676ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 19 Jul 2019 20:24:44 +0200 Subject: [PATCH 67/78] cleanup: Stop using PopupMenuItem.actor properties Popup menu items are now actor subclasses, and their actor property points to the item itself. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/84 --- extensions/drive-menu/extension.js | 2 +- extensions/window-list/extension.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/drive-menu/extension.js b/extensions/drive-menu/extension.js index 3b17f565..963abfe8 100644 --- a/extensions/drive-menu/extension.js +++ b/extensions/drive-menu/extension.js @@ -152,7 +152,7 @@ class DriveMenu extends PanelMenu.Button { } _updateMenuVisibility() { - if (this._mounts.filter(i => i.actor.visible).length > 0) + if (this._mounts.filter(i => i.visible).length > 0) this.show(); else this.hide(); diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 6af96344..690c407c 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -435,12 +435,12 @@ class AppContextMenu extends PopupMenu.PopupMenu { open(animate) { let windows = this._appButton.getWindowList(); - this._minimizeItem.actor.visible = windows.some(w => !w.minimized); - this._unminimizeItem.actor.visible = windows.some(w => w.minimized); - this._maximizeItem.actor.visible = windows.some(w => { + this._minimizeItem.visible = windows.some(w => !w.minimized); + this._unminimizeItem.visible = windows.some(w => w.minimized); + this._maximizeItem.visible = windows.some(w => { return w.get_maximized() != Meta.MaximizeFlags.BOTH; }); - this._unmaximizeItem.actor.visible = windows.some(w => { + this._unmaximizeItem.visible = windows.some(w => { return w.get_maximized() == Meta.MaximizeFlags.BOTH; }); @@ -605,7 +605,7 @@ class AppButton extends BaseButton { for (let i = 0; i < windows.length; i++) { let windowTitle = new WindowTitle(windows[i]); let item = new PopupMenu.PopupBaseMenuItem(); - item.actor.add_actor(windowTitle.actor); + item.add_actor(windowTitle.actor); item._window = windows[i]; this._menu.addMenuItem(item); } From 5b7631898c5ef9057edca390b14d2dccc68df2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 19 Jul 2019 20:45:27 +0200 Subject: [PATCH 68/78] cleanup: Use GObject.NotImplementedError Since version 1.50.0, gjs defines GObject.NotImplementedError for throwing errors when a virtual method that requires a subclass implementation is not defined. So use this instead of a generic JS Error in such cases. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/84 --- extensions/window-list/extension.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 690c407c..a89a449e 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -251,7 +251,8 @@ class BaseButton { } _onClicked(_actor, _button) { - throw new Error('Not implemented'); + throw new GObject.NotImplementedError( + `_onClicked in ${this.constructor.name}`); } _canOpenPopupMenu() { @@ -265,7 +266,8 @@ class BaseButton { } _isFocused() { - throw new Error('Not implemented'); + throw new GObject.NotImplementedError( + `_isFocused in ${this.constructor.name}`); } _updateStyle() { @@ -276,7 +278,8 @@ class BaseButton { } _windowEnteredOrLeftMonitor(_metaDisplay, _monitorIndex, _metaWindow) { - throw new Error('Not implemented'); + throw new GObject.NotImplementedError( + `_windowEnteredOrLeftMonitor in ${this.constructor.name}`); } _isWindowVisible(window) { @@ -288,7 +291,8 @@ class BaseButton { } _updateVisibility() { - throw new Error('Not implemented'); + throw new GObject.NotImplementedError( + `_updateVisibility in ${this.constructor.name}`); } _getIconGeometry() { @@ -301,7 +305,8 @@ class BaseButton { } _updateIconGeometry() { - throw new Error('Not implemented'); + throw new GObject.NotImplementedError( + `_updateIconGeometry in ${this.constructor.name}`); } _onDestroy() { From b6a6de9bb5eda0db59bad59e20c5a31a09415777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 19 Jul 2019 16:00:36 +0200 Subject: [PATCH 69/78] window-list: Actorize gnome-shell is in the process of moving from composition to subclassing. Do the same here, and use custom actor classes instead of "actor" and "_delegate" properties. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/84 --- extensions/window-list/extension.js | 190 +++++++++++++------------ extensions/window-list/windowPicker.js | 34 +++-- 2 files changed, 116 insertions(+), 108 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index a89a449e..057f2640 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -1,5 +1,5 @@ /* exported init */ -const { Clutter, Gio, GLib, Gtk, Meta, Shell, St } = imports.gi; +const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi; const DND = imports.ui.dnd; const ExtensionUtils = imports.misc.extensionUtils; @@ -133,19 +133,22 @@ class WindowContextMenu extends PopupMenu.PopupMenu { } } -class WindowTitle { - constructor(metaWindow) { +const WindowTitle = GObject.registerClass({ + GTypeName: 'WindowListWindowTitle' +}, class WindowTitle extends St.BoxLayout { + _init(metaWindow) { this._metaWindow = metaWindow; - this.actor = new St.BoxLayout({ + + super._init({ style_class: 'window-button-box', x_expand: true, y_expand: true }); this._icon = new St.Bin({ style_class: 'window-button-icon' }); - this.actor.add(this._icon); + this.add(this._icon); this.label_actor = new St.Label({ y_align: Clutter.ActorAlign.CENTER }); - this.actor.add(this.label_actor); + this.add(this.label_actor); this._textureCache = St.TextureCache.get_default(); this._iconThemeChangedId = this._textureCache.connect( @@ -156,7 +159,7 @@ class WindowTitle { 'notify::gtk-application-id', this._updateIcon.bind(this)); this._updateIcon(); - this.actor.connect('destroy', this._onDestroy.bind(this)); + this.connect('destroy', this._onDestroy.bind(this)); this._notifyTitleId = this._metaWindow.connect( 'notify::title', this._updateTitle.bind(this)); @@ -198,33 +201,32 @@ class WindowTitle { this._metaWindow.disconnect(this._notifyWmClass); this._metaWindow.disconnect(this._notifyAppId); } -} +}); -class BaseButton { - constructor(perMonitor, monitorIndex) { - if (this.constructor === BaseButton) - throw new TypeError('Cannot instantiate abstract class BaseButton'); - +const BaseButton = GObject.registerClass({ + GTypeName: 'WindowListBaseButton', + GTypeFlags: GObject.TypeFlags.ABSTRACT +}, class BaseButton extends St.Button { + _init(perMonitor, monitorIndex) { this._perMonitor = perMonitor; this._monitorIndex = monitorIndex; - this.actor = new St.Button({ + super._init({ style_class: 'window-button', x_fill: true, y_fill: true, can_focus: true, button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE }); - this.actor._delegate = this; - this.actor.connect('allocation-changed', + this.connect('allocation-changed', this._updateIconGeometry.bind(this)); - this.actor.connect('clicked', this._onClicked.bind(this)); - this.actor.connect('destroy', this._onDestroy.bind(this)); - this.actor.connect('popup-menu', this._onPopupMenu.bind(this)); + this.connect('clicked', this._onClicked.bind(this)); + this.connect('destroy', this._onDestroy.bind(this)); + this.connect('popup-menu', this._onPopupMenu.bind(this)); - this._contextMenuManager = new PopupMenu.PopupMenuManager(this.actor); + this._contextMenuManager = new PopupMenu.PopupMenuManager(this); this._switchWorkspaceId = global.window_manager.connect( 'switch-workspace', this._updateVisibility.bind(this)); @@ -240,14 +242,14 @@ class BaseButton { } get active() { - return this.actor.has_style_class_name('focused'); + return this.has_style_class_name('focused'); } activate() { if (this.active) return; - this._onClicked(this.actor, 1); + this._onClicked(this, 1); } _onClicked(_actor, _button) { @@ -272,9 +274,9 @@ class BaseButton { _updateStyle() { if (this._isFocused()) - this.actor.add_style_class_name('focused'); + this.add_style_class_name('focused'); else - this.actor.remove_style_class_name('focused'); + this.remove_style_class_name('focused'); } _windowEnteredOrLeftMonitor(_metaDisplay, _monitorIndex, _metaWindow) { @@ -298,8 +300,8 @@ class BaseButton { _getIconGeometry() { let rect = new Meta.Rectangle(); - [rect.x, rect.y] = this.actor.get_transformed_position(); - [rect.width, rect.height] = this.actor.get_transformed_size(); + [rect.x, rect.y] = this.get_transformed_position(); + [rect.width, rect.height] = this.get_transformed_size(); return rect; } @@ -320,21 +322,23 @@ class BaseButton { global.display.disconnect(this._windowLeftMonitorId); this._windowLeftMonitorId = 0; } -} +}); -class WindowButton extends BaseButton { - constructor(metaWindow, perMonitor, monitorIndex) { - super(perMonitor, monitorIndex); +const WindowButton = GObject.registerClass({ + GTypeName: 'WindowListWindowButton' +}, class WindowButton extends BaseButton { + _init(metaWindow, perMonitor, monitorIndex) { + super._init(perMonitor, monitorIndex); this.metaWindow = metaWindow; this._updateVisibility(); this._windowTitle = new WindowTitle(this.metaWindow); - this.actor.set_child(this._windowTitle.actor); - this.actor.label_actor = this._windowTitle.label_actor; + this.set_child(this._windowTitle); + this.label_actor = this._windowTitle.label_actor; - this._contextMenu = new WindowContextMenu(this.actor, this.metaWindow); + this._contextMenu = new WindowContextMenu(this, this.metaWindow); this._contextMenu.connect('open-state-changed', _onMenuStateChanged); this._contextMenu.actor.hide(); this._contextMenuManager.addMenu(this._contextMenu); @@ -368,9 +372,9 @@ class WindowButton extends BaseButton { super._updateStyle(); if (this.metaWindow.minimized) - this.actor.add_style_class_name('minimized'); + this.add_style_class_name('minimized'); else - this.actor.remove_style_class_name('minimized'); + this.remove_style_class_name('minimized'); } _windowEnteredOrLeftMonitor(metaDisplay, monitorIndex, metaWindow) { @@ -379,7 +383,7 @@ class WindowButton extends BaseButton { } _updateVisibility() { - this.actor.visible = this._isWindowVisible(this.metaWindow); + this.visible = this._isWindowVisible(this.metaWindow); } _updateIconGeometry() { @@ -392,14 +396,14 @@ class WindowButton extends BaseButton { global.display.disconnect(this._notifyFocusId); this._contextMenu.destroy(); } -} +}); class AppContextMenu extends PopupMenu.PopupMenu { - constructor(source, appButton) { + constructor(source) { super(source, 0.5, St.Side.BOTTOM); - this._appButton = appButton; + this._appButton = source; this._minimizeItem = new PopupMenu.PopupMenuItem(_('Minimize all')); this._minimizeItem.connect('activate', () => { @@ -453,15 +457,17 @@ class AppContextMenu extends PopupMenu.PopupMenu { } } -class AppButton extends BaseButton { - constructor(app, perMonitor, monitorIndex) { - super(perMonitor, monitorIndex); +const AppButton = GObject.registerClass({ + GTypeName: 'WindowListAppButton', +}, class AppButton extends BaseButton { + _init(app, perMonitor, monitorIndex) { + super._init(perMonitor, monitorIndex); this.app = app; this._updateVisibility(); let stack = new St.Widget({ layout_manager: new Clutter.BinLayout() }); - this.actor.set_child(stack); + this.set_child(stack); this._singleWindowTitle = new St.Bin({ x_expand: true, @@ -489,15 +495,15 @@ class AppButton extends BaseButton { this._multiWindowTitle.add(label); this._multiWindowTitle.label_actor = label; - this._menuManager = new PopupMenu.PopupMenuManager(this.actor); - this._menu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.BOTTOM); + this._menuManager = new PopupMenu.PopupMenuManager(this); + this._menu = new PopupMenu.PopupMenu(this, 0.5, St.Side.BOTTOM); this._menu.connect('open-state-changed', _onMenuStateChanged); this._menu.actor.hide(); this._menu.connect('activate', this._onMenuActivate.bind(this)); this._menuManager.addMenu(this._menu); Main.uiGroup.add_actor(this._menu.actor); - this._appContextMenu = new AppContextMenu(this.actor, this); + this._appContextMenu = new AppContextMenu(this); this._appContextMenu.connect('open-state-changed', _onMenuStateChanged); this._appContextMenu.actor.hide(); Main.uiGroup.add_actor(this._appContextMenu.actor); @@ -530,9 +536,9 @@ class AppButton extends BaseButton { if (!this._perMonitor) { // fast path: use ShellApp API to avoid iterating over all windows. let workspace = global.workspace_manager.get_active_workspace(); - this.actor.visible = this.app.is_on_workspace(workspace); + this.visible = this.app.is_on_workspace(workspace); } else { - this.actor.visible = this.getWindowList().length >= 1; + this.visible = this.getWindowList().length >= 1; } } @@ -560,8 +566,8 @@ class AppButton extends BaseButton { if (!this._windowTitle) { this.metaWindow = windows[0]; this._windowTitle = new WindowTitle(this.metaWindow); - this._singleWindowTitle.child = this._windowTitle.actor; - this._windowContextMenu = new WindowContextMenu(this.actor, this.metaWindow); + this._singleWindowTitle.child = this._windowTitle; + this._windowContextMenu = new WindowContextMenu(this, this.metaWindow); this._windowContextMenu.connect( 'open-state-changed', _onMenuStateChanged); Main.uiGroup.add_actor(this._windowContextMenu.actor); @@ -570,7 +576,7 @@ class AppButton extends BaseButton { } this._contextMenuManager.removeMenu(this._appContextMenu); this._contextMenu = this._windowContextMenu; - this.actor.label_actor = this._windowTitle.label_actor; + this.label_actor = this._windowTitle.label_actor; } else { if (this._windowTitle) { this.metaWindow = null; @@ -581,7 +587,7 @@ class AppButton extends BaseButton { } this._contextMenu = this._appContextMenu; this._contextMenuManager.addMenu(this._appContextMenu); - this.actor.label_actor = this._multiWindowTitle.label_actor; + this.label_actor = this._multiWindowTitle.label_actor; } } @@ -610,7 +616,7 @@ class AppButton extends BaseButton { for (let i = 0; i < windows.length; i++) { let windowTitle = new WindowTitle(windows[i]); let item = new PopupMenu.PopupBaseMenuItem(); - item.add_actor(windowTitle.actor); + item.add_actor(windowTitle); item._window = windows[i]; this._menu.addMenuItem(item); } @@ -638,25 +644,27 @@ class AppButton extends BaseButton { this.app.disconnect(this._windowsChangedId); this._menu.destroy(); } -} +}); -class WindowList { - constructor(perMonitor, monitor) { +const WindowList = GObject.registerClass({ + GTypeName: 'WindowListWindowList', +}, class WindowList extends St.Widget { + _init(perMonitor, monitor) { this._perMonitor = perMonitor; this._monitor = monitor; - this.actor = new St.Widget({ + super._init({ name: 'panel', style_class: 'bottom-panel solid', reactive: true, track_hover: true, layout_manager: new Clutter.BinLayout() }); - this.actor.connect('destroy', this._onDestroy.bind(this)); + this.connect('destroy', this._onDestroy.bind(this)); let box = new St.BoxLayout({ x_expand: true, y_expand: true }); - this.actor.add_actor(box); + this.add_actor(box); let toggle = new WindowPickerToggle(); box.add_actor(toggle); @@ -697,18 +705,18 @@ class WindowList { this._updateWorkspaceIndicatorVisibility.bind(this)); this._updateWorkspaceIndicatorVisibility(); - this._menuManager = new PopupMenu.PopupMenuManager(this.actor); + this._menuManager = new PopupMenu.PopupMenuManager(this); this._menuManager.addMenu(this._workspaceIndicator.menu); - Main.layoutManager.addChrome(this.actor, { + Main.layoutManager.addChrome(this, { affectsStruts: true, trackFullscreen: true }); - Main.uiGroup.set_child_above_sibling(this.actor, Main.layoutManager.panelBox); - Main.ctrlAltTabManager.addGroup(this.actor, _('Window List'), 'start-here-symbolic'); + Main.uiGroup.set_child_above_sibling(this, Main.layoutManager.panelBox); + Main.ctrlAltTabManager.addGroup(this, _('Window List'), 'start-here-symbolic'); - this.actor.width = this._monitor.width; - this.actor.connect('notify::height', this._updatePosition.bind(this)); + this.width = this._monitor.width; + this.connect('notify::height', this._updatePosition.bind(this)); this._updatePosition(); this._appSystem = Shell.AppSystem.get_default(); @@ -723,10 +731,10 @@ class WindowList { keyboardBox.visible = state; if (state) { Main.uiGroup.set_child_above_sibling( - this.actor, keyboardBox); + this, keyboardBox); } else { Main.uiGroup.set_child_above_sibling( - this.actor, Main.layoutManager.panelBox); + this, Main.layoutManager.panelBox); } this._updateKeyboardAnchor(); }); @@ -742,12 +750,12 @@ class WindowList { 'switch-workspace', this._checkGrouping.bind(this)); this._overviewShowingId = Main.overview.connect('showing', () => { - this.actor.hide(); + this.hide(); this._updateKeyboardAnchor(); }); this._overviewHidingId = Main.overview.connect('hiding', () => { - this.actor.visible = !Main.layoutManager.primaryMonitor.inFullscreen; + this.visible = !Main.layoutManager.primaryMonitor.inFullscreen; this._updateKeyboardAnchor(); }); @@ -785,17 +793,16 @@ class WindowList { return; let children = this._windowList.get_children() - .filter(c => c.visible) - .map(a => a._delegate); + .filter(c => c.visible); let active = children.findIndex(c => c.active); let newActive = Math.max(0, Math.min(active + diff, children.length - 1)); children[newActive].activate(); } _updatePosition() { - this.actor.set_position( + this.set_position( this._monitor.x, - this._monitor.y + this._monitor.height - this.actor.height); + this._monitor.y + this._monitor.height - this.height); } _updateWorkspaceIndicatorVisibility() { @@ -842,7 +849,7 @@ class WindowList { _getMaxWindowListWidth() { let indicatorsBox = this._workspaceIndicator.get_parent(); - return this.actor.width - indicatorsBox.get_preferred_width(-1)[1]; + return this.width - indicatorsBox.get_preferred_width(-1)[1]; } _groupingModeChanged() { @@ -894,7 +901,7 @@ class WindowList { if (!Main.keyboard.actor) return; - let translationY = Main.overview.visible ? 0 : this.actor.height; + let translationY = Main.overview.visible ? 0 : this.height; Main.keyboard.actor.translation_y = -translationY; } @@ -910,7 +917,7 @@ class WindowList { _addApp(app) { let button = new AppButton(app, this._perMonitor, this._monitor.index); - this._windowList.layout_manager.pack(button.actor, + this._windowList.layout_manager.pack(button, true, true, true, Clutter.BoxAlignment.START, Clutter.BoxAlignment.START); @@ -918,7 +925,7 @@ class WindowList { _removeApp(app) { let children = this._windowList.get_children(); - let child = children.find(c => c._delegate.app == app); + let child = children.find(c => c.app == app); if (child) child.destroy(); } @@ -934,11 +941,11 @@ class WindowList { return; let children = this._windowList.get_children(); - if (children.find(c => c._delegate.metaWindow == win)) + if (children.find(c => c.metaWindow == win)) return; let button = new WindowButton(win, this._perMonitor, this._monitor.index); - this._windowList.layout_manager.pack(button.actor, + this._windowList.layout_manager.pack(button, true, true, true, Clutter.BoxAlignment.START, Clutter.BoxAlignment.START); @@ -955,7 +962,7 @@ class WindowList { return; // not actually removed, just moved to another workspace let children = this._windowList.get_children(); - let child = children.find(c => c._delegate.metaWindow == win); + let child = children.find(c => c.metaWindow == win); if (child) child.destroy(); } @@ -1004,15 +1011,12 @@ class WindowList { _onDragMotion(dragEvent) { if (Main.overview.visible || - !this.actor.contains(dragEvent.targetActor)) { + !this.contains(dragEvent.targetActor)) { this._removeActivateTimeout(); return DND.DragMotionResult.CONTINUE; } - let hoveredWindow = null; - if (dragEvent.targetActor._delegate) - hoveredWindow = dragEvent.targetActor._delegate.metaWindow; - + let hoveredWindow = dragEvent.targetActor.metaWindow; if (!hoveredWindow || this._dndWindow == hoveredWindow) return DND.DragMotionResult.CONTINUE; @@ -1037,7 +1041,7 @@ class WindowList { let [x, y] = global.get_pointer(); let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y); - if (this._dndWindow && this.actor.contains(pickedActor)) + if (this._dndWindow && this.contains(pickedActor)) this._dndWindow.activate(global.get_current_time()); this._dndWindow = null; this._dndTimeoutId = 0; @@ -1051,7 +1055,7 @@ class WindowList { this._workspaceIndicator.destroy(); - Main.ctrlAltTabManager.removeGroup(this.actor); + Main.ctrlAltTabManager.removeGroup(this); this._appSystem.disconnect(this._appStateChangedId); this._appStateChangedId = 0; @@ -1083,7 +1087,7 @@ class WindowList { for (let i = 0; i < windows.length; i++) windows[i].metaWindow.set_icon_geometry(null); } -} +}); class Extension { constructor() { @@ -1112,7 +1116,7 @@ class Extension { } _buildWindowLists() { - this._windowLists.forEach(list => list.actor.destroy()); + this._windowLists.forEach(list => list.destroy()); this._windowLists = []; let showOnAllMonitors = this._settings.get_boolean('show-on-all-monitors'); @@ -1134,19 +1138,19 @@ class Extension { this._monitorsChangedId = 0; this._windowLists.forEach(windowList => { - windowList.actor.hide(); - windowList.actor.destroy(); + windowList.hide(); + windowList.destroy(); }); this._windowLists = null; - Main.windowPicker.actor.destroy(); + Main.windowPicker.destroy(); delete Main.windowPicker; Main.overview.hide = this._hideOverviewOrig; } someWindowListContains(actor) { - return this._windowLists.some(list => list.actor.contains(actor)); + return this._windowLists.some(list => list.contains(actor)); } } diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js index 12a7627f..e27bbb5c 100644 --- a/extensions/window-list/windowPicker.js +++ b/extensions/window-list/windowPicker.js @@ -1,6 +1,5 @@ /* exported WindowPicker, WindowPickerToggle */ const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; -const Signals = imports.signals; const Layout = imports.ui.layout; const Main = imports.ui.main; @@ -51,7 +50,7 @@ let MyWorkspacesDisplay = class extends WorkspacesDisplay { this._workspacesViews.forEach(v => { Main.layoutManager.overviewGroup.remove_actor(v.actor); - Main.windowPicker.actor.add_actor(v.actor); + Main.windowPicker.add_actor(v.actor); }); } @@ -62,27 +61,33 @@ let MyWorkspacesDisplay = class extends WorkspacesDisplay { } }; -var WindowPicker = class { - constructor() { +var WindowPicker = GObject.registerClass({ + GTypeName: 'WindowListWindowPicker', + Signals: { + 'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] }, + 'scroll-event': { param_types: [Clutter.Event.$gtype] } + } +}, class extends Clutter.Actor { + _init() { this._visible = false; this._modal = false; this._overlayKeyId = 0; this._stageKeyPressId = 0; - this.actor = new Clutter.Actor(); + super._init(); - this.actor.connect('destroy', this._onDestroy.bind(this)); + this.connect('destroy', this._onDestroy.bind(this)); global.bind_property('screen-width', - this.actor, 'width', + this, 'width', GObject.BindingFlags.SYNC_CREATE); global.bind_property('screen-height', - this.actor, 'height', + this, 'height', GObject.BindingFlags.SYNC_CREATE); this._backgroundGroup = new Meta.BackgroundGroup({ reactive: true }); - this.actor.add_child(this._backgroundGroup); + this.add_child(this._backgroundGroup); this._backgroundGroup.connect('scroll-event', (a, ev) => { this.emit('scroll-event', ev); @@ -93,7 +98,7 @@ var WindowPicker = class { Main.overview.addAction = a => this._backgroundGroup.add_action(a); this._workspacesDisplay = new MyWorkspacesDisplay(); - this.actor.add_child(this._workspacesDisplay.actor); + this.add_child(this._workspacesDisplay.actor); Main.overview.addAction = addActionOrig; @@ -103,7 +108,7 @@ var WindowPicker = class { this._updateBackgrounds.bind(this)); this._updateBackgrounds(); - Main.uiGroup.insert_child_below(this.actor, global.window_group); + Main.uiGroup.insert_child_below(this, global.window_group); if (!Main.sessionMode.hasOverview) { this._overlayKeyId = global.display.connect('overlay-key', () => { @@ -194,7 +199,7 @@ var WindowPicker = class { if (this._modal) return true; - this._modal = Main.pushModal(this.actor, { + this._modal = Main.pushModal(this, { actionMode: Shell.ActionMode.OVERVIEW }); @@ -203,7 +208,7 @@ var WindowPicker = class { return false; } } else if (this._modal) { - Main.popModal(this.actor); + Main.popModal(this); this._modal = false; } return true; @@ -234,8 +239,7 @@ var WindowPicker = class { _unshadeBackgrounds() { Main.overview._unshadeBackgrounds.call(this); } -}; -Signals.addSignalMethods(WindowPicker.prototype); +}); var WindowPickerToggle = GObject.registerClass( class WindowPickerToggle extends St.Button { From 1a13f29b0ccdc3170db66ebb211bb1b50755fa2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Sat, 20 Jul 2019 14:01:47 +0200 Subject: [PATCH 70/78] Update POTFILES.in --- po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 9c1438ac..8b74e88b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,6 +15,7 @@ extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml extensions/window-list/extension.js extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml extensions/window-list/prefs.js +extensions/window-list/workspaceIndicator.js extensions/windowsNavigator/extension.js extensions/workspace-indicator/extension.js extensions/workspace-indicator/prefs.js From a41bcd4f10c93d9feea421351a0301cb24e950fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 19 Jul 2019 19:25:34 +0200 Subject: [PATCH 71/78] Bump version to 3.33.4 Update NEWS. --- NEWS | 19 +++++++++++++++++++ meson.build | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index bc707b51..5d403b29 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,22 @@ +3.33.4 +====== +* Make GNOME Classic more classic: + - Disable GNOME 3 overview [Florian; !69] + - Add window picker button to window list [Florian; !73, !80] + - Style improvements and fixes [Jakub; #169, !82] + - Support horizontal workspace layout in window list [Florian; !70] + - Add draggable previews to window list workspace switcher [Florian; !74] + - Arrange workspaces horizontally [Florian; !72] +* workspace-indicator: Support horizontal workspace layout [Florian; !71] +* workspace-indicator: Add draggable previews [Florian; !77] +* Misc. bug fixes and cleanups [Florian; !75, !76, !79, !78, #168, !84] + +Contributors: + Florian Müllner, Jakub Steiner, Jor Teron + +Translators: + Jor Teron [mjw] + 3.33.3 ====== * Misc. bug fixes [Florian, Marco; !67, !68] diff --git a/meson.build b/meson.build index 16a48cf3..a9e6e081 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.33.3', + version: '3.33.4', meson_version: '>= 0.44.0', license: 'GPL2+' ) From f9b87f9b44689216380d6721487f891472211849 Mon Sep 17 00:00:00 2001 From: Jor Teron Date: Thu, 25 Jul 2019 10:46:02 +0000 Subject: [PATCH 72/78] Update Karbi translation --- po/mjw.po | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/po/mjw.po b/po/mjw.po index 0bb0df8e..6777da99 100644 --- a/po/mjw.po +++ b/po/mjw.po @@ -8,10 +8,10 @@ msgstr "" "Project-Id-Version: gnome-shell-extensions master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/" "issues\n" -"POT-Creation-Date: 2019-07-14 04:31+0000\n" -"PO-Revision-Date: 2019-07-16 08:19+0530\n" +"POT-Creation-Date: 2019-07-02 19:23+0000\n" +"PO-Revision-Date: 2019-07-25 00:00+0530\n" "Last-Translator: Jor Teron \n" -"Language-Team: Karbi \n" +"Language-Team: Karbi \n" "Language: mjw\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -63,14 +63,14 @@ msgstr "" #: extensions/auto-move-windows/prefs.js:117 msgid "Add" -msgstr "" +msgstr "Kethap" #. TRANSLATORS: %s is the filesystem name #: extensions/drive-menu/extension.js:102 #: extensions/places-menu/placeDisplay.js:232 #, javascript-format msgid "Ejecting drive “%s” failed:" -msgstr "" +msgstr "Drive “%s” patet un-eh:" #: extensions/drive-menu/extension.js:118 msgid "Removable devices" @@ -105,12 +105,12 @@ msgstr "" #: extensions/places-menu/extension.js:80 #: extensions/places-menu/extension.js:84 msgid "Places" -msgstr "Places" +msgstr "" #: extensions/places-menu/placeDisplay.js:46 #, javascript-format msgid "Failed to launch “%s”" -msgstr "“%s” ingpu un-eh" +msgstr "“%s” Ingpu un-eh" #: extensions/places-menu/placeDisplay.js:61 #, javascript-format @@ -128,7 +128,7 @@ msgstr "Home" #: extensions/places-menu/placeDisplay.js:403 msgid "Browse Network" -msgstr "" +msgstr "Network kelang" #: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:7 msgid "Cycle Screenshot Sizes" @@ -217,7 +217,7 @@ msgstr "" #: extensions/window-list/prefs.js:25 msgid "Window Grouping" -msgstr "Window muluk" +msgstr "Windows muluk" #: extensions/window-list/prefs.js:47 msgid "Never group windows" @@ -241,7 +241,7 @@ msgstr "Workspace amen hai" #: extensions/workspace-indicator/prefs.js:151 msgid "Name" -msgstr "Amen" +msgstr "Men" #: extensions/workspace-indicator/prefs.js:191 #, javascript-format From 827af154b8a6f5a496b85b4df499cd012540131f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 19 Jul 2019 19:55:13 +0200 Subject: [PATCH 73/78] window-list: Support showing windows from all workspaces gnome-panel's window list applet has such an option, so let's support it as well. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/154 --- extensions/window-list/extension.js | 35 +++++++++++++++++-- ...e.shell.extensions.window-list.gschema.xml | 7 ++++ extensions/window-list/prefs.js | 7 ++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 057f2640..87b8c3db 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -206,11 +206,18 @@ const WindowTitle = GObject.registerClass({ const BaseButton = GObject.registerClass({ GTypeName: 'WindowListBaseButton', - GTypeFlags: GObject.TypeFlags.ABSTRACT + GTypeFlags: GObject.TypeFlags.ABSTRACT, + Properties: { + 'ignore-workspace': GObject.ParamSpec.boolean( + 'ignore-workspace', 'ignore-workspace', 'ignore-workspace', + GObject.ParamFlags.READWRITE, + false) + } }, class BaseButton extends St.Button { _init(perMonitor, monitorIndex) { this._perMonitor = perMonitor; this._monitorIndex = monitorIndex; + this._ignoreWorkspace = false; super._init({ style_class: 'window-button', @@ -245,6 +252,22 @@ const BaseButton = GObject.registerClass({ return this.has_style_class_name('focused'); } + // eslint-disable-next-line camelcase + get ignore_workspace() { + return this._ignoreWorkspace; + } + + // eslint-disable-next-line camelcase + set ignore_workspace(ignore) { + if (this._ignoreWorkspace == ignore) + return; + + this._ignoreWorkspace = ignore; + this.notify('ignore-workspace'); + + this._updateVisibility(); + } + activate() { if (this.active) return; @@ -288,7 +311,7 @@ const BaseButton = GObject.registerClass({ let workspace = global.workspace_manager.get_active_workspace(); return !window.skip_taskbar && - window.located_on_workspace(workspace) && + (this._ignoreWorkspace || window.located_on_workspace(workspace)) && (!this._perMonitor || window.get_monitor() == this._monitorIndex); } @@ -533,7 +556,9 @@ const AppButton = GObject.registerClass({ } _updateVisibility() { - if (!this._perMonitor) { + if (this._ignoreWorkspace) { + this.visible = true; + } else if (!this._perMonitor) { // fast path: use ShellApp API to avoid iterating over all windows. let workspace = global.workspace_manager.get_active_workspace(); this.visible = this.app.is_on_workspace(workspace); @@ -917,6 +942,8 @@ const WindowList = GObject.registerClass({ _addApp(app) { let button = new AppButton(app, this._perMonitor, this._monitor.index); + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); this._windowList.layout_manager.pack(button, true, true, true, Clutter.BoxAlignment.START, @@ -945,6 +972,8 @@ const WindowList = GObject.registerClass({ return; let button = new WindowButton(win, this._perMonitor, this._monitor.index); + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); this._windowList.layout_manager.pack(button, true, true, true, Clutter.BoxAlignment.START, diff --git a/extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml b/extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml index b7459417..299864cf 100644 --- a/extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml +++ b/extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml @@ -15,6 +15,13 @@ window list. Possible values are “never”, “auto” and “always”. + + false + Show windows from all workspaces + + Whether to show windows from all workspaces or only the current one. + + false Show the window list on all monitors diff --git a/extensions/window-list/prefs.js b/extensions/window-list/prefs.js index 78792b5a..ea3cb753 100644 --- a/extensions/window-list/prefs.js +++ b/extensions/window-list/prefs.js @@ -77,6 +77,13 @@ class WindowListPrefsWidget extends Gtk.Grid { }); this._settings.bind('show-on-all-monitors', check, 'active', Gio.SettingsBindFlags.DEFAULT); this.add(check); + + check = new Gtk.CheckButton({ + label: _('Show windows from all workspaces'), + margin_top: 6 + }); + this._settings.bind('display-all-workspaces', check, 'active', Gio.SettingsBindFlags.DEFAULT); + this.add(check); } }); From 974305417496a724423a4c54a2d869aa39815591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 10 Aug 2019 00:02:33 +0200 Subject: [PATCH 74/78] window-list: Don't override existing signal Since commit b6a6de9bb5 turned WindowPicker into a ClutterActor subclass, we already have a 'scroll-event' signal and don't need to define our own. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/86 --- extensions/window-list/windowPicker.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js index e27bbb5c..99da3563 100644 --- a/extensions/window-list/windowPicker.js +++ b/extensions/window-list/windowPicker.js @@ -64,8 +64,7 @@ let MyWorkspacesDisplay = class extends WorkspacesDisplay { var WindowPicker = GObject.registerClass({ GTypeName: 'WindowListWindowPicker', Signals: { - 'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] }, - 'scroll-event': { param_types: [Clutter.Event.$gtype] } + 'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] } } }, class extends Clutter.Actor { _init() { From af6f5fea540b8289f8a1d7c270c1543b6f889d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 10 Aug 2019 00:12:39 +0200 Subject: [PATCH 75/78] window-list: Adjust animation time gnome-shell changed all animations times to use milliseconds. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/86 --- extensions/window-list/extension.js | 2 +- extensions/window-list/windowPicker.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 87b8c3db..7b3b7c86 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -846,7 +846,7 @@ const WindowList = GObject.registerClass({ Tweener.addTween(this._windowList, { opacity: visible ? 255 : 0, transition: 'ease-out-quad', - time: Overview.ANIMATION_TIME + time: Overview.ANIMATION_TIME / 1000 }); this._windowList.reactive = visible; diff --git a/extensions/window-list/windowPicker.js b/extensions/window-list/windowPicker.js index 99da3563..bfac17fe 100644 --- a/extensions/window-list/windowPicker.js +++ b/extensions/window-list/windowPicker.js @@ -176,7 +176,7 @@ var WindowPicker = GObject.registerClass({ Main.overview.animationInProgress = true; GLib.timeout_add( GLib.PRIORITY_DEFAULT, - Overview.ANIMATION_TIME * 1000, + Overview.ANIMATION_TIME, () => { Main.overview.animationInProgress = false; if (onComplete) From 80de26dc161af0878df340070544f07c1d19b348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 7 Aug 2019 23:50:30 +0200 Subject: [PATCH 76/78] cleanup: Stop using Tweener gnome-shell added convenience API for Clutter animations and replaced Tweener everywhere; follow suite and do the same. https://gitlab.gnome.org/GNOME/gnome-shell-extensions/merge_requests/87 --- extensions/screenshot-window-sizer/extension.js | 12 ++++++------ extensions/window-list/extension.js | 7 +++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/extensions/screenshot-window-sizer/extension.js b/extensions/screenshot-window-sizer/extension.js index 2644ea31..44bad8e9 100644 --- a/extensions/screenshot-window-sizer/extension.js +++ b/extensions/screenshot-window-sizer/extension.js @@ -25,7 +25,7 @@ const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const Tweener = imports.ui.tweener; -const MESSAGE_FADE_TIME = 2; +const MESSAGE_FADE_TIME = 2000; let text; @@ -40,7 +40,7 @@ function flashMessage(message) { Main.uiGroup.add_actor(text); } - Tweener.removeTweens(text); + text.remove_all_transitions(); text.text = message; text.opacity = 255; @@ -50,11 +50,11 @@ function flashMessage(message) { monitor.x + Math.floor(monitor.width / 2 - text.width / 2), monitor.y + Math.floor(monitor.height / 2 - text.height / 2)); - Tweener.addTween(text, { + text.ease({ opacity: 0, - time: MESSAGE_FADE_TIME, - transition: 'easeOutQuad', - onComplete: hideMessage + duration: MESSAGE_FADE_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: hideMessage, }); } diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 7b3b7c86..ec6dbbec 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -6,7 +6,6 @@ const ExtensionUtils = imports.misc.extensionUtils; const Main = imports.ui.main; const Overview = imports.ui.overview; const PopupMenu = imports.ui.popupMenu; -const Tweener = imports.ui.tweener; const Me = ExtensionUtils.getCurrentExtension(); const { WindowPicker, WindowPickerToggle } = Me.imports.windowPicker; @@ -843,10 +842,10 @@ const WindowList = GObject.registerClass({ _updateWindowListVisibility() { let visible = !Main.windowPicker.visible; - Tweener.addTween(this._windowList, { + this._windowList.ease({ opacity: visible ? 255 : 0, - transition: 'ease-out-quad', - time: Overview.ANIMATION_TIME / 1000 + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + duration: Overview.ANIMATION_TIME, }); this._windowList.reactive = visible; From f486dfa112a11a015c1db9e236aa4b870014d646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 10 Aug 2019 00:40:11 +0200 Subject: [PATCH 77/78] Update sass submodule --- data/gnome-shell-sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gnome-shell-sass b/data/gnome-shell-sass index 478d47a1..c38a7b13 160000 --- a/data/gnome-shell-sass +++ b/data/gnome-shell-sass @@ -1 +1 @@ -Subproject commit 478d47a177b4a55f4805e737436b6ae427238b5c +Subproject commit c38a7b13207a2849ac5772eb348dc87527c3272c From c336e7d70ef61786c64a93f90aada9dfcc9b384a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 10 Aug 2019 00:41:55 +0200 Subject: [PATCH 78/78] Bump version to 3.33.90 Update NEWS. --- NEWS | 11 +++++++++++ meson.build | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5d403b29..41717f9f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +3.33.90 +======= +* window-list: Support showing windows from all workspaces [Florian; #154] +* Misc. bug fixes and cleanups [Florian; !86, !87] + +Contributors: + Florian Müllner + +Translators: + Jor Teron [mjw] + 3.33.4 ====== * Make GNOME Classic more classic: diff --git a/meson.build b/meson.build index a9e6e081..c32f57cf 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.33.4', + version: '3.33.90', meson_version: '>= 0.44.0', license: 'GPL2+' )