diff options
Diffstat (limited to 'extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js')
-rw-r--r-- | extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js b/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js new file mode 100644 index 0000000..092d828 --- /dev/null +++ b/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js @@ -0,0 +1,289 @@ +/* +Copyright (C) 2014 spin83 + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, visit https://www.gnu.org/licenses/. +*/ + +const { Clutter, Gio } = imports.gi; + +const Main = imports.ui.main; +var { ANIMATION_TIME } = imports.ui.overview; + +const Config = imports.misc.config; +const GNOME_SHELL_VERSION = Config.PACKAGE_VERSION.split('.'); + +const ExtensionUtils = imports.misc.extensionUtils; +const MultiMonitors = ExtensionUtils.getCurrentExtension(); +const Convenience = MultiMonitors.imports.convenience; + +const MMLayout = MultiMonitors.imports.mmlayout; +const MMOverview = MultiMonitors.imports.mmoverview; +const MMIndicator = MultiMonitors.imports.indicator; + +const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides'; +const MUTTER_SCHEMA = 'org.gnome.mutter'; +const WORKSPACES_ONLY_ON_PRIMARY_ID = 'workspaces-only-on-primary'; + +const SHOW_INDICATOR_ID = 'show-indicator'; +const THUMBNAILS_SLIDER_POSITION_ID = 'thumbnails-slider-position'; + +function copyClass (s, d) { +// global.log(s.name +" > "+ d.name); + if (!s) throw Error(`copyClass s undefined for d ${d.name}`) + let propertyNames = Reflect.ownKeys(s.prototype); + for (let pName of propertyNames.values()) { + +// global.log(" ) "+pName.toString()); + if (typeof pName === "symbol") continue; + if (d.prototype.hasOwnProperty(pName)) continue; + if (pName === "prototype") continue; + if (pName === "constructor") continue; +// global.log(pName); + let pDesc = Reflect.getOwnPropertyDescriptor(s.prototype, pName); +// global.log(typeof pDesc); + if (typeof pDesc !== 'object') continue; + Reflect.defineProperty(d.prototype, pName, pDesc); + } +}; + +function gnomeShellVersion() { + return GNOME_SHELL_VERSION; +} + +class MultiMonitorsAddOn { + + constructor() { + this._settings = Convenience.getSettings(); + this._ov_settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA }); + this._mu_settings = new Gio.Settings({ schema: MUTTER_SCHEMA }); + + this.mmIndicator = null; + Main.mmOverview = null; + Main.mmLayoutManager = null; + + this._mmMonitors = 0; + this.syncWorkspacesActualGeometry = null; + } + + _showIndicator() { + if(this._settings.get_boolean(SHOW_INDICATOR_ID)) { + if(!this.mmIndicator) { + this.mmIndicator = Main.panel.addToStatusArea('MultiMonitorsAddOn', new MMIndicator.MultiMonitorsIndicator()); + } + } + else { + this._hideIndicator(); + } + } + + _hideIndicator() { + if(this.mmIndicator) { + this.mmIndicator.destroy(); + this.mmIndicator = null; + } + } + + _showThumbnailsSlider() { + if (this._settings.get_string(THUMBNAILS_SLIDER_POSITION_ID) === 'none') { + this._hideThumbnailsSlider(); + return; + } + + if(this._ov_settings.get_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID)) + this._ov_settings.set_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID, false); + if(this._mu_settings.get_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID)) + this._mu_settings.set_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID, false); + + if (Main.mmOverview) + return; + + Main.mmOverview = []; + for (let idx = 0; idx < Main.layoutManager.monitors.length; idx++) { + if (idx != Main.layoutManager.primaryIndex) { + Main.mmOverview[idx] = new MMOverview.MultiMonitorsOverview(idx); + } + } + + this.syncWorkspacesActualGeometry = Main.overview.searchController._workspacesDisplay._syncWorkspacesActualGeometry; + Main.overview.searchController._workspacesDisplay._syncWorkspacesActualGeometry = function() { + if (this._inWindowFade) + return; + + const primaryView = this._getPrimaryView(); + if (primaryView) { + primaryView.ease({ + ...this._actualGeometry, + duration: Main.overview.animationInProgress ? ANIMATION_TIME : 0, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + }); + } + + for (let idx = 0; idx < Main.mmOverview.length; idx++) { + if (!Main.mmOverview[idx]) + continue; + if (!Main.mmOverview[idx]._overview) + continue; + const mmView = Main.mmOverview[idx]._overview._controls._workspacesViews; + if (!mmView) + continue; + + const mmGeometry = Main.mmOverview[idx].getWorkspacesActualGeometry(); + mmView.ease({ + ...mmGeometry, + duration: Main.overview.animationInProgress ? ANIMATION_TIME : 0, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + }); + } + } + } + + _hideThumbnailsSlider() { + if (!Main.mmOverview) + return; + + for (let idx = 0; idx < Main.mmOverview.length; idx++) { + if (Main.mmOverview[idx]) + Main.mmOverview[idx].destroy(); + } + Main.mmOverview = null; + Main.overview.searchController._workspacesDisplay._syncWorkspacesActualGeometry = this.syncWorkspacesActualGeometry; + } + + _relayout() { + if(this._mmMonitors!=Main.layoutManager.monitors.length){ + this._mmMonitors = Main.layoutManager.monitors.length; + global.log("pi:"+Main.layoutManager.primaryIndex); + for (let i = 0; i < Main.layoutManager.monitors.length; i++) { + let monitor = Main.layoutManager.monitors[i]; + global.log("i:"+i+" x:"+monitor.x+" y:"+monitor.y+" w:"+monitor.width+" h:"+monitor.height); + } + this._hideThumbnailsSlider(); + this._showThumbnailsSlider(); + } + } + + _switchOffThumbnails() { + if (this._ov_settings.get_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID) || this._mu_settings.get_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID)) { + this._settings.set_string(THUMBNAILS_SLIDER_POSITION_ID, 'none'); + } + } + + enable(version) { + global.log("Enable Multi Monitors Add-On ("+version+")...") + + if(Main.panel.statusArea.MultiMonitorsAddOn) + disable(); + + this._mmMonitors = 0; + + this._switchOffThumbnailsOvId = this._ov_settings.connect('changed::'+WORKSPACES_ONLY_ON_PRIMARY_ID, + this._switchOffThumbnails.bind(this)); + this._switchOffThumbnailsMuId = this._mu_settings.connect('changed::'+WORKSPACES_ONLY_ON_PRIMARY_ID, + this._switchOffThumbnails.bind(this)); + + this._showIndicatorId = this._settings.connect('changed::'+SHOW_INDICATOR_ID, this._showIndicator.bind(this)); + this._showIndicator(); + + Main.mmLayoutManager = new MMLayout.MultiMonitorsLayoutManager(); + this._showPanelId = this._settings.connect('changed::'+MMLayout.SHOW_PANEL_ID, Main.mmLayoutManager.showPanel.bind(Main.mmLayoutManager)); + Main.mmLayoutManager.showPanel(); + + this._thumbnailsSliderPositionId = this._settings.connect('changed::'+THUMBNAILS_SLIDER_POSITION_ID, this._showThumbnailsSlider.bind(this)); + this._relayoutId = Main.layoutManager.connect('monitors-changed', this._relayout.bind(this)); + this._relayout(); + } + + disable() { + Main.layoutManager.disconnect(this._relayoutId); + this._ov_settings.disconnect(this._switchOffThumbnailsOvId); + this._mu_settings.disconnect(this._switchOffThumbnailsMuId); + + this._settings.disconnect(this._showPanelId); + this._settings.disconnect(this._thumbnailsSliderPositionId); + this._settings.disconnect(this._showIndicatorId); + + + this._hideIndicator(); + + Main.mmLayoutManager.hidePanel(); + Main.mmLayoutManager = null; + + this._hideThumbnailsSlider(); + this._mmMonitors = 0; + + global.log("Disable Multi Monitors Add-On ...") + } +} + +var multiMonitorsAddOn = null; +var version = null; + +function init() { + Convenience.initTranslations(); + + // fix bug in panel: Destroy function many time added to this same indicator. + Main.panel._ensureIndicator = function(role) { + let indicator = this.statusArea[role]; + if (indicator) { + indicator.container.show(); + return null; + } + else { + let constructor = PANEL_ITEM_IMPLEMENTATIONS[role]; + if (!constructor) { + // This icon is not implemented (this is a bug) + return null; + } + indicator = new constructor(this); + this.statusArea[role] = indicator; + } + return indicator; + }; + + const metaVersion = MultiMonitors.metadata['version']; + if (Number.isFinite(metaVersion)) { + version = 'v'+Math.trunc(metaVersion); + switch(Math.round((metaVersion%1)*10)) { + case 0: + break; + case 1: + version += '+bugfix'; + break; + case 2: + version += '+develop'; + break; + default: + version += '+modified'; + break; + } + } + else + version = metaVersion; +} + +function enable() { + if (multiMonitorsAddOn !== null) + return; + + multiMonitorsAddOn = new MultiMonitorsAddOn(); + multiMonitorsAddOn.enable(version); +} + +function disable() { + if (multiMonitorsAddOn == null) + return; + + multiMonitorsAddOn.disable(); + multiMonitorsAddOn = null; +} |