diff --git a/README.md b/README.md index ffbbed0..af69762 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This is a clone of the [Workspace Grid](https://github.com/zakkak/workspace-grid - Configurable timeout of the workspace switcher popup. - Two wraparound modes for navigating workspaces (optional). - Workspace labels in the workspace switcher popup (optional). +- Workspace overview on Super+W. ## Installation diff --git a/wsmatrix@martin.zurowietz.de/BaseWorkspaceSwitcherPopup.js b/wsmatrix@martin.zurowietz.de/BaseWorkspaceSwitcherPopup.js index ab57aba..9215a4c 100644 --- a/wsmatrix@martin.zurowietz.de/BaseWorkspaceSwitcherPopup.js +++ b/wsmatrix@martin.zurowietz.de/BaseWorkspaceSwitcherPopup.js @@ -12,8 +12,14 @@ class BaseWorkspaceSwitcherPopup extends WorkspaceSwitcherPopup { display(direction, activeWorkspaceIndex) { super.display(direction, activeWorkspaceIndex); - Mainloop.source_remove(this._timeoutId); - this._timeoutId = Mainloop.timeout_add(this._popupTimeout, this._onTimeout.bind(this)); - GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._onTimeout'); + if (this._timeoutId !== 0) { + Mainloop.source_remove(this._timeoutId); + this._timeoutId = 0; + } + + if (this._popupTimeout > 0) { + this._timeoutId = Mainloop.timeout_add(this._popupTimeout, this._onTimeout.bind(this)); + GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._onTimeout'); + } } }); diff --git a/wsmatrix@martin.zurowietz.de/WmOverride.js b/wsmatrix@martin.zurowietz.de/WmOverride.js index 3b2dbef..c26db6f 100644 --- a/wsmatrix@martin.zurowietz.de/WmOverride.js +++ b/wsmatrix@martin.zurowietz.de/WmOverride.js @@ -14,7 +14,7 @@ const WraparoundMode = { }; var WmOverride = class { - constructor(settings) { + constructor(settings, keybindings) { this.wm = Main.wm; this.settings = settings; this._mutterSettings = new Gio.Settings({ schema_id: 'org.gnome.mutter' }); @@ -22,6 +22,7 @@ var WmOverride = class { this.originalNumberOfWorkspaces = this.wsManager.n_workspaces; this.originalDynamicWorkspaces = this._mutterSettings.get_boolean('dynamic-workspaces'); this.originalAllowedKeybindings = {}; + this._keybindings = keybindings; this._overrideDynamicWorkspaces(); this._overrideKeybindingHandlers(); @@ -34,6 +35,7 @@ var WmOverride = class { this._handleWraparoundModeChanged(); this._connectSettings(); this._notify(); + this._addKeybindings(); } destroy() { @@ -44,6 +46,7 @@ var WmOverride = class { this._restoreNumberOfWorkspaces(); this._restoreDynamicWorkspaces(); this._notify(); + this._removeKeybindings(); } _connectSettings() { @@ -99,6 +102,70 @@ var WmOverride = class { this.settings.disconnect(this.settingsHandlerCachePopup); } + _addKeybindings() { + this.wm.addKeybinding( + 'workspace-overview-toggle', + this._keybindings, + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + this._toggleWorkspaceOverview.bind(this) + ); + } + + _removeKeybindings() { + this.wm.removeKeybinding('workspace-overview-toggle'); + } + + _addWsOverviewKeybindings(keybindings) { + this.wm.addKeybinding( + 'workspace-overview-right', + this._keybindings, + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + this._workspaceOverviewMoveRight.bind(this) + ); + + this.wm.addKeybinding( + 'workspace-overview-left', + this._keybindings, + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + this._workspaceOverviewMoveLeft.bind(this) + ); + + this.wm.addKeybinding( + 'workspace-overview-up', + this._keybindings, + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + this._workspaceOverviewMoveUp.bind(this) + ); + + this.wm.addKeybinding( + 'workspace-overview-down', + this._keybindings, + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + this._workspaceOverviewMoveDown.bind(this) + ); + + this.wm.addKeybinding( + 'workspace-overview-confirm', + this._keybindings, + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, + this._workspaceOverviewConfirm.bind(this) + ); + } + + _removeWsOverviewKeybindings() { + this.wm.removeKeybinding('workspace-overview-right'); + this.wm.removeKeybinding('workspace-overview-left'); + this.wm.removeKeybinding('workspace-overview-up'); + this.wm.removeKeybinding('workspace-overview-down'); + this.wm.removeKeybinding('workspace-overview-confirm'); + } + _handleNumberOfWorkspacesChanged() { this.rows = this.settings.get_int('num-rows'); this.columns = this.settings.get_int('num-columns'); @@ -256,39 +323,7 @@ var WmOverride = class { } direction = Meta.MotionDirection[target.toUpperCase()]; - newWs = workspaceManager.get_active_workspace().get_neighbor(direction); - - let currentIndex = workspaceManager.get_active_workspace_index(); - if (this.wraparoundMode !== WraparoundMode.NONE && currentIndex === newWs.index()) { - // Given a direction input the workspace has not changed, so do wraparound. - let targetRow = Math.floor(currentIndex / this.columns); - let targetColumn = currentIndex % this.columns; - - let offset = 0; - if (direction === Meta.MotionDirection.UP || direction === Meta.MotionDirection.LEFT) { - offset = -1; - } else if (direction === Meta.MotionDirection.DOWN || direction === Meta.MotionDirection.RIGHT) { - offset = 1; - } - - if (this.wraparoundMode === WraparoundMode.NEXT_PREV) { - targetRow += offset; - targetColumn += offset; - } else if (this.wraparoundMode === WraparoundMode.ROW_COL) { - if (direction === Meta.MotionDirection.UP || direction === Meta.MotionDirection.DOWN) { - targetRow += offset; - } else if (direction === Meta.MotionDirection.LEFT || direction === Meta.MotionDirection.RIGHT) { - targetColumn += offset; - } - } - - // Handle negative targets. - targetColumn = (targetColumn + this.columns) % this.columns; - targetRow = (targetRow + this.rows) % this.rows; - - target = targetRow * this.columns + targetColumn; - newWs = workspaceManager.get_workspace_by_index(target); - } + newWs = this._getTargetWorkspace(direction); } else if (target > 0) { target--; newWs = workspaceManager.get_workspace_by_index(target); @@ -307,22 +342,7 @@ var WmOverride = class { if (!Main.overview.visible && this.popupTimeout > 0) { if (this.wm._workspaceSwitcherPopup == null) { this.wm._workspaceTracker.blockUpdates(); - if (this.showThumbnails) { - this.wm._workspaceSwitcherPopup = new ThumbnailWsmatrixPopup( - this.rows, - this.columns, - this.scale, - this.popupTimeout, - this.cachePopup - ); - } else { - this.wm._workspaceSwitcherPopup = new IndicatorWsmatrixPopup( - this.rows, - this.columns, - this.popupTimeout, - this.showWorkspaceNames - ); - } + this.wm._workspaceSwitcherPopup = this._createNewPopup(); this.wm._workspaceSwitcherPopup.connect('destroy', () => { this.wm._workspaceTracker.unblockUpdates(); this.wm._workspaceSwitcherPopup = null; @@ -342,4 +362,106 @@ var WmOverride = class { } } } + + _getTargetWorkspace(direction) { + let newWs = this.wsManager.get_active_workspace().get_neighbor(direction); + let currentIndex = this.wsManager.get_active_workspace_index(); + if (this.wraparoundMode !== WraparoundMode.NONE && currentIndex === newWs.index()) { + // Given a direction input the workspace has not changed, so do wraparound. + let targetRow = Math.floor(currentIndex / this.columns); + let targetColumn = currentIndex % this.columns; + + let offset = 0; + if (direction === Meta.MotionDirection.UP || direction === Meta.MotionDirection.LEFT) { + offset = -1; + } else if (direction === Meta.MotionDirection.DOWN || direction === Meta.MotionDirection.RIGHT) { + offset = 1; + } + + if (this.wraparoundMode === WraparoundMode.NEXT_PREV) { + targetRow += offset; + targetColumn += offset; + } else if (this.wraparoundMode === WraparoundMode.ROW_COL) { + if (direction === Meta.MotionDirection.UP || direction === Meta.MotionDirection.DOWN) { + targetRow += offset; + } else if (direction === Meta.MotionDirection.LEFT || direction === Meta.MotionDirection.RIGHT) { + targetColumn += offset; + } + } + + // Handle negative targets. + targetColumn = (targetColumn + this.columns) % this.columns; + targetRow = (targetRow + this.rows) % this.rows; + + target = targetRow * this.columns + targetColumn; + newWs = this.wsManager.get_workspace_by_index(target); + } + + return newWs; + } + + _createNewPopup(timeout) { + timeout = timeout === undefined ? this.popupTimeout : timeout; + + if (this.showThumbnails) { + return new ThumbnailWsmatrixPopup( + this.rows, + this.columns, + this.scale, + timeout, + this.cachePopup + ); + } + + return new IndicatorWsmatrixPopup( + this.rows, + this.columns, + timeout, + this.showWorkspaceNames + ); + } + + _toggleWorkspaceOverview() { + if (this.wm._workspaceSwitcherPopup === null) { + this.wm._workspaceSwitcherPopup = this._createNewPopup(0); + this.wm._workspaceSwitcherPopup.connect('destroy', () => { + this.wm._workspaceTracker.unblockUpdates(); + this.wm._workspaceSwitcherPopup = null; + this.wm._isWorkspacePrepended = false; + this._removeWsOverviewKeybindings(); + }); + this.wm._workspaceSwitcherPopup.display(null, this.wsManager.get_active_workspace_index()); + this._addWsOverviewKeybindings(); + } else { + this._destroyWorkspaceSwitcherPopup(); + } + } + + _moveToWorkspace(direction) { + let workspace = this._getTargetWorkspace(direction); + this.wm.actionMoveWorkspace(workspace); + if (this.wm._workspaceSwitcherPopup) { + this.wm._workspaceSwitcherPopup.display(direction, workspace.index()); + } + } + + _workspaceOverviewMoveRight() { + this._moveToWorkspace(Meta.MotionDirection.RIGHT); + } + + _workspaceOverviewMoveLeft() { + this._moveToWorkspace(Meta.MotionDirection.LEFT); + } + + _workspaceOverviewMoveUp() { + this._moveToWorkspace(Meta.MotionDirection.UP); + } + + _workspaceOverviewMoveDown() { + this._moveToWorkspace(Meta.MotionDirection.DOWN); + } + + _workspaceOverviewConfirm() { + this._destroyWorkspaceSwitcherPopup(); + } } diff --git a/wsmatrix@martin.zurowietz.de/WorkspaceOverview.js b/wsmatrix@martin.zurowietz.de/WorkspaceOverview.js deleted file mode 100644 index ab80202..0000000 --- a/wsmatrix@martin.zurowietz.de/WorkspaceOverview.js +++ /dev/null @@ -1,27 +0,0 @@ -const Main = imports.ui.main; -const {Meta, Shell} = imports.gi; - -var WorkspaceOverview = class { - constructor(keybindings) { - this._addKeybindings(keybindings); - } - - _addKeybindings(keybindings) { - Main.wm.addKeybinding( - 'toggle-workspace-overview', - keybindings, - Meta.KeyBindingFlags.NONE, - Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, - this.toggle.bind(this) - ); - } - - toggle() { - log('TOGGLE'); - } - - destroy() { - Main.wm.removeKeybinding('toggle-workspace-overview'); - } - -}; diff --git a/wsmatrix@martin.zurowietz.de/extension.js b/wsmatrix@martin.zurowietz.de/extension.js index 76fba32..033ccf2 100644 --- a/wsmatrix@martin.zurowietz.de/extension.js +++ b/wsmatrix@martin.zurowietz.de/extension.js @@ -3,18 +3,15 @@ const Lang = imports.lang; const Meta = imports.gi.Meta; const Settings = WsMatrix.imports.Settings.Settings; const WmOverride = WsMatrix.imports.WmOverride.WmOverride; -const WorkspaceOverview = WsMatrix.imports.WorkspaceOverview.WorkspaceOverview; class WsMatrixExtension { constructor() { let settings = new Settings(WsMatrix.metadata['settings-schema']); let keybindings = new Settings(WsMatrix.metadata['keybindings-schema']); - this.override = new WmOverride(settings); - this.overview = new WorkspaceOverview(keybindings); + this.override = new WmOverride(settings, keybindings); } destroy() { this.override.destroy(); - this.overview.destroy(); } } diff --git a/wsmatrix@martin.zurowietz.de/schemas/gschemas.compiled b/wsmatrix@martin.zurowietz.de/schemas/gschemas.compiled index a8012cc..0f58401 100644 Binary files a/wsmatrix@martin.zurowietz.de/schemas/gschemas.compiled and b/wsmatrix@martin.zurowietz.de/schemas/gschemas.compiled differ diff --git a/wsmatrix@martin.zurowietz.de/schemas/org.gnome.shell.extensions.wsmatrix.gschema.xml b/wsmatrix@martin.zurowietz.de/schemas/org.gnome.shell.extensions.wsmatrix.gschema.xml index 5a1ed0e..bbccab1 100644 --- a/wsmatrix@martin.zurowietz.de/schemas/org.gnome.shell.extensions.wsmatrix.gschema.xml +++ b/wsmatrix@martin.zurowietz.de/schemas/org.gnome.shell.extensions.wsmatrix.gschema.xml @@ -43,12 +43,47 @@ - + ["<Super>w"] Keybinding to open the workspace overview Keybinding to open the workspace overview. + + ["Right"] + Keybinding to move to the right in the workspace overview + + Keybinding to move to the right in the workspace overview + + + + ["Left"] + Keybinding to move to the left in the workspace overview + + Keybinding to move to the left in the workspace overview + + + + ["Up"] + Keybinding to move up in the workspace overview + + Keybinding to move up in the workspace overview + + + + ["Down"] + Keybinding to move down in the workspace overview + + Keybinding to move down in the workspace overview + + + + ["Return","Escape"] + Keybinding to confirm and close the workspace overview + + Keybinding to confirm and close the workspace overview + +