Skip to content

Commit

Permalink
Merge pull request #49 from ebeem/multi_monitor_support_3
Browse files Browse the repository at this point in the history
Support multi-monitor setups
  • Loading branch information
ebeem authored Sep 4, 2019
2 parents 9543a73 + 24fad89 commit b395025
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 48 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This is a clone of the [Workspace Grid](https://github.com/zakkak/workspace-grid
- Two wraparound modes for navigating workspaces (optional).
- Workspace labels in the workspace switcher popup (optional).
- Workspace overview on <kbd>Super</kbd>+<kbd>W</kbd>.
- Workspace switcher popup on all monitors (optional).

## Installation

Expand Down
19 changes: 14 additions & 5 deletions [email protected]/IndicatorWsmatrixPopup.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ const Main = imports.ui.main;

var IndicatorWsmatrixPopupList = GObject.registerClass(
class IndicatorWsmatrixPopupList extends WorkspaceSwitcherPopupList {
_init(rows, columns) {
_init(rows, columns, monitorIndex) {
super._init();
this._rows = rows;
this._columns = columns;
this._monitorIndex = monitorIndex;
}

vfunc_get_preferred_height(forWidth) {
let children = this.get_children();
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
let themeNode = this.get_theme_node();

let availHeight = workArea.height;
Expand All @@ -41,7 +42,7 @@ class IndicatorWsmatrixPopupList extends WorkspaceSwitcherPopupList {
}

vfunc_get_preferred_width(forHeight) {
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
let themeNode = this.get_theme_node();

let availWidth = workArea.width;
Expand Down Expand Up @@ -87,11 +88,12 @@ class IndicatorWsmatrixPopupList extends WorkspaceSwitcherPopupList {

var IndicatorWsmatrixPopup = GObject.registerClass(
class IndicatorWsmatrixPopup extends BaseWorkspaceSwitcherPopup {
_init(rows, columns, popupTimeout, showWorkspaceNames) {
_init(rows, columns, popupTimeout, showWorkspaceNames, monitorIndex) {
this._monitorIndex = monitorIndex;
super._init(popupTimeout);
this.showWorkspaceNames = showWorkspaceNames;
let oldList = this._list;
this._list = new IndicatorWsmatrixPopupList(rows, columns);
this._list = new IndicatorWsmatrixPopupList(rows, columns, this._monitorIndex);
this._container.replace_child(oldList, this._list);
this._redisplay();
this.hide();
Expand All @@ -104,6 +106,13 @@ class IndicatorWsmatrixPopup extends BaseWorkspaceSwitcherPopup {

_redisplay() {
super._redisplay();

let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
let [, containerNatHeight] = this._container.get_preferred_height(global.screen_width);
let [, containerNatWidth] = this._container.get_preferred_width(containerNatHeight);
this._container.x = workArea.x + Math.floor((workArea.width - containerNatWidth) / 2);
this._container.y = workArea.y + Math.floor((workArea.height - containerNatHeight) / 2);

let indicators = this._list.get_children();
for (let i = 0; i < indicators.length; i++) {
if (this.showWorkspaceNames) {
Expand Down
22 changes: 12 additions & 10 deletions [email protected]/ThumbnailWsmatrixPopup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ const WsMatrix = imports.misc.extensionUtils.getCurrentExtension();
const DisplayWrapper = WsMatrix.imports.DisplayWrapper.DisplayWrapper;
const BaseWorkspaceSwitcherPopup = WsMatrix.imports.BaseWorkspaceSwitcherPopup.BaseWorkspaceSwitcherPopup;
const WorkspaceSwitcherPopupList = imports.ui.workspaceSwitcherPopup.WorkspaceSwitcherPopupList;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
const WorkspaceThumbnail = WsMatrix.imports.WsmatrixThumbnail.WsmatrixThumbnail;
const Main = imports.ui.main;

var ThumbnailWsmatrixPopupList = GObject.registerClass(
class ThumbnailWsmatrixPopupList extends WorkspaceSwitcherPopupList {
_init(rows, columns, scale) {
_init(rows, columns, scale, monitorIndex) {
super._init();
this._rows = rows;
this._columns = columns;
this._scale = scale;
this._activeWorkspaceIndex = 0;
this._monitorIndex = monitorIndex;
}

vfunc_get_preferred_height(forWidth) {
let children = this.get_children();
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
let themeNode = this.get_theme_node();

let availHeight = workArea.height;
Expand All @@ -37,7 +38,7 @@ class ThumbnailWsmatrixPopupList extends WorkspaceSwitcherPopupList {

vfunc_get_preferred_width(forHeight) {
let children = this.get_children();
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
let themeNode = this.get_theme_node();

let availWidth = workArea.width;
Expand Down Expand Up @@ -105,12 +106,13 @@ class ThumbnailWsmatrixPopupList extends WorkspaceSwitcherPopupList {

var ThumbnailWsmatrixPopup = GObject.registerClass(
class ThumbnailWsmatrixPopup extends BaseWorkspaceSwitcherPopup {
_init(rows, columns, scale, popupTimeout, hideOnly) {
_init(rows, columns, scale, popupTimeout, hideOnly, monitorIndex) {
super._init(popupTimeout);
this._hideOnly = hideOnly;
this._monitorIndex = monitorIndex;
this._workspaceManager = DisplayWrapper.getWorkspaceManager();
let oldList = this._list;
this._list = new ThumbnailWsmatrixPopupList(rows, columns, scale);
this._list = new ThumbnailWsmatrixPopupList(rows, columns, scale, this._monitorIndex);
this._container.replace_child(oldList, this._list);
this._redisplay();
this.hide();
Expand Down Expand Up @@ -138,16 +140,16 @@ class ThumbnailWsmatrixPopup extends BaseWorkspaceSwitcherPopup {

for (let i = 0; i < this._workspaceManager.n_workspaces; i++) {
let workspace = this._workspaceManager.get_workspace_by_index(i);
let thumbnail = new WorkspaceThumbnail.WorkspaceThumbnail(workspace);
let thumbnail = new WorkspaceThumbnail(workspace, this._monitorIndex);
this._list.add_actor(thumbnail.actor);
}

// The workspace indicator is always last.
this._list.add_actor(indicator);

let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
let [containerMinHeight, containerNatHeight] = this._container.get_preferred_height(global.screen_width);
let [containerMinWidth, containerNatWidth] = this._container.get_preferred_width(containerNatHeight);
let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
let [, containerNatHeight] = this._container.get_preferred_height(global.screen_width);
let [, containerNatWidth] = this._container.get_preferred_width(containerNatHeight);
this._container.x = workArea.x + Math.floor((workArea.width - containerNatWidth) / 2);
this._container.y = workArea.y + Math.floor((workArea.height - containerNatHeight) / 2);

Expand Down
131 changes: 101 additions & 30 deletions [email protected]/WmOverride.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ const WraparoundMode = {
var WmOverride = class {
constructor(settings, keybindings) {
this.wm = Main.wm;
this.wm._wsPopupList = [];
this.settings = settings;
this._mutterSettings = new Gio.Settings({ schema_id: 'org.gnome.mutter' });
this.wsManager = DisplayWrapper.getWorkspaceManager();
this.originalDynamicWorkspaces = this._mutterSettings.get_boolean('dynamic-workspaces');
this.originalAllowedKeybindings = {};
this._keybindings = keybindings;
this.monitors = [];

this._overrideDynamicWorkspaces();
this._overrideKeybindingHandlers();
this._handleNumberOfWorkspacesChanged();
this._handlePopupTimeoutChanged();
this._handleScaleChanged();
this._handleMultiMonitorChanged();
this._handleShowThumbnailsChanged();
this._handleShowWorkspaceNamesChanged();
this._handleCachePopupChanged();
Expand All @@ -36,6 +39,7 @@ var WmOverride = class {
this._notify();
this._addKeybindings();
this._connectOverview();
this._connectLayoutManager();
}

destroy() {
Expand All @@ -47,6 +51,7 @@ var WmOverride = class {
this._notify();
this._removeKeybindings();
this._disconnectOverview();
this._disconnectLayoutManager();
}

_connectSettings() {
Expand All @@ -70,6 +75,11 @@ var WmOverride = class {
this._handleScaleChanged.bind(this)
);

this.settingsHandlerMultiMonitor = this.settings.connect(
'changed::multi-monitor',
this._handleMultiMonitorChanged.bind(this)
);

this.settingsHandlerShowThumbnails = this.settings.connect(
'changed::show-thumbnails',
this._handleShowThumbnailsChanged.bind(this)
Expand All @@ -96,6 +106,7 @@ var WmOverride = class {
this.settings.disconnect(this.settingsHandlerColumns);
this.settings.disconnect(this.settingsHandlerPopupTimeout);
this.settings.disconnect(this.settingsHandlerScale);
this.settings.disconnect(this.settingsHandlerMultiMonitor);
this.settings.disconnect(this.settingsHandlerShowThumbnails);
this.settings.disconnect(this.settingsHandlerWraparoundMode);
this.settings.disconnect(this.settingsHandlerShowWorkspaceNames);
Expand All @@ -113,6 +124,17 @@ var WmOverride = class {
Main.overview.disconnect(this.overviewHandlerShown);
}

_connectLayoutManager() {
this.monitorsChanged = Main.layoutManager.connect(
'monitors-changed',
this._updateMonitors.bind(this)
);
}

_disconnectLayoutManager() {
Main.layoutManager.disconnect(this.monitorsChanged);
}

_addKeybindings() {
this.wm.addKeybinding(
'workspace-overview-toggle',
Expand Down Expand Up @@ -195,6 +217,12 @@ var WmOverride = class {
this._destroyWorkspaceSwitcherPopup();
}

_handleMultiMonitorChanged() {
this.multiMonitor = this.settings.get_boolean('multi-monitor');
this._updateMonitors();
this._destroyWorkspaceSwitcherPopup();
}

_handleShowThumbnailsChanged() {
this.showThumbnails = this.settings.get_boolean('show-thumbnails');
this._destroyWorkspaceSwitcherPopup();
Expand Down Expand Up @@ -281,6 +309,12 @@ var WmOverride = class {
);
}

_updateMonitors() {
this.monitors = this.multiMonitor ?
Main.layoutManager.monitors :
[Main.layoutManager.primaryMonitor];
}

_notify() {
// Update the workspace display to match the number of workspaces.
this.wsManager.notify('n-workspaces');
Expand Down Expand Up @@ -347,27 +381,43 @@ var WmOverride = class {
this.wm.actionMoveWindow(window, newWs);

if (!Main.overview.visible && this.popupTimeout > 0) {
if (this.wm._workspaceSwitcherPopup == null) {
this.wm._workspaceTracker.blockUpdates();
this.wm._workspaceSwitcherPopup = this._createNewPopup();
this.wm._workspaceSwitcherPopup.connect('destroy', () => {
this.wm._workspaceTracker.unblockUpdates();
this.wm._workspaceSwitcherPopup = null;
this.wm._isWorkspacePrepended = false;
});
}
this.wm._workspaceSwitcherPopup.display(direction, newWs.index());
this.monitors.forEach((monitor) => {
let monitorIndex = monitor.index;

if (!this.wm._wsPopupList[monitorIndex]) {
this.wm._workspaceTracker.blockUpdates();
this.wm._wsPopupList[monitorIndex] = this._createNewPopup({
monitorIndex: monitorIndex,
});
this.wm._wsPopupList[monitorIndex].connect('destroy', () => {
this.wm._workspaceTracker.unblockUpdates();
this.wm._wsPopupList[monitorIndex] = null;
if (monitorIndex === Main.layoutManager.primaryIndex) {
this.wm._workspaceSwitcherPopup = null;
this.wm._isWorkspacePrepended = false;
}
});
}

this.wm._wsPopupList[monitorIndex].display(direction, newWs.index());
if (monitorIndex === Main.layoutManager.primaryIndex) {
this.wm._workspaceSwitcherPopup = this.wm._wsPopupList[monitorIndex];
}
});
}
}

_destroyWorkspaceSwitcherPopup() {
if (this.wm._workspaceSwitcherPopup) {
if (this.wm._workspaceSwitcherPopup instanceof ThumbnailWsmatrixPopup) {
this.wm._workspaceSwitcherPopup.destroy(true);
} else {
this.wm._workspaceSwitcherPopup.destroy();
this.monitors.forEach((monitor) => {
let monitorIndex = monitor.index;
if (this.wm._wsPopupList[monitorIndex]) {
if (this.wm._wsPopupList[monitorIndex] instanceof ThumbnailWsmatrixPopup) {
this.wm._wsPopupList[monitorIndex].destroy(true);
} else {
this.wm._wsPopupList[monitorIndex].destroy();
}
}
}
});
}

_getTargetWorkspace(direction) {
Expand Down Expand Up @@ -407,38 +457,56 @@ var WmOverride = class {
return newWs;
}

_createNewPopup(timeout) {
timeout = timeout === undefined ? this.popupTimeout : timeout;
_createNewPopup(options) {
let timeout = options.timeout === undefined ?
this.popupTimeout :
options.timeout;

if (this.showThumbnails) {
return new ThumbnailWsmatrixPopup(
this.rows,
this.columns,
this.scale,
timeout,
this.cachePopup
this.cachePopup,
options.monitorIndex
);
}

return new IndicatorWsmatrixPopup(
this.rows,
this.columns,
timeout,
this.showWorkspaceNames
this.showWorkspaceNames,
options.monitorIndex
);
}

_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.monitors.forEach((monitor) => {
let monitorIndex = monitor.index;
this.wm._wsPopupList[monitorIndex] = this._createNewPopup({
timeout: 0,
monitorIndex: monitorIndex,
});
this.wm._wsPopupList[monitorIndex].display(null, this.wsManager.get_active_workspace_index());

this.wm._wsPopupList[monitorIndex].connect('destroy', () => {
this.wm._workspaceTracker.unblockUpdates();
this.wm._wsPopupList[monitorIndex] = null;

if (monitorIndex === Main.layoutManager.primaryIndex){
this.wm._workspaceSwitcherPopup = null;
this.wm._isWorkspacePrepended = false;
this._removeWsOverviewKeybindings();
}
});
});
this.wm._workspaceSwitcherPopup.display(null, this.wsManager.get_active_workspace_index());

this.wm._workspaceSwitcherPopup = this.wm._wsPopupList[Main.layoutManager.primaryIndex];
this._addWsOverviewKeybindings();

} else {
this._destroyWorkspaceSwitcherPopup();
}
Expand All @@ -447,9 +515,12 @@ var WmOverride = class {
_moveToWorkspace(direction) {
let workspace = this._getTargetWorkspace(direction);
this.wm.actionMoveWorkspace(workspace);
if (this.wm._workspaceSwitcherPopup) {
this.wm._workspaceSwitcherPopup.display(direction, workspace.index());
}
this.monitors.forEach((monitor) => {
let monitorIndex = monitor.index;
if (this.wm._wsPopupList[monitorIndex]) {
this.wm._wsPopupList[monitorIndex].display(direction, workspace.index());
}
});
}

_workspaceOverviewMoveRight() {
Expand Down
11 changes: 11 additions & 0 deletions [email protected]/WsmatrixThumbnail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const Main = imports.ui.main;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail.WorkspaceThumbnail;

var WsmatrixThumbnail = class WsmatrixThumbnail extends WorkspaceThumbnail {
constructor(metaWorkspace, monitorIndex) {
let tempPrimaryIndex = Main.layoutManager.primaryIndex;
Main.layoutManager.primaryIndex = monitorIndex;
super(metaWorkspace);
Main.layoutManager.primaryIndex = tempPrimaryIndex;
}
}
Loading

0 comments on commit b395025

Please sign in to comment.