diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/multi-monitors-add-on@spin83/extension.js b/multi-monitors-add-on@spin83/extension.js index 0a3dce7..0b226cf 100644 --- a/multi-monitors-add-on@spin83/extension.js +++ b/multi-monitors-add-on@spin83/extension.js @@ -15,58 +15,63 @@ 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; +import Clutter from 'gi://Clutter'; +import Gio from 'gi://Gio'; -const Main = imports.ui.main; -var { ANIMATION_TIME } = imports.ui.overview; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js'; +import Convenience from './convenience.js'; -const Config = imports.misc.config; -const GNOME_SHELL_VERSION = Config.PACKAGE_VERSION.split('.'); +import MMLayout from './mmlayout.js'; +import MMOverview from './mmoverview.js'; +import MMIndicator from './indicator.js'; -const ExtensionUtils = imports.misc.extensionUtils; -const MultiMonitors = ExtensionUtils.getCurrentExtension(); -const Convenience = MultiMonitors.imports.convenience; +import {ANIMATION_TIME} from 'resource:///org/gnome/shell/ui/overview.js'; -const MMLayout = MultiMonitors.imports.mmlayout; -const MMOverview = MultiMonitors.imports.mmoverview; -const MMIndicator = MultiMonitors.imports.indicator; - -const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides'; +// 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}`) +export function copyClass(s, d) { +// 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); +// log(" ) "+pName.toString()); + if (typeof pName === 'symbol') { + continue + } + if (d.prototype.hasOwnProperty(pName)) { + continue + } + if (pName === 'prototype') { + continue + } + if (pName === 'constructor') { + continue + } +// log(pName); let pDesc = Reflect.getOwnPropertyDescriptor(s.prototype, pName); -// global.log(typeof pDesc); +// log(typeof pDesc); if (typeof pDesc !== 'object') continue; Reflect.defineProperty(d.prototype, pName, pDesc); } -}; - -function gnomeShellVersion() { - return GNOME_SHELL_VERSION; } -class MultiMonitorsAddOn { +export default class MultiMonitorsAddOn extends Extension { + version = null; - constructor() { + constructor(metadata) { + super(metadata); this._settings = Convenience.getSettings(); // this._ov_settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA }); - this._mu_settings = new Gio.Settings({ schema: MUTTER_SCHEMA }); + this._mu_settings = new Gio.Settings({schema: MUTTER_SCHEMA}); this.mmIndicator = null; Main.mmOverview = null; @@ -74,219 +79,210 @@ class MultiMonitorsAddOn { this._mmMonitors = 0; this.syncWorkspacesActualGeometry = null; + + // todo translate "unknown" + this._init(metadata.version ? metadata.version : 'unknown'); } _showIndicator() { - if(this._settings.get_boolean(SHOW_INDICATOR_ID)) { - if(!this.mmIndicator) { - this.mmIndicator = Main.panel.addToStatusArea('MultiMonitorsAddOn', new MMIndicator.MultiMonitorsIndicator()); - } - } - else { - this._hideIndicator(); - } + 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; - } + 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, - }); - } - } + 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) + _hideThumbnailsSlider() { + if (!Main.mmOverview) { return; + } for (let idx = 0; idx < Main.mmOverview.length; idx++) { - if (Main.mmOverview[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(); - } + if (this._mmMonitors != Main.layoutManager.monitors.length) { + this._mmMonitors = Main.layoutManager.monitors.length; + log(`pi:${Main.layoutManager.primaryIndex}`); + for (let i = 0; i < Main.layoutManager.monitors.length; i++) { + let monitor = Main.layoutManager.monitors[i]; + log(`i:${i} x:${monitor.x} y:${monitor.y} w:${monitor.width} h:${monitor.height}`); + } + this._hideThumbnailsSlider(); + this._showThumbnailsSlider(); + } } _switchOffThumbnails() { - if ( + 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'); - } + this._mu_settings.get_boolean(WORKSPACES_ONLY_ON_PRIMARY_ID)) { + this._settings.set_string(THUMBNAILS_SLIDER_POSITION_ID, 'none'); + } + } + + _init(metaVersion) { + 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; + }; + + if (Number.isFinite(metaVersion)) { + this.version = 'v' + Math.trunc(metaVersion); + switch (Math.round((metaVersion % 1) * 10)) { + case 0: + break; + case 1: + this.version += '+bugfix'; + break; + case 2: + this.version += '+develop'; + break; + default: + this.version += '+modified'; + break; + } + } else { + this.version = metaVersion; + } } - enable(version) { - global.log("Enable Multi Monitors Add-On ("+version+")...") - - if(Main.panel.statusArea.MultiMonitorsAddOn) - disable(); - - this._mmMonitors = 0; + enable() { + log(`Enable Multi Monitors Add-On (${this.version})...`) + + if (Main.panel.statusArea.MultiMonitorsAddOn) { + this.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(); + 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); + 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 ...") - } -} + this._mu_settings.disconnect(this._switchOffThumbnailsMuId); -var multiMonitorsAddOn = null; -var version = null; + this._settings.disconnect(this._showPanelId); + this._settings.disconnect(this._thumbnailsSliderPositionId); + this._settings.disconnect(this._showIndicatorId); -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; + this._hideIndicator(); - multiMonitorsAddOn = new MultiMonitorsAddOn(); - multiMonitorsAddOn.enable(version); -} + Main.mmLayoutManager.hidePanel(); + Main.mmLayoutManager = null; -function disable() { - if (multiMonitorsAddOn == null) - return; + this._hideThumbnailsSlider(); + this._mmMonitors = 0; - multiMonitorsAddOn.disable(); - multiMonitorsAddOn = null; + log('Disable Multi Monitors Add-On ...') + } } diff --git a/multi-monitors-add-on@spin83/metadata.json b/multi-monitors-add-on@spin83/metadata.json index 35ea54b..9a98444 100644 --- a/multi-monitors-add-on@spin83/metadata.json +++ b/multi-monitors-add-on@spin83/metadata.json @@ -1,10 +1,10 @@ { - "shell-version": ["40", "41", "42", "43", "44"], + "shell-version": ["45"], "uuid": "multi-monitors-add-on@spin83", "name": "Multi Monitors Add-On", "settings-schema": "org.gnome.shell.extensions.multi-monitors-add-on", "gettext-domain": "multi-monitors-add-on", "description": "Add multiple monitors overview and panel for gnome-shell.", "url": "https://github.com/spin83/multi-monitors-add-on.git", - "version": 26 + "version": 27 } diff --git a/multi-monitors-add-on@spin83/prefs.js b/multi-monitors-add-on@spin83/prefs.js index d1ba7ea..2a15efc 100644 --- a/multi-monitors-add-on@spin83/prefs.js +++ b/multi-monitors-add-on@spin83/prefs.js @@ -15,20 +15,14 @@ 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 Lang = imports.lang; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import Gdk from 'gi://Gdk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import {gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/extension.js'; -const GObject = imports.gi.GObject; -const Gdk = imports.gi.Gdk; -const Gtk = imports.gi.Gtk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; - -const Gettext = imports.gettext.domain('multi-monitors-add-on'); -const _ = Gettext.gettext; - -const ExtensionUtils = imports.misc.extensionUtils; -const MultiMonitors = ExtensionUtils.getCurrentExtension(); -const Convenience = MultiMonitors.imports.convenience; +const Convenience = './convenience.js'; const SHOW_INDICATOR_ID = 'show-indicator'; const SHOW_PANEL_ID = 'show-panel'; @@ -45,245 +39,262 @@ const Columns = { MONITOR_NUMBER: 1 }; +function langCallback(sourceObject, arg1) { + if (this === sourceObject) { + log('`sourceObject` is correctly bound to `this`'); + } +} -var MultiMonitorsPrefsWidget = GObject.registerClass( -class MultiMonitorsPrefsWidget extends Gtk.Grid { - _init() { - super._init({ - margin_top: 6, margin_end: 6, margin_bottom: 6, margin_start: 6 - }); +const MultiMonitorsPrefsWidget = GObject.registerClass( + class MultiMonitorsPrefsWidget extends Gtk.Grid { + _init() { + super._init({ + margin_top: 6, margin_end: 6, margin_bottom: 6, margin_start: 6 + }); - this._numRows = 0; + this._numRows = 0; - this.set_orientation(Gtk.Orientation.VERTICAL); + this.set_orientation(Gtk.Orientation.VERTICAL); - this._settings = Convenience.getSettings(); - this._desktopSettings = Convenience.getSettings("org.gnome.desktop.interface"); + this._settings = Convenience.getSettings(); + this._desktopSettings = Convenience.getSettings('org.gnome.desktop.interface'); - this._display = Gdk.Display.get_default(); - this._monitors = this._display.get_monitors() + this._display = Gdk.Display.get_default(); + this._monitors = this._display.get_monitors() - this._addBooleanSwitch(_('Show Multi Monitors indicator on Top Panel.'), SHOW_INDICATOR_ID); - this._addBooleanSwitch(_('Show Panel on additional monitors.'), SHOW_PANEL_ID); - this._addBooleanSwitch(_('Show Activities-Button on additional monitors.'), SHOW_ACTIVITIES_ID); - this._addBooleanSwitch(_('Show AppMenu-Button on additional monitors.'), SHOW_APP_MENU_ID); - this._addBooleanSwitch(_('Show DateTime-Button on additional monitors.'), SHOW_DATE_TIME_ID); - this._addComboBoxSwitch(_('Show Thumbnails-Slider on additional monitors.'), THUMBNAILS_SLIDER_POSITION_ID, { - none: _('No'), - right: _('On the right'), - left: _('On the left'), - auto: _('Auto') - }); - this._addSettingsBooleanSwitch(_('Enable hot corners.'), this._desktopSettings, ENABLE_HOT_CORNERS); + this._addBooleanSwitch(_('Show Multi Monitors indicator on Top Panel.'), SHOW_INDICATOR_ID); + this._addBooleanSwitch(_('Show Panel on additional monitors.'), SHOW_PANEL_ID); + this._addBooleanSwitch(_('Show Activities-Button on additional monitors.'), SHOW_ACTIVITIES_ID); + this._addBooleanSwitch(_('Show AppMenu-Button on additional monitors.'), SHOW_APP_MENU_ID); + this._addBooleanSwitch(_('Show DateTime-Button on additional monitors.'), SHOW_DATE_TIME_ID); + this._addComboBoxSwitch(_('Show Thumbnails-Slider on additional monitors.'), THUMBNAILS_SLIDER_POSITION_ID, { + none: _('No'), + right: _('On the right'), + left: _('On the left'), + auto: _('Auto') + }); + this._addSettingsBooleanSwitch(_('Enable hot corners.'), this._desktopSettings, ENABLE_HOT_CORNERS); - this._store = new Gtk.ListStore(); - this._store.set_column_types([GObject.TYPE_STRING, GObject.TYPE_INT]); + this._store = new Gtk.ListStore(); + this._store.set_column_types([GObject.TYPE_STRING, GObject.TYPE_INT]); - this._treeView = new Gtk.TreeView({ model: this._store, hexpand: true, vexpand: true }); - this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE); + this._treeView = new Gtk.TreeView({model: this._store, hexpand: true, vexpand: true}); + this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE); - let appColumn = new Gtk.TreeViewColumn({ expand: true, sort_column_id: Columns.INDICATOR_NAME, - title: _("A list of indicators for transfer to additional monitors.") }); + let appColumn = new Gtk.TreeViewColumn({ + expand: true, sort_column_id: Columns.INDICATOR_NAME, + title: _('A list of indicators for transfer to additional monitors.') + }); - let nameRenderer = new Gtk.CellRendererText; - appColumn.pack_start(nameRenderer, true); - appColumn.add_attribute(nameRenderer, "text", Columns.INDICATOR_NAME); + let nameRenderer = new Gtk.CellRendererText; + appColumn.pack_start(nameRenderer, true); + appColumn.add_attribute(nameRenderer, 'text', Columns.INDICATOR_NAME); - nameRenderer = new Gtk.CellRendererText; - appColumn.pack_start(nameRenderer, true); - appColumn.add_attribute(nameRenderer, "text", Columns.MONITOR_NUMBER); - - this._treeView.append_column(appColumn); - this.add(this._treeView); + nameRenderer = new Gtk.CellRendererText; + appColumn.pack_start(nameRenderer, true); + appColumn.add_attribute(nameRenderer, 'text', Columns.MONITOR_NUMBER); - let toolbar = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL}); - toolbar.get_style_context().add_class("inline-toolbar"); + this._treeView.append_column(appColumn); + this.add(this._treeView); - this._settings.connect('changed::'+TRANSFER_INDICATORS_ID, Lang.bind(this, this._updateIndicators)); - this._updateIndicators(); + let toolbar = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL}); + toolbar.get_style_context().add_class('inline-toolbar'); - let addTButton = new Gtk.Button({ icon_name: "list-add" }); - addTButton.connect('clicked', Lang.bind(this, this._addIndicator)); - toolbar.append(addTButton); + this._settings.connect(`changed::${TRANSFER_INDICATORS_ID}`, langCallback.bind(this, this._updateIndicators)); + this._updateIndicators(); - let removeTButton = new Gtk.Button({ icon_name: "list-remove" }); - removeTButton.connect('clicked', Lang.bind(this, this._removeIndicator)); - toolbar.append(removeTButton); - - this.add(toolbar); - } + let addTButton = new Gtk.Button({icon_name: 'list-add'}); + addTButton.connect('clicked', langCallback.bind(this, this._addIndicator)); + toolbar.append(addTButton); - add(child) { - this.attach(child, 0, this._numRows++, 1, 1); - } + let removeTButton = new Gtk.Button({icon_name: 'list-remove'}); + removeTButton.connect('clicked', langCallback.bind(this, this._removeIndicator)); + toolbar.append(removeTButton); + + this.add(toolbar); + } + + add(child) { + this.attach(child, 0, this._numRows++, 1, 1); + } + + _updateIndicators() { + this._store.clear(); + + let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).deep_unpack(); + + for (let indicator in transfers) { + if (transfers.hasOwnProperty(indicator)) { + let monitor = transfers[indicator]; + let iter = this._store.append(); + this._store.set(iter, [Columns.INDICATOR_NAME, Columns.MONITOR_NUMBER], [indicator, monitor]); + } + } + } - _updateIndicators() { - this._store.clear(); - - let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).deep_unpack(); - - for(let indicator in transfers) { - if(transfers.hasOwnProperty(indicator)){ - let monitor = transfers[indicator]; - let iter = this._store.append(); - this._store.set(iter, [Columns.INDICATOR_NAME, Columns.MONITOR_NUMBER], [indicator, monitor]); - } - } - } - - _addIndicator() { - - let dialog = new Gtk.Dialog({ title: _("Select indicator"), - transient_for: this.get_toplevel(), modal: true }); - dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL); - dialog.add_button(_("Add"), Gtk.ResponseType.OK); - dialog.set_default_response(Gtk.ResponseType.OK); - - let grid = new Gtk.Grid({ column_spacing: 10, row_spacing: 15, - margin_top: 10, margin_end: 10, margin_bottom: 10, margin_start: 10 }); - - grid.set_orientation(Gtk.Orientation.VERTICAL); - - dialog._store = new Gtk.ListStore(); - dialog._store.set_column_types([GObject.TYPE_STRING]); - - dialog._treeView = new Gtk.TreeView({ model: dialog._store, hexpand: true, vexpand: true }); - dialog._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE); - - let appColumn = new Gtk.TreeViewColumn({ expand: true, sort_column_id: Columns.INDICATOR_NAME, - title: _("Indicators on Top Panel") }); - - let nameRenderer = new Gtk.CellRendererText; - appColumn.pack_start(nameRenderer, true); - appColumn.add_attribute(nameRenderer, "text", Columns.INDICATOR_NAME); - - dialog._treeView.append_column(appColumn); - - let availableIndicators = () => { - let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).unpack(); - dialog._store.clear(); - this._settings.get_strv(AVAILABLE_INDICATORS_ID).forEach((indicator) => { - if(!transfers.hasOwnProperty(indicator)){ - let iter = dialog._store.append(); - dialog._store.set(iter, [Columns.INDICATOR_NAME], [indicator]); - } - }); - }; - - let availableIndicatorsId = this._settings.connect('changed::'+AVAILABLE_INDICATORS_ID, - availableIndicators); - let transferIndicatorsId = this._settings.connect('changed::'+TRANSFER_INDICATORS_ID, - availableIndicators); - - availableIndicators.apply(this); - grid.attach(dialog._treeView, 0, 0, 2, 1); - - let gHBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, + _addIndicator() { + let dialog = new Gtk.Dialog({ + title: _('Select indicator'), + transient_for: this.get_toplevel(), modal: true + }); + dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL); + dialog.add_button(_('Add'), Gtk.ResponseType.OK); + dialog.set_default_response(Gtk.ResponseType.OK); + + let grid = new Gtk.Grid({ + column_spacing: 10, row_spacing: 15, + margin_top: 10, margin_end: 10, margin_bottom: 10, margin_start: 10 + }); + + grid.set_orientation(Gtk.Orientation.VERTICAL); + + dialog._store = new Gtk.ListStore(); + dialog._store.set_column_types([GObject.TYPE_STRING]); + + dialog._treeView = new Gtk.TreeView({model: dialog._store, hexpand: true, vexpand: true}); + dialog._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE); + + let appColumn = new Gtk.TreeViewColumn({ + expand: true, sort_column_id: Columns.INDICATOR_NAME, + title: _('Indicators on Top Panel') + }); + + let nameRenderer = new Gtk.CellRendererText; + appColumn.pack_start(nameRenderer, true); + appColumn.add_attribute(nameRenderer, 'text', Columns.INDICATOR_NAME); + + dialog._treeView.append_column(appColumn); + + let availableIndicators = () => { + let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).unpack(); + dialog._store.clear(); + this._settings.get_strv(AVAILABLE_INDICATORS_ID).forEach((indicator) => { + if (!transfers.hasOwnProperty(indicator)) { + let iter = dialog._store.append(); + dialog._store.set(iter, [Columns.INDICATOR_NAME], [indicator]); + } + }); + }; + + let availableIndicatorsId = this._settings.connect(`changed::${AVAILABLE_INDICATORS_ID}`, + availableIndicators); + let transferIndicatorsId = this._settings.connect(`changed::${TRANSFER_INDICATORS_ID}`, + availableIndicators); + + availableIndicators.apply(this); + grid.attach(dialog._treeView, 0, 0, 2, 1); + + let gHBox = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, margin_top: 10, margin_end: 10, margin_bottom: 10, margin_start: 10, - spacing: 20, hexpand: true}); - let gLabel = new Gtk.Label({label: _('Monitor index:'), halign: Gtk.Align.START}); - gHBox.append(gLabel); - dialog._adjustment = new Gtk.Adjustment({lower: 0.0, upper: 0.0, step_increment:1.0}); - let spinButton = new Gtk.SpinButton({halign: Gtk.Align.END, adjustment: dialog._adjustment, numeric: 1}); - gHBox.append(spinButton); - - let monitorsChanged = () => { - let n_monitors = this._monitors.get_n_items() -1; - dialog._adjustment.set_upper(n_monitors) - dialog._adjustment.set_value(n_monitors); - }; - - let monitorsChangedId = this._monitors.connect('items-changed', monitorsChanged); - - monitorsChanged.apply(this); - grid.append(gHBox); - - dialog.get_content_area().append(grid); - - dialog.connect('response', (dialog, id) => { - this._monitors.disconnect(monitorsChangedId); - this._settings.disconnect(availableIndicatorsId); - this._settings.disconnect(transferIndicatorsId); - if (id != Gtk.ResponseType.OK) { - dialog.destroy(); - return; - } - - let [any, model, iter] = dialog._treeView.get_selection().get_selected(); - if (any) { - let indicator = model.get_value(iter, Columns.INDICATOR_NAME); - - let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).deep_unpack(); - if(!transfers.hasOwnProperty(indicator)){ - transfers[indicator] = dialog._adjustment.get_value(); - this._settings.set_value(TRANSFER_INDICATORS_ID, new GLib.Variant('a{si}', transfers)); - } - } - - dialog.destroy(); - }); - } - - _removeIndicator() { - let [any, model, iter] = this._treeView.get_selection().get_selected(); - if (any) { - let indicator = model.get_value(iter, Columns.INDICATOR_NAME); - - let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).deep_unpack(); - if(transfers.hasOwnProperty(indicator)){ - delete transfers[indicator]; - this._settings.set_value(TRANSFER_INDICATORS_ID, new GLib.Variant('a{si}', transfers)); - } + spacing: 20, hexpand: true + }); + let gLabel = new Gtk.Label({label: _('Monitor index:'), halign: Gtk.Align.START}); + gHBox.append(gLabel); + dialog._adjustment = new Gtk.Adjustment({lower: 0.0, upper: 0.0, step_increment: 1.0}); + let spinButton = new Gtk.SpinButton({halign: Gtk.Align.END, adjustment: dialog._adjustment, numeric: 1}); + gHBox.append(spinButton); + + let monitorsChanged = () => { + let n_monitors = this._monitors.get_n_items() - 1; + dialog._adjustment.set_upper(n_monitors) + dialog._adjustment.set_value(n_monitors); + }; + + let monitorsChangedId = this._monitors.connect('items-changed', monitorsChanged); + + monitorsChanged.apply(this); + grid.append(gHBox); + + dialog.get_content_area().append(grid); + + dialog.connect('response', (dialog, id) => { + this._monitors.disconnect(monitorsChangedId); + this._settings.disconnect(availableIndicatorsId); + this._settings.disconnect(transferIndicatorsId); + if (id != Gtk.ResponseType.OK) { + dialog.destroy(); + return; + } + + let [any, model, iter] = dialog._treeView.get_selection().get_selected(); + if (any) { + let indicator = model.get_value(iter, Columns.INDICATOR_NAME); + + let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).deep_unpack(); + if (!transfers.hasOwnProperty(indicator)) { + transfers[indicator] = dialog._adjustment.get_value(); + this._settings.set_value(TRANSFER_INDICATORS_ID, new GLib.Variant('a{si}', transfers)); + } + } + + dialog.destroy(); + }); } - } - _addComboBoxSwitch(label, schema_id, options) { - this._addSettingsComboBoxSwitch(label, this._settings, schema_id, options) - } + _removeIndicator() { + let [any, model, iter] = this._treeView.get_selection().get_selected(); + if (any) { + let indicator = model.get_value(iter, Columns.INDICATOR_NAME); + + let transfers = this._settings.get_value(TRANSFER_INDICATORS_ID).deep_unpack(); + if (transfers.hasOwnProperty(indicator)) { + delete transfers[indicator]; + this._settings.set_value(TRANSFER_INDICATORS_ID, new GLib.Variant('a{si}', transfers)); + } + } + } - _addSettingsComboBoxSwitch(label, settings, schema_id, options) { - let gHBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, + _addComboBoxSwitch(label, schema_id, options) { + this._addSettingsComboBoxSwitch(label, this._settings, schema_id, options) + } + + _addSettingsComboBoxSwitch(label, settings, schema_id, options) { + let gHBox = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, margin_top: 10, margin_end: 10, margin_bottom: 10, margin_start: 10, - spacing: 20, hexpand: true}); - let gLabel = new Gtk.Label({label: _(label), halign: Gtk.Align.START}); - gHBox.append(gLabel); + spacing: 20, hexpand: true + }); + let gLabel = new Gtk.Label({label: _(label), halign: Gtk.Align.START}); + gHBox.append(gLabel); - let gCBox = new Gtk.ComboBoxText({halign: Gtk.Align.END}); - Object.entries(options).forEach(function(entry) { - const [key, val] = entry; - gCBox.append(key, val); - }); - gHBox.append(gCBox); + let gCBox = new Gtk.ComboBoxText({halign: Gtk.Align.END}); + Object.entries(options).forEach(function (entry) { + const [key, val] = entry; + gCBox.append(key, val); + }); + gHBox.append(gCBox); - this.add(gHBox); + this.add(gHBox); - settings.bind(schema_id, gCBox, 'active-id', Gio.SettingsBindFlags.DEFAULT); - } + settings.bind(schema_id, gCBox, 'active-id', Gio.SettingsBindFlags.DEFAULT); + } - _addBooleanSwitch(label, schema_id) { - this._addSettingsBooleanSwitch(label, this._settings, schema_id); - } + _addBooleanSwitch(label, schema_id) { + this._addSettingsBooleanSwitch(label, this._settings, schema_id); + } - _addSettingsBooleanSwitch(label, settings, schema_id) { - let gHBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, + _addSettingsBooleanSwitch(label, settings, schema_id) { + let gHBox = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, margin_top: 10, margin_end: 10, margin_bottom: 10, margin_start: 10, - spacing: 20, hexpand: true}); - let gLabel = new Gtk.Label({label: _(label), halign: Gtk.Align.START}); - gHBox.append(gLabel); - let gSwitch = new Gtk.Switch({halign: Gtk.Align.END}); - gHBox.append(gSwitch); - this.add(gHBox); - - settings.bind(schema_id, gSwitch, 'active', Gio.SettingsBindFlags.DEFAULT); + spacing: 20, hexpand: true + }); + let gLabel = new Gtk.Label({label: _(label), halign: Gtk.Align.START}); + gHBox.append(gLabel); + let gSwitch = new Gtk.Switch({halign: Gtk.Align.END}); + gHBox.append(gSwitch); + this.add(gHBox); + + settings.bind(schema_id, gSwitch, 'active', Gio.SettingsBindFlags.DEFAULT); + } } -}); +); -function init() { - Convenience.initTranslations(); -} - -function buildPrefsWidget() { - let widget = new MultiMonitorsPrefsWidget(); +export default class MultiMonitorsAddonPreferences extends ExtensionPreferences { + fillPreferencesWindow() { + Convenience.initTranslations(); - return widget; + let preferences = new MultiMonitorsPrefsWidget(); + } } diff --git a/multi-monitors-add-on@spin83/stylesheet.css b/multi-monitors-add-on@spin83/stylesheet.css index b1d20c5..a31fad6 100644 --- a/multi-monitors-add-on@spin83/stylesheet.css +++ b/multi-monitors-add-on@spin83/stylesheet.css @@ -1,15 +1,14 @@ - .helloworld-label { font-size: 72px; font-weight: bold; color: #ffffff; - background-color: rgba(0,0,0,0.5); + background-color: rgba(0, 0, 0, 0.5); border-radius: 5px; padding: .5em; } .multimonitor-spacer { - height: 4em; + height: 4em; } .multimonitor-status-indicators-box { @@ -21,9 +20,9 @@ } .workspace-thumbnails-left { - border-radius: 0 9px 9px 0; + border-radius: 0 9px 9px 0; } .workspace-thumbnails-left:rtl { - border-radius: 9px 0 0 9px; + border-radius: 9px 0 0 9px; }