From b0c9cb924df8efa9fcf0cfbdd9e6c9b171b43b13 Mon Sep 17 00:00:00 2001 From: Sergio Costas Date: Tue, 19 Oct 2021 23:33:43 +0200 Subject: [PATCH] Desktop Icons NG integration This MR integrates Dash to Panel with Desktop Icons NG, allowing DING to know how many pixels does the panel occupy even when in intellihide mode. --- Makefile | 2 +- desktopIconsIntegration.js | 159 +++++++++++++++++++++++++++++++++++++ panelManager.js | 37 +++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 desktopIconsIntegration.js diff --git a/Makefile b/Makefile index e21b836..0081302 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ UUID = dash-to-panel@jderose9.github.com BASE_MODULES = extension.js stylesheet.css metadata.json COPYING README.md -EXTRA_MODULES = appIcons.js panel.js panelManager.js proximity.js intellihide.js progress.js panelPositions.js panelSettings.js panelStyle.js overview.js taskbar.js transparency.js windowPreview.js prefs.js utils.js Settings.ui +EXTRA_MODULES = appIcons.js panel.js panelManager.js proximity.js intellihide.js progress.js panelPositions.js panelSettings.js panelStyle.js overview.js taskbar.js transparency.js windowPreview.js prefs.js utils.js Settings.ui desktopIconsIntegration.js EXTRA_IMAGES = highlight_stacked_bg.svg highlight_stacked_bg_2.svg highlight_stacked_bg_3.svg TOLOCALIZE = prefs.js appIcons.js diff --git a/desktopIconsIntegration.js b/desktopIconsIntegration.js new file mode 100644 index 0000000..5754d5e --- /dev/null +++ b/desktopIconsIntegration.js @@ -0,0 +1,159 @@ +/* + * The code in this file is distributed under a "1-clause BSD license", + * which makes it compatible with GPLv2 and GPLv3 too, and others. + * + * License text: + * + * Copyright (C) 2021 Sergio Costas (rastersoft@gmail.com) + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/******************************************************************************* + * Integration class + * + * This class must be added to other extensions in order to integrate + * them with Desktop Icons NG. It allows an extension to notify how much margin + * it uses in each side of each monitor. + * + * DON'T SEND PATCHES TO THIS FILE TO THE EXTENSION MAINTAINER. SEND THEM TO + * DESKTOP ICONS NG MAINTAINER: https://gitlab.com/rastersoft/desktop-icons-ng + * + * In the *enable()* function, create a *DesktopIconsUsableAreaClass()* + * object with + * + * new DesktopIconsIntegration.DesktopIconsUsableAreaClass(object); + * + * Now, in the *disable()* function just call to the *destroy()* method before + * nullifying the pointer. You must create a new object in enable() the next + * time the extension is enabled. + * + * In your code, every time you change the margins, you should call first to + * *resetMargins()* method to clear the current margins, and then call to + * *setMargins(...)* method as many times as you need to set the margins in each + * monitor. You don't need to call it for all the monitors, only for those where + * you are painting something. If you don't set values for a monitor, they will + * be considered zero. + * + * The margins values are relative to the monitor border. + * + *******************************************************************************/ + +const GLib = imports.gi.GLib; +const Main = imports.ui.main; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); + +const IDENTIFIER_UUID = "130cbc66-235c-4bd6-8571-98d2d8bba5e2"; + +var DesktopIconsUsableAreaClass = class { + constructor() { + this._extensionManager = Main.extensionManager; + this._timedMarginsID = 0; + this._margins = {}; + this._emID = this._extensionManager.connect('extension-state-changed', (_obj, extension) => { + if (!extension) + return; + + // If an extension is being enabled and lacks the DesktopIconsUsableArea object, we can avoid launching a refresh + if (extension.state === ExtensionUtils.ExtensionState.ENABLED) { + this._sendMarginsToExtension(extension); + return; + } + // if the extension is being disabled, we must do a full refresh, because if there were other extensions originally + // loaded after that extension, those extensions will be disabled and enabled again without notification + this._changedMargins(); + }); + } + + /** + * Sets or updates the top, bottom, left and right margins for a + * monitor. Values are measured from the monitor border (and NOT from + * the workspace border). + * + * @param {int} monitor Monitor number to which set the margins. + * A negative value means "the primary monitor". + * @param {int} top Top margin in pixels + * @param {int} bottom Bottom margin in pixels + * @param {int} left Left margin in pixels + * @param {int} right Right margin in pixels + */ + setMargins(monitor, top, bottom, left, right) { + this._margins[monitor] = { + 'top': top, + 'bottom': bottom, + 'left': left, + 'right': right + }; + this._changedMargins(); + } + + /** + * Clears the current margins. Must be called before configuring the monitors + * margins with setMargins(). + */ + resetMargins() { + this._margins = {}; + this._changedMargins(); + } + + /** + * Disconnects all the signals and removes the margins. + */ + destroy() { + if (this._emID) { + this._extensionManager.disconnect(this._emID); + this._emID = 0; + } + if (this._timedMarginsID) { + GLib.source_remove(this._timedMarginsID); + this._timedMarginsID = 0; + } + this._margins = null; + this._changedMargins(); + } + + _changedMargins() { + if (this._timedMarginsID) { + GLib.source_remove(this._timedMarginsID); + } + this._timedMarginsID = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, ()=> { + this._sendMarginsToAll(); + this._timedMarginsID = 0; + return GLib.SOURCE_REMOVE; + }); + } + + _sendMarginsToAll() { + this._extensionManager.getUuids().forEach(uuid => + this._sendMarginsToExtension(this._extensionManager.lookup(uuid))); + } + + _sendMarginsToExtension(extension) { + // check that the extension is an extension that has the logic to accept + // working margins + if (extension?.state !== ExtensionUtils.ExtensionState.ENABLED) + return; + + const usableArea = extension?.stateObj?.DesktopIconsUsableArea; + if (usableArea?.uuid === IDENTIFIER_UUID) + usableArea.setMarginsForExtension(Me.uuid, this._margins); + } +} diff --git a/panelManager.js b/panelManager.js index b824ccb..5ea951a 100755 --- a/panelManager.js +++ b/panelManager.js @@ -34,6 +34,7 @@ const PanelSettings = Me.imports.panelSettings; const Proximity = Me.imports.proximity; const Taskbar = Me.imports.taskbar; const Utils = Me.imports.utils; +const DesktopIconsIntegration = Me.imports.desktopIconsIntegration; const Gi = imports._gi; const GLib = imports.gi.GLib; @@ -64,6 +65,9 @@ var PanelManager = class { } enable(reset) { + if (!reset) + this._desktopIconsUsableArea = new DesktopIconsIntegration.DesktopIconsUsableAreaClass(); + let dtpPrimaryIndex = Me.settings.get_int('primary-monitor'); this.dtpPrimaryMonitor = Main.layoutManager.monitors[dtpPrimaryIndex] || Main.layoutManager.primaryMonitor; @@ -97,6 +101,7 @@ var PanelManager = class { p.taskbar.iconAnimator.start(); }); + this._setDesktopIconsMargins(); //in 3.32, BoxPointer now inherits St.Widget if (BoxPointer.BoxPointer.prototype.vfunc_get_preferred_height) { let panelManager = this; @@ -169,6 +174,16 @@ var PanelManager = class { 'changed::intellihide-key-toggle-text', () => this._setKeyBindings(true) ], + [ + Me.settings, + 'changed::panel-sizes', + () => { + GLib.idle_add(GLib.PRIORITY_LOW, () => { + this._setDesktopIconsMargins(); + return GLib.SOURCE_REMOVE; + }); + } + ], [ Utils.DisplayWrapper.getMonitorManager(), 'monitors-changed', @@ -268,6 +283,28 @@ var PanelManager = class { delete LookingGlass.LookingGlass.prototype._oldOpen delete Main.panel.style; + this._desktopIconsUsableArea.destroy(); + this._desktopIconsUsableArea = null; + } + + _setDesktopIconsMargins() { + this._desktopIconsUsableArea?.resetMargins(); + this.allPanels.forEach(p => { + switch(p.geom.position) { + case St.Side.TOP: + this._desktopIconsUsableArea?.setMargins(p.monitor.index, p.geom.h, 0, 0, 0); + break; + case St.Side.BOTTOM: + this._desktopIconsUsableArea?.setMargins(p.monitor.index, 0, p.geom.h, 0, 0); + break; + case St.Side.LEFT: + this._desktopIconsUsableArea?.setMargins(p.monitor.index, 0, 0, p.geom.w, 0); + break; + case St.Side.RIGHT: + this._desktopIconsUsableArea?.setMargins(p.monitor.index, 0, 0, 0, p.geom.w); + break; + } + }); } setFocusedMonitor(monitor) {