5 Commits
40.20 ... 65.2

Author SHA1 Message Date
Artyom Zorin
bb69c75c70 Bump to version 65.2 2025-02-27 15:46:57 +00:00
Artyom Zorin
f46cab04cb Bump to version 56.11 2024-10-20 18:00:25 +01:00
Artyom Zorin
de47b50149 Updated French translations based on contribution from Zac0511 2024-10-20 17:55:55 +01:00
Artyom Zorin
d396f3af52 Bump to verison 56.10 2024-09-09 17:46:17 +01:00
Artyom Zorin
2a447787a5 Bump to version 56.9 2024-09-03 14:08:20 +01:00
65 changed files with 32931 additions and 21384 deletions

2
.gitignore vendored
View File

@@ -4,4 +4,4 @@ gschemas.compiled
zorin-taskbar@zorinos.com*.zip zorin-taskbar@zorinos.com*.zip
*.mo *.mo
po/zorin-taskbar.pot po/zorin-taskbar.pot
Settings.ui.h ui/*.ui.h

View File

@@ -2,7 +2,9 @@
UUID = zorin-taskbar@zorinos.com UUID = zorin-taskbar@zorinos.com
BASE_MODULES = extension.js stylesheet.css metadata.json COPYING README.md BASE_MODULES = extension.js stylesheet.css metadata.json COPYING README.md
EXTRA_MODULES = appIcons.js convenience.js panel.js panelManager.js proximity.js intellihide.js progress.js panelPositions.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 desktopIconsIntegration.js
UI_MODULES = ui/BoxDynamicOpacityOptions.ui ui/BoxGroupAppsOptions.ui ui/BoxIntellihideOptions.ui ui/BoxMiddleClickOptions.ui ui/BoxOverlayShortcut.ui ui/BoxShowDateMenuOptions.ui ui/BoxShowDesktopOptions.ui ui/BoxWindowPreviewOptions.ui ui/SettingsAction.ui ui/SettingsBehavior.ui ui/SettingsPosition.ui ui/SettingsStyle.ui
EXTRA_IMAGES = show-desktop-symbolic.svg EXTRA_IMAGES = show-desktop-symbolic.svg
TOLOCALIZE = prefs.js appIcons.js TOLOCALIZE = prefs.js appIcons.js
@@ -18,7 +20,7 @@ INSTALLNAME = zorin-taskbar@zorinos.com
# in the metadata and in the generated zip-file. # in the metadata and in the generated zip-file.
ifdef VERSION ifdef VERSION
else else
VERSION = 40 VERSION = 65
endif endif
ifdef TARGET ifdef TARGET
@@ -44,11 +46,17 @@ mergepo: potfile
msgmerge -U $$l ./po/zorin-taskbar.pot; \ msgmerge -U $$l ./po/zorin-taskbar.pot; \
done; done;
./po/zorin-taskbar.pot: $(TOLOCALIZE) Settings.ui ./po/zorin-taskbar.pot: $(TOLOCALIZE)
mkdir -p po mkdir -p po
xgettext -k_ -kN_ -o po/zorin-taskbar.pot --package-name "Zorin Taskbar" $(TOLOCALIZE) xgettext -k_ -kN_ -o po/zorin-taskbar.pot --package-name "Zorin Taskbar" $(TOLOCALIZE) --from-code=UTF-8
intltool-extract --type=gettext/glade Settings.ui
xgettext -k_ -kN_ --join-existing -o po/zorin-taskbar.pot Settings.ui.h for l in $(UI_MODULES) ; do \
intltool-extract --type=gettext/glade $$l; \
xgettext -k_ -kN_ -o po/zorin-taskbar.pot $$l.h --join-existing --from-code=UTF-8; \
rm -rf $$l.h; \
done;
sed -i -e 's/&\#10;/\\n/g' po/zorin-taskbar.pot
./po/%.mo: ./po/%.po ./po/%.mo: ./po/%.po
msgfmt -c $< -o $@ msgfmt -c $< -o $@
@@ -72,10 +80,8 @@ _build: all
-rm -fR ./_build -rm -fR ./_build
mkdir -p _build mkdir -p _build
cp $(BASE_MODULES) $(EXTRA_MODULES) _build cp $(BASE_MODULES) $(EXTRA_MODULES) _build
mkdir -p _build/ui
ifeq ($(TARGET),ego) cp $(UI_MODULES) _build/ui
find _build -name '*.js' -exec sed -i '/\/\/!start-update/,/\/\/!end-update/d' {} +
endif
mkdir -p _build/img mkdir -p _build/img
cd img ; cp $(EXTRA_IMAGES) ../_build/img/ cd img ; cp $(EXTRA_IMAGES) ../_build/img/

View File

@@ -1,4 +1,4 @@
# Zorin Taskbar # Zorin Taskbar
The official taskbar for Zorin OS. The official taskbar for Zorin OS.
Based on the [Dash to Panel](https://github.com/home-sweet-gnome/dash-to-panel) Gnome Shell extension and the [Dash to Dock](https://github.com/micheleg/dash-to-dock) extension by micheleg. Re-based on the [Dash to Panel](https://github.com/home-sweet-gnome/dash-to-panel) GNOME Shell extension. Dash to Panel was initially based on the original version of Zorin Taskbar from 2016, with some code derived from the [Dash to Dock](https://github.com/micheleg/dash-to-dock) extension by micheleg.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,89 +0,0 @@
/*
* This file is part of the Zorin Taskbar extension for Zorin OS.
*
* 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, see <http://www.gnu.org/licenses/>.
*
*
* Credits:
* This file is based on code from the Dash to Dock extension by micheleg
* and code from the Dash to Panel extension
* Some code was also adapted from the upstream Gnome Shell source code.
*/
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
/**
* initTranslations:
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
*/
function initTranslations(domain) {
let extension = ExtensionUtils.getCurrentExtension();
domain = domain || extension.metadata['gettext-domain'];
// Check if this extension was built with "make zip-file", and thus
// has the locale files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell
let localeDir = extension.dir.get_child('locale');
if (localeDir.query_exists(null))
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
/**
* getSettings:
* @schema: (optional): the GSettings schema id
*
* Builds and return a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is not provided, it is taken from
* metadata['settings-schema'].
*/
function getSettings(schema) {
let extension = ExtensionUtils.getCurrentExtension();
schema = schema || extension.metadata['settings-schema'];
const GioSSS = Gio.SettingsSchemaSource;
// Check if this extension was built with "make zip-file", and thus
// has the schema files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell (and therefore schemas are available
// in the standard folders)
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
else
schemaSource = GioSSS.get_default();
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
throw new Error('Schema ' + schema + ' could not be found for extension '
+ extension.metadata.uuid + '. Please check your installation.');
return new Gio.Settings({
settings_schema: schemaObj
});
}

123
debian/changelog vendored
View File

@@ -1,3 +1,126 @@
gnome-shell-extension-zorin-taskbar (65.2) noble; urgency=medium
* Separated floating rounded theme from intellihide as an independent
styling option
-- Artyom Zorin <azorin@zoringroup.com> Thu, 27 Feb 2025 13:57:03 +0000
gnome-shell-extension-zorin-taskbar (65.1) noble; urgency=medium
* Fixed various bugs
-- Artyom Zorin <azorin@zoringroup.com> Wed, 26 Feb 2025 12:20:34 +0000
gnome-shell-extension-zorin-taskbar (65) noble; urgency=medium
* Re-based on upstream version 65
-- Artyom Zorin <azorin@zoringroup.com> Tue, 25 Feb 2025 22:29:43 +0000
gnome-shell-extension-zorin-taskbar (56.11) jammy; urgency=medium
* Updated French translations
-- Artyom Zorin <azorin@zoringroup.com> Sun, 20 Oct 2024 17:58:19 +0100
gnome-shell-extension-zorin-taskbar (56.10) jammy; urgency=medium
* Bug fix for window previews
-- Artyom Zorin <azorin@zoringroup.com> Mon, 09 Sep 2024 17:44:12 +0100
gnome-shell-extension-zorin-taskbar (56.9) jammy; urgency=medium
* Increased window preview leave timeout to 250ms
-- Artyom Zorin <azorin@zoringroup.com> Tue, 03 Sep 2024 14:04:19 +0100
gnome-shell-extension-zorin-taskbar (56.8) jammy; urgency=medium
* Fixed barrier code
-- Artyom Zorin <azorin@zoringroup.com> Mon, 12 Aug 2024 23:38:18 +0100
gnome-shell-extension-zorin-taskbar (56.7) jammy; urgency=medium
* Added link to Application Switching settings to set workspace and
monitor isolation behaviour
-- Artyom Zorin <azorin@zoringroup.com> Wed, 15 May 2024 19:21:08 +0100
gnome-shell-extension-zorin-taskbar (56.6) jammy; urgency=medium
* Correctly handle desktop icons when calculating proximity
-- Artyom Zorin <azorin@zoringroup.com> Tue, 27 Feb 2024 20:11:37 +0000
gnome-shell-extension-zorin-taskbar (56.5) jammy; urgency=medium
* Fixed show desktop functionality
-- Artyom Zorin <azorin@zoringroup.com> Wed, 13 Dec 2023 17:22:08 +0000
gnome-shell-extension-zorin-taskbar (56.4) jammy; urgency=medium
* Fixed regression with shortcuts overlay
-- Artyom Zorin <azorin@zoringroup.com> Wed, 13 Dec 2023 16:21:07 +0000
gnome-shell-extension-zorin-taskbar (56.3) jammy; urgency=medium
* Adjusted shortcut-num-keys default setting
-- Artyom Zorin <azorin@zoringroup.com> Tue, 12 Dec 2023 22:21:55 +0000
gnome-shell-extension-zorin-taskbar (56.2) jammy; urgency=medium
* Fixed floating theme centering bug
-- Artyom Zorin <azorin@zoringroup.com> Sun, 10 Dec 2023 18:41:12 +0000
gnome-shell-extension-zorin-taskbar (56.1) jammy; urgency=medium
* Moved isolate settings to GNOME Control Center
-- Artyom Zorin <azorin@zoringroup.com> Sat, 18 Nov 2023 19:23:50 +0000
gnome-shell-extension-zorin-taskbar (56.0.2) jammy; urgency=medium
* Removed blue background on favorite apps when dragging app icons
-- Artyom Zorin <azorin@zoringroup.com> Wed, 01 Nov 2023 12:39:55 +0000
gnome-shell-extension-zorin-taskbar (56.0.1) jammy; urgency=medium
* Corrected Makefile
-- Artyom Zorin <azorin@zoringroup.com> Wed, 31 May 2023 01:23:02 +0100
gnome-shell-extension-zorin-taskbar (56) jammy; urgency=medium
* Re-based on upstream version 56 as at commit
9274982189f2d5306afaf29f274d007f0cd12d48
-- Artyom Zorin <azorin@zoringroup.com> Wed, 31 May 2023 00:14:18 +0100
gnome-shell-extension-zorin-taskbar (40.23) focal; urgency=medium
* Changed default window preview size to 200px
-- Artyom Zorin <azorin@zoringroup.com> Sat, 16 Oct 2021 12:44:27 +0100
gnome-shell-extension-zorin-taskbar (40.22) focal; urgency=medium
* Fixed Spanish translations
-- Artyom Zorin <azorin@zoringroup.com> Sun, 22 Aug 2021 16:45:29 +0100
gnome-shell-extension-zorin-taskbar (40.21) focal; urgency=medium
* Updated Spanish translations
-- Artyom Zorin <azorin@zoringroup.com> Sun, 22 Aug 2021 15:49:06 +0100
gnome-shell-extension-zorin-taskbar (40.20) focal; urgency=medium gnome-shell-extension-zorin-taskbar (40.20) focal; urgency=medium
* Corrected translation string * Corrected translation string

8
debian/control vendored
View File

@@ -2,12 +2,12 @@ Source: gnome-shell-extension-zorin-taskbar
Section: gnome Section: gnome
Priority: optional Priority: optional
Maintainer: Artyom Zorin <azorin@zoringroup.com> Maintainer: Artyom Zorin <azorin@zoringroup.com>
Build-Depends: debhelper-compat (= 12), libglib2.0-bin, zip Build-Depends: debhelper-compat (= 13), libglib2.0-bin, zip
Standards-Version: 4.5.0 Standards-Version: 4.6.0
Rules-Requires-Root: no Rules-Requires-Root: no
Package: gnome-shell-extension-zorin-taskbar Package: gnome-shell-extension-zorin-taskbar
Architecture: all Architecture: all
Depends: ${misc:Depends}, gnome-shell (>= 3.18) Depends: ${misc:Depends}, gnome-shell (>= 46), gnome-shell (<< 48~)
Description: Zorin Taskbar extension Description: Zorin Taskbar extension
A taskbar extension for the Zorin Desktop environment. A taskbar extension for the Zorin OS desktop.

10
debian/copyright vendored
View File

@@ -2,8 +2,8 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: gnome-shell-extension-zorin-taskbar Upstream-Name: gnome-shell-extension-zorin-taskbar
Files: * Files: *
Copyright: 2016-2020, Jason DeRose (https://github.com/jderose9) Copyright: 2016-2025, Jason DeRose (https://github.com/jderose9)
2016-2020, Zorin OS Technologies Ltd. 2016-2025, Zorin OS Technologies Ltd.
License: GPL-2+ License: GPL-2+
Files: po/cs.po Files: po/cs.po
@@ -52,8 +52,12 @@ Files: po/tr.po
Copyright: 2018 Serdar Sağlam <teknomobil@yandex.com> Copyright: 2018 Serdar Sağlam <teknomobil@yandex.com>
License: GPL-2+ License: GPL-2+
Files: po/sk.po
Copyright: 2021 Jose Riha <jose1711@gmail.com>
License: GPL-2+
Files: debian/* Files: debian/*
Copyright: 2017-2020 Jonathan Carter <jcc@debian.org> Copyright: 2017-2021 Jonathan Carter <jcc@debian.org>
License: GPL-2+ License: GPL-2+
License: GPL-2+ License: GPL-2+

165
desktopIconsIntegration.js Normal file
View File

@@ -0,0 +1,165 @@
/*
* 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.
*
*******************************************************************************/
import GLib from 'gi://GLib';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as ExtensionUtils from 'resource:///org/gnome/shell/misc/extensionUtils.js';
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
const IDENTIFIER_UUID = "130cbc66-235c-4bd6-8571-98d2d8bba5e2";
export class DesktopIconsUsableAreaClass {
_checkIfExtensionIsEnabled(extension) {
return (extension?.state === ExtensionUtils.ExtensionState.ENABLED) ||
(extension?.state === ExtensionUtils.ExtensionState.ACTIVE);
}
constructor() {
const Me = Extension.lookupByURL(import.meta.url);
this._UUID = Me.uuid;
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 (this._checkIfExtensionIsEnabled(extension)) {
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 (!this._checkIfExtensionIsEnabled(extension))
return;
const usableArea = extension?.stateObj?.DesktopIconsUsableArea;
if (usableArea?.uuid === IDENTIFIER_UUID)
usableArea.setMarginsForExtension(this._UUID, this._margins);
}
}

View File

@@ -17,124 +17,116 @@
*/ */
const Main = imports.ui.main; import Gio from 'gi://Gio';
const Meta = imports.gi.Meta;
const Gio = imports.gi.Gio; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const GLib = imports.gi.GLib; import {EventEmitter} from 'resource:///org/gnome/shell/misc/signals.js';
const Lang = imports.lang; import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
const Shell = imports.gi.Shell;
const St = imports.gi.St; import * as PanelManager from './panelManager.js';
const WindowManager = imports.ui.windowManager; import * as AppIcons from './appIcons.js';
const ExtensionUtils = imports.misc.extensionUtils;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const PanelManager = Me.imports.panelManager;
const Utils = Me.imports.utils;
const ZORIN_DASH_UUID = 'zorin-dash@zorinos.com'; const ZORIN_DASH_UUID = 'zorin-dash@zorinos.com';
let panelManager; let panelManager;
let oldDash;
let extensionChangedHandler; let extensionChangedHandler;
let startupCompleteHandler;
let disabledZorinDash; let disabledZorinDash;
let extensionSystem = (Main.extensionManager || imports.ui.extensionSystem); let extensionSystem = Main.extensionManager;
function init() { export let DTP_EXTENSION = null;
Convenience.initTranslations(Utils.TRANSLATION_DOMAIN); export let SETTINGS = null;
export let DESKTOPSETTINGS = null;
//create an object that persists until gnome-shell is restarted, even if the extension is disabled export let TERMINALSETTINGS = null;
Me.persistentStorage = {}; export let PERSISTENTSTORAGE = null;
} export let EXTENSION_UUID = null;
export let EXTENSION_PATH = null;
function enable() { export default class ZorinTaskbarExtension extends Extension {
// The Zorin Dash extension might get enabled after this extension constructor(metadata) {
extensionChangedHandler = extensionSystem.connect('extension-state-changed', (data, extension) => { super(metadata);
if (extension.uuid === ZORIN_DASH_UUID && extension.state === 1) {
_enable();
}
});
//create a global object that can emit signals and conveniently expose functionalities to other extensions this._realHasOverview = Main.sessionMode.hasOverview;
global.zorinTaskbar = {};
Signals.addSignalMethods(global.zorinTaskbar); //create an object that persists until gnome-shell is restarted, even if the extension is disabled
PERSISTENTSTORAGE = {};
_enable();
}
function _enable() {
let zorinDash = Main.extensionManager ?
Main.extensionManager.lookup(ZORIN_DASH_UUID) : //gnome-shell >= 3.33.4
ExtensionUtils.extensions[ZORIN_DASH_UUID];
if (zorinDash && zorinDash.stateObj && zorinDash.stateObj.dockManager) {
// Disable Zorin Dash
let extensionOrder = (extensionSystem.extensionOrder || extensionSystem._extensionOrder);
Utils.getStageTheme().get_theme().unload_stylesheet(zorinDash.stylesheet);
zorinDash.stateObj.disable();
disabledZorinDash = true;
zorinDash.state = 2; //ExtensionState.DISABLED
extensionOrder.splice(extensionOrder.indexOf(ZORIN_DASH_UUID), 1);
//reset to prevent conflicts with the zorin-dash
if (panelManager) {
disable(true);
}
} }
if (panelManager) return; //already initialized enable() {
DTP_EXTENSION = this;
Me.settings = Convenience.getSettings('org.gnome.shell.extensions.zorin-taskbar'); // The Zorin Dash extension might get enabled after this extension
Me.desktopSettings = Convenience.getSettings('org.gnome.desktop.interface'); extensionChangedHandler = extensionSystem.connect('extension-state-changed', (data, extension) => {
if (extension.uuid === ZORIN_DASH_UUID && extension.state === 1) {
_enable(this);
}
});
panelManager = new PanelManager.dtpPanelManager(); //create a global object that can emit signals and conveniently expose functionalities to other extensions
global.zorinTaskbar = new EventEmitter();
_enable(this);
}
disable(reset = false) {
panelManager.disable();
DTP_EXTENSION = null;
SETTINGS = null;
DESKTOPSETTINGS = null;
TERMINALSETTINGS = null;
panelManager = null;
if (!reset) {
extensionSystem.disconnect(extensionChangedHandler);
if (disabledZorinDash) {
disabledZorinDash = false;
extensionSystem.enableExtension(ZORIN_DASH_UUID);
}
delete global.zorinTaskbar;
AppIcons.resetRecentlyClickedApp();
}
if (startupCompleteHandler) {
Main.layoutManager.disconnect(startupCompleteHandler);
startupCompleteHandler = null;
}
Main.sessionMode.hasOverview = this._realHasOverview;
}
}
function _enable(extension) {
let enabled = global.settings.get_strv('enabled-extensions');
if (enabled?.indexOf(ZORIN_DASH_UUID) >= 0) {
disabledZorinDash = true;
extensionSystem.disableExtension(ZORIN_DASH_UUID);
}
if (panelManager)
return panelManager.toggleDash(); // already initialized but Zorin Dash restored the original dash on disable
SETTINGS = extension.getSettings('org.gnome.shell.extensions.zorin-taskbar');
DESKTOPSETTINGS = new Gio.Settings({schema_id: 'org.gnome.desktop.interface'});
TERMINALSETTINGS = new Gio.Settings({schema_id: 'org.gnome.desktop.default-applications.terminal'})
EXTENSION_UUID = extension.uuid
EXTENSION_PATH = extension.path
Main.layoutManager.startInOverview = false;
if (Main.layoutManager._startingUp) {
Main.sessionMode.hasOverview = false;
startupCompleteHandler = Main.layoutManager.connect('startup-complete', () => {
Main.sessionMode.hasOverview = extension._realHasOverview
});
}
panelManager = new PanelManager.PanelManager();
panelManager.enable(); panelManager.enable();
Utils.removeKeybinding('open-application-menu');
Utils.addKeybinding(
'open-application-menu',
new Gio.Settings({ schema_id: WindowManager.SHELL_KEYBINDINGS_SCHEMA }),
Lang.bind(this, function() {
panelManager.primaryPanel.taskbar.popupFocusedAppSecondaryMenu();
}),
Shell.ActionMode.NORMAL | Shell.ActionMode.POPUP
);
// Pretend I'm the dash: meant to make appgrd swarm animation come from the
// right position of the appShowButton.
oldDash = Main.overview._dash;
Main.overview._dash = panelManager.primaryPanel.taskbar;
}
function disable(reset) {
panelManager.disable();
Main.overview._dash = oldDash;
Me.settings.run_dispose();
Me.desktopSettings.run_dispose();
delete Me.settings;
oldDash = null;
panelManager = null;
Utils.removeKeybinding('open-application-menu');
Utils.addKeybinding(
'open-application-menu',
new Gio.Settings({ schema_id: WindowManager.SHELL_KEYBINDINGS_SCHEMA }),
Lang.bind(Main.wm, Main.wm._toggleAppMenu),
Shell.ActionMode.NORMAL | Shell.ActionMode.POPUP
);
if (!reset) {
extensionSystem.disconnect(extensionChangedHandler);
delete global.zorinTaskbar;
// Re-enable Zorin Dash if it was disabled by Zorin Taskbar
if (disabledZorinDash && Main.sessionMode.allowExtensions) {
(extensionSystem._callExtensionEnable || extensionSystem.enableExtension).call(extensionSystem, ZORIN_DASH_UUID);
}
}
} }

View File

@@ -18,22 +18,20 @@
* This file is based on code from the Dash to Panel extension * This file is based on code from the Dash to Panel extension
*/ */
const Lang = imports.lang; import Clutter from 'gi://Clutter';
const Clutter = imports.gi.Clutter; import Meta from 'gi://Meta';
const Meta = imports.gi.Meta; import Shell from 'gi://Shell';
const Shell = imports.gi.Shell; import St from 'gi://St';
const St = imports.gi.St;
var GrabHelper = imports.ui.grabHelper; import * as GrabHelper from 'resource:///org/gnome/shell/ui/grabHelper.js';
const Layout = imports.ui.layout; import * as Layout from 'resource:///org/gnome/shell/ui/layout.js';
const Main = imports.ui.main; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const OverviewControls = imports.ui.overviewControls; import * as OverviewControls from 'resource:///org/gnome/shell/ui/overviewControls.js';
const PointerWatcher = imports.ui.pointerWatcher; import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.js';
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Proximity from './proximity.js';
const Panel = Me.imports.panel; import * as Utils from './utils.js';
const Proximity = Me.imports.proximity; import {SETTINGS} from './extension.js';
const Utils = Me.imports.utils;
var INTELLIHIDE_PRESSURE_THRESHOLD = 100; var INTELLIHIDE_PRESSURE_THRESHOLD = 100;
var INTELLIHIDE_PRESSURE_TIME = 1000; var INTELLIHIDE_PRESSURE_TIME = 1000;
@@ -51,20 +49,18 @@ const MIN_UPDATE_MS = 250;
const T1 = 'checkGrabTimeout'; const T1 = 'checkGrabTimeout';
const T2 = 'limitUpdateTimeout'; const T2 = 'limitUpdateTimeout';
const T3 = 'postAnimateTimeout'; const T3 = 'postAnimateTimeout';
const T4 = 'panelBoxClipTimeout';
var SIDE_CONTROLS_ANIMATION_TIME = OverviewControls.SIDE_CONTROLS_ANIMATION_TIME / (OverviewControls.SIDE_CONTROLS_ANIMATION_TIME > 1 ? 1000 : 1); const SIDE_CONTROLS_ANIMATION_TIME = OverviewControls.SIDE_CONTROLS_ANIMATION_TIME / (OverviewControls.SIDE_CONTROLS_ANIMATION_TIME > 1 ? 1000 : 1);
var Hold = { export const Hold = {
NONE: 0, NONE: 0,
TEMPORARY: 1, TEMPORARY: 1,
PERMANENT: 2 PERMANENT: 2
}; };
var Intellihide = Utils.defineClass({ export const Intellihide = class {
Name: 'ZorinTaskbar.Intellihide',
_init: function(dtpPanel) { constructor(dtpPanel) {
this._dtpPanel = dtpPanel; this._dtpPanel = dtpPanel;
this._panelBox = dtpPanel.panelBox; this._panelBox = dtpPanel.panelBox;
this._panelManager = dtpPanel.panelManager; this._panelManager = dtpPanel.panelManager;
@@ -74,14 +70,14 @@ var Intellihide = Utils.defineClass({
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler();
this._timeoutsHandler = new Utils.TimeoutsHandler(); this._timeoutsHandler = new Utils.TimeoutsHandler();
this._intellihideChangedId = Me.settings.connect('changed::intellihide', () => this._changeEnabledStatus()); this._intellihideChangedId = SETTINGS.connect('changed::intellihide', () => this._changeEnabledStatus());
this._intellihideOnlySecondaryChangedId = Me.settings.connect('changed::intellihide-only-secondary', () => this._changeEnabledStatus()); this._intellihideOnlySecondaryChangedId = SETTINGS.connect('changed::intellihide-only-secondary', () => this._changeEnabledStatus());
this.enabled = false; this.enabled = false;
this._changeEnabledStatus(); this._changeEnabledStatus();
}, }
enable: function() { enable() {
this.enabled = true; this.enabled = true;
this._monitor = this._dtpPanel.monitor; this._monitor = this._dtpPanel.monitor;
this._animationDestination = -1; this._animationDestination = -1;
@@ -96,10 +92,11 @@ var Intellihide = Utils.defineClass({
this._setTrackPanel(true); this._setTrackPanel(true);
this._bindGeneralSignals(); this._bindGeneralSignals();
if (Me.settings.get_boolean('intellihide-hide-from-windows')) { if (SETTINGS.get_boolean('intellihide-hide-from-windows')) {
this._proximityWatchId = this._proximityManager.createWatch( this._proximityWatchId = this._proximityManager.createWatch(
this._panelBox.get_parent(), this._panelBox.get_parent(),
Proximity.Mode[Me.settings.get_string('intellihide-behaviour')], this._dtpPanel.monitor.index,
Proximity.Mode[SETTINGS.get_string('intellihide-behaviour')],
0, 0, 0, 0,
overlap => { overlap => {
this._windowOverlap = overlap; this._windowOverlap = overlap;
@@ -110,10 +107,9 @@ var Intellihide = Utils.defineClass({
this._setRevealMechanism(); this._setRevealMechanism();
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition();
this._toggleFloatingRoundedTheme(); }
},
disable: function(reset) { disable(reset) {
if (this._proximityWatchId) { if (this._proximityWatchId) {
this._proximityManager.removeWatch(this._proximityWatchId); this._proximityManager.removeWatch(this._proximityWatchId);
} }
@@ -128,86 +124,64 @@ var Intellihide = Utils.defineClass({
this._revealPanel(!reset); this._revealPanel(!reset);
this.enabled = false; this.enabled = false;
}
if (this._panelBox.has_style_class_name('floating')) { destroy() {
this._panelBox.remove_style_class_name('floating'); SETTINGS.disconnect(this._intellihideChangedId);
SETTINGS.disconnect(this._intellihideOnlySecondaryChangedId);
this._resetPanelGeometry();
}
},
destroy: function() {
Me.settings.disconnect(this._intellihideChangedId);
Me.settings.disconnect(this._intellihideOnlySecondaryChangedId);
if (this.enabled) { if (this.enabled) {
this.disable(); this.disable();
} }
}, }
toggle: function() { toggle() {
this[this._holdStatus & Hold.PERMANENT ? 'release' : 'revealAndHold'](Hold.PERMANENT); this[this._holdStatus & Hold.PERMANENT ? 'release' : 'revealAndHold'](Hold.PERMANENT);
}, }
revealAndHold: function(holdStatus) { revealAndHold(holdStatus) {
if (this.enabled && !this._holdStatus) { if (this.enabled && !this._holdStatus) {
this._revealPanel(); this._revealPanel();
} }
this._holdStatus |= holdStatus; this._holdStatus |= holdStatus;
}, }
release: function(holdStatus) { release(holdStatus) {
this._holdStatus -= holdStatus; this._holdStatus -= holdStatus;
if (this.enabled && !this._holdStatus) { if (this.enabled && !this._holdStatus) {
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition();
} }
}, }
reset: function() { reset() {
this.disable(true); this.disable(true);
this.enable(); this.enable();
}, }
_toggleFloatingRoundedTheme: function() {
if (Me.settings.get_boolean('intellihide-floating-rounded-theme')) {
if (!this._panelBox.has_style_class_name('floating'))
this._panelBox.add_style_class_name('floating');
} else {
if (this._panelBox.has_style_class_name('floating'))
this._panelBox.remove_style_class_name('floating');
}
this._resetPanelGeometry();
},
_resetPanelGeometry: function() {
this._dtpPanel.geom = this._dtpPanel.getGeometry();
this._dtpPanel._setPanelGhostSize();
this._dtpPanel._setPanelPosition();
this._dtpPanel.dynamicTransparency.updateExternalStyle();
},
_changeEnabledStatus: function() { _changeEnabledStatus() {
let intellihide = Me.settings.get_boolean('intellihide'); let intellihide = SETTINGS.get_boolean('intellihide');
let onlySecondary = Me.settings.get_boolean('intellihide-only-secondary'); let onlySecondary = SETTINGS.get_boolean('intellihide-only-secondary');
let enabled = intellihide && !(this._dtpPanel.isPrimary && onlySecondary); let enabled = intellihide && !(this._dtpPanel.isPrimary && onlySecondary);
if (this.enabled !== enabled) { if (this.enabled !== enabled) {
this[enabled ? 'enable' : 'disable'](); this[enabled ? 'enable' : 'disable']();
} }
}, }
_bindGeneralSignals: function() { _bindGeneralSignals() {
this._signalsHandler.add( this._signalsHandler.add(
[ [
this._dtpPanel.taskbar, this._dtpPanel.taskbar,
'menu-closed', ['menu-closed', 'end-drag'],
() => this._panelBox.sync_hover() () => {
this._panelBox.sync_hover();
this._onHoverChanged();
}
], ],
[ [
Me.settings, SETTINGS,
[ [
'changed::intellihide-use-pressure', 'changed::intellihide-use-pressure',
'changed::intellihide-hide-from-windows', 'changed::intellihide-hide-from-windows',
@@ -215,13 +189,6 @@ var Intellihide = Utils.defineClass({
], ],
() => this.reset() () => this.reset()
], ],
[
Me.settings,
[
'changed::intellihide-floating-rounded-theme'
],
() => this._toggleFloatingRoundedTheme()
],
[ [
this._panelBox, this._panelBox,
'notify::hover', 'notify::hover',
@@ -241,17 +208,24 @@ var Intellihide = Utils.defineClass({
() => this._queueUpdatePanelPosition() () => this._queueUpdatePanelPosition()
] ]
); );
},
_onHoverChanged: function() { if (Meta.is_wayland_compositor()) {
this._signalsHandler.add([
this._panelBox,
'notify::visible',
() => Utils.setDisplayUnredirect(!this._panelBox.visible)
]);
}
}
_onHoverChanged() {
this._hoveredOut = !this._panelBox.hover; this._hoveredOut = !this._panelBox.hover;
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition();
}, }
_setTrackPanel(enable) {
let actorData = Utils.getTrackedActorData(this._panelBox)
_setTrackPanel: function(enable) {
let trackedIndex = Main.layoutManager._findActor(this._panelBox);
let actorData = Main.layoutManager._trackedActors[trackedIndex]
actorData.affectsStruts = !enable; actorData.affectsStruts = !enable;
actorData.trackFullscreen = !enable; actorData.trackFullscreen = !enable;
@@ -260,14 +234,16 @@ var Intellihide = Utils.defineClass({
this._panelBox.visible = enable ? enable : this._panelBox.visible; this._panelBox.visible = enable ? enable : this._panelBox.visible;
Main.layoutManager._queueUpdateRegions(); Main.layoutManager._queueUpdateRegions();
}, }
_setRevealMechanism: function() { _setRevealMechanism() {
if (global.display.supports_extended_barriers() && Me.settings.get_boolean('intellihide-use-pressure')) { let barriers = Meta.BackendCapabilities.BARRIERS
if ((global.backend.capabilities & barriers) === barriers && SETTINGS.get_boolean('intellihide-use-pressure')) {
this._edgeBarrier = this._createBarrier(); this._edgeBarrier = this._createBarrier();
this._pressureBarrier = new Layout.PressureBarrier( this._pressureBarrier = new Layout.PressureBarrier(
INTELLIHIDE_PRESSURE_THRESHOLD, INTELLIHIDE_PRESSURE_THRESHOLD,
INTELLIHIDE_PRESSURE_TIME, INTELLIHIDE_PRESSURE_TIME,
Shell.ActionMode.NORMAL Shell.ActionMode.NORMAL
); );
this._pressureBarrier.addBarrier(this._edgeBarrier); this._pressureBarrier.addBarrier(this._edgeBarrier);
@@ -276,9 +252,9 @@ var Intellihide = Utils.defineClass({
this._pointerWatch = PointerWatcher.getPointerWatcher() this._pointerWatch = PointerWatcher.getPointerWatcher()
.addWatch(CHECK_POINTER_MS, (x, y) => this._checkMousePointer(x, y)); .addWatch(CHECK_POINTER_MS, (x, y) => this._checkMousePointer(x, y));
} }
}, }
_removeRevealMechanism: function() { _removeRevealMechanism() {
if (this._pointerWatch) { if (this._pointerWatch) {
PointerWatcher.getPointerWatcher()._removeWatch(this._pointerWatch); PointerWatcher.getPointerWatcher()._removeWatch(this._pointerWatch);
} }
@@ -286,12 +262,14 @@ var Intellihide = Utils.defineClass({
if (this._pressureBarrier) { if (this._pressureBarrier) {
this._pressureBarrier.destroy(); this._pressureBarrier.destroy();
this._edgeBarrier.destroy(); this._edgeBarrier.destroy();
}
},
_createBarrier: function() { this._pressureBarrier = 0;
}
}
_createBarrier() {
let position = this._dtpPanel.geom.position; let position = this._dtpPanel.geom.position;
let opts = { display: global.display }; let opts = { backend: global.backend };
if (this._dtpPanel.checkIfVertical()) { if (this._dtpPanel.checkIfVertical()) {
opts.y1 = this._monitor.y; opts.y1 = this._monitor.y;
@@ -316,9 +294,9 @@ var Intellihide = Utils.defineClass({
} }
return new Meta.Barrier(opts); return new Meta.Barrier(opts);
}, }
_checkMousePointer: function(x, y) { _checkMousePointer(x, y) {
let position = this._dtpPanel.geom.position; let position = this._dtpPanel.geom.position;
if (!this._panelBox.hover && !Main.overview.visible && if (!this._panelBox.hover && !Main.overview.visible &&
@@ -330,9 +308,9 @@ var Intellihide = Utils.defineClass({
(y >= this._monitor.y && y < this._monitor.y + this._monitor.height))) { (y >= this._monitor.y && y < this._monitor.y + this._monitor.height))) {
this._queueUpdatePanelPosition(true); this._queueUpdatePanelPosition(true);
} }
}, }
_queueUpdatePanelPosition: function(fromRevealMechanism) { _queueUpdatePanelPosition(fromRevealMechanism) {
if (!fromRevealMechanism && this._timeoutsHandler.getId(T2) && !Main.overview.visible) { if (!fromRevealMechanism && this._timeoutsHandler.getId(T2) && !Main.overview.visible) {
//unless this is a mouse interaction or entering/leaving the overview, limit the number //unless this is a mouse interaction or entering/leaving the overview, limit the number
//of updates, but remember to update again when the limit timeout is reached //of updates, but remember to update again when the limit timeout is reached
@@ -341,18 +319,18 @@ var Intellihide = Utils.defineClass({
this._checkIfShouldBeVisible(fromRevealMechanism) ? this._revealPanel() : this._hidePanel(); this._checkIfShouldBeVisible(fromRevealMechanism) ? this._revealPanel() : this._hidePanel();
this._timeoutsHandler.add([T2, MIN_UPDATE_MS, () => this._endLimitUpdate()]); this._timeoutsHandler.add([T2, MIN_UPDATE_MS, () => this._endLimitUpdate()]);
} }
}, }
_endLimitUpdate: function() { _endLimitUpdate() {
if (this._pendingUpdate) { if (this._pendingUpdate) {
this._pendingUpdate = false; this._pendingUpdate = false;
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition();
} }
}, }
_checkIfShouldBeVisible: function(fromRevealMechanism) { _checkIfShouldBeVisible(fromRevealMechanism) {
if (Main.overview.visibleTarget || this._dtpPanel.taskbar.previewMenu.opened || if (Main.overview.visibleTarget || this._dtpPanel.taskbar.previewMenu.opened ||
this._panelBox.get_hover() || this._checkIfGrab()) { this._dtpPanel.taskbar._dragMonitor || this._panelBox.get_hover() || this._checkIfGrab()) {
return true; return true;
} }
@@ -361,46 +339,61 @@ var Intellihide = Utils.defineClass({
//the user is trying to reveal the panel //the user is trying to reveal the panel
if (this._monitor.inFullscreen && !mouseBtnIsPressed) { if (this._monitor.inFullscreen && !mouseBtnIsPressed) {
return Me.settings.get_boolean('intellihide-show-in-fullscreen'); return SETTINGS.get_boolean('intellihide-show-in-fullscreen');
} }
return !mouseBtnIsPressed; return !mouseBtnIsPressed;
} }
if (!Me.settings.get_boolean('intellihide-hide-from-windows')) { if (!SETTINGS.get_boolean('intellihide-hide-from-windows')) {
return this._panelBox.hover; return this._panelBox.hover;
} }
return !this._windowOverlap; return !this._windowOverlap;
}, }
_checkIfGrab: function() { _checkIfGrab() {
if (GrabHelper._grabHelperStack.some(gh => gh._owner == this._dtpPanel.panel.actor)) { let isGrab
if (GrabHelper._grabHelperStack)
// gnome-shell < 42
isGrab = GrabHelper._grabHelperStack.some(gh => gh._owner == this._dtpPanel.panel)
else if (global.stage.get_grab_actor) {
// gnome-shell >= 42
let grabActor = global.stage.get_grab_actor()
let sourceActor = grabActor?._sourceActor || grabActor
isGrab = sourceActor &&
(sourceActor == Main.layoutManager.dummyCursor ||
this._dtpPanel.statusArea.quickSettings?.menu.actor.contains(sourceActor) ||
this._dtpPanel.panel.contains(sourceActor))
}
if (isGrab)
//there currently is a grab on a child of the panel, check again soon to catch its release //there currently is a grab on a child of the panel, check again soon to catch its release
this._timeoutsHandler.add([T1, CHECK_GRAB_MS, () => this._queueUpdatePanelPosition()]); this._timeoutsHandler.add([T1, CHECK_GRAB_MS, () => this._queueUpdatePanelPosition()]);
return true; return isGrab;
} }
},
_revealPanel: function(immediate) { _revealPanel(immediate) {
if (!this._panelBox.visible) { if (!this._panelBox.visible) {
this._panelBox.visible = true; this._panelBox.visible = true;
this._dtpPanel.taskbar._shownInitially = false; this._dtpPanel.taskbar._shownInitially = false;
} }
this._animatePanel(0, immediate); this._animatePanel(0, immediate);
}, }
_hidePanel: function(immediate) { _hidePanel(immediate) {
let position = this._dtpPanel.geom.position; let position = this._dtpPanel.geom.position;
let size = this._panelBox[position == St.Side.LEFT || position == St.Side.RIGHT ? 'width' : 'height']; let size = this._panelBox[position == St.Side.LEFT || position == St.Side.RIGHT ? 'width' : 'height'];
let coefficient = position == St.Side.TOP || position == St.Side.LEFT ? -1 : 1; let coefficient = position == St.Side.TOP || position == St.Side.LEFT ? -1 : 1;
this._animatePanel(size * coefficient, immediate); this._animatePanel(size * coefficient, immediate);
}, }
_animatePanel: function(destination, immediate) { _animatePanel(destination, immediate) {
let animating = Utils.isAnimating(this._panelBox, this._translationProp); let animating = Utils.isAnimating(this._panelBox, this._translationProp);
if (!((animating && destination === this._animationDestination) || if (!((animating && destination === this._animationDestination) ||
@@ -437,5 +430,5 @@ var Intellihide = Utils.defineClass({
} }
this._hoveredOut = false; this._hoveredOut = false;
}, }
}); }

View File

@@ -1,9 +1,9 @@
{ {
"extension-id": "zorin-taskbar", "extension-id": "zorin-taskbar",
"uuid": "zorin-taskbar@zorinos.com", "uuid": "zorin-taskbar@zorinos.com",
"name": "Zorin Taskbar", "name": "Zorin Taskbar",
"description": "A taskbar extension for the Zorin Desktop environment.", "description": "A taskbar extension for the Zorin OS desktop.",
"shell-version": [ "3.18", "3.20", "3.22", "3.24", "3.26", "3.28", "3.30", "3.32", "3.34", "3.36", "3.38" ], "shell-version": [ "46", "47" ],
"gettext-domain": "zorin-taskbar", "gettext-domain": "zorin-taskbar",
"version": 9999 "version": 65
} }

View File

@@ -20,108 +20,131 @@
* Some code was also adapted from the upstream Gnome Shell source code. * Some code was also adapted from the upstream Gnome Shell source code.
*/ */
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Intellihide from './intellihide.js';
const Intellihide = Me.imports.intellihide; import * as Utils from './utils.js';
const Utils = Me.imports.utils;
const Clutter = imports.gi.Clutter; import Clutter from 'gi://Clutter';
const Lang = imports.lang; import Gio from 'gi://Gio';
const Main = imports.ui.main; import Shell from 'gi://Shell';
const Shell = imports.gi.Shell; import St from 'gi://St';
const Gtk = imports.gi.Gtk; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const Gdk = imports.gi.Gdk; import * as WindowManager from 'resource:///org/gnome/shell/ui/windowManager.js';
const Gio = imports.gi.Gio; import {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js';
const Mainloop = imports.mainloop; import {InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js';
const IconGrid = imports.ui.iconGrid; import {SETTINGS} from './extension.js';
const ViewSelector = imports.ui.viewSelector;
const Meta = imports.gi.Meta;
const GS_HOTKEYS_KEY = 'switch-to-application-'; const GS_HOTKEYS_KEY = 'switch-to-application-';
const OVERLAY_TIMEOUT = 750; const OVERLAY_TIMEOUT = 750;
const SHORTCUT_TIMEOUT = 2000; const SHORTCUT_TIMEOUT = 2000;
// When the dash is shown, workspace window preview bottom labels go over it (default
// gnome-shell behavior), but when the extension hides the dash, leave some space
// so those labels don't go over a bottom panel
const LABEL_MARGIN = 60;
//timeout names //timeout names
const T1 = 'swipeEndTimeout'; const T1 = 'swipeEndTimeout';
const T2 = 'numberOverlayTimeout';
var dtpOverview = Utils.defineClass({ export const Overview = class {
Name: 'ZorinTaskbar.Overview',
_init: function() { constructor() {
this._injectionManager = new InjectionManager();
this._numHotkeys = 10; this._numHotkeys = 10;
this._timeoutsHandler = new Utils.TimeoutsHandler(); }
},
enable : function(panel) { enable (primaryPanel) {
this._panel = panel; this._panel = primaryPanel;
this.taskbar = panel.taskbar; this.taskbar = primaryPanel.taskbar;
this._injectionsHandler = new Utils.InjectionsHandler(); this._injectionsHandler = new Utils.InjectionsHandler();
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler();
this._timeoutsHandler = new Utils.TimeoutsHandler();
this._optionalWorkspaceIsolation(); this._optionalWorkspaceIsolation();
this._optionalHotKeys(); this._optionalHotKeys();
this._optionalNumberOverlay(); this._optionalNumberOverlay();
this._toggleDash();
},
disable: function () { this.toggleDash();
this._adaptAlloc();
this._signalsHandler.add([
SETTINGS,
[
'changed::panel-sizes'
],
() => this.toggleDash()
]);
}
disable() {
this._signalsHandler.destroy(); this._signalsHandler.destroy();
this._injectionsHandler.destroy(); this._injectionsHandler.destroy();
this._timeoutsHandler.destroy();
this._toggleDash(true); this._injectionManager.clear();
this.toggleDash(true);
// Remove key bindings // Remove key bindings
this._disableHotKeys(); this._disableHotKeys();
this._disableExtraShortcut(); this._disableExtraShortcut();
}, }
_toggleDash: function(visible) {
// To hide the dash, set its width to 1, so it's almost not taken into account by code
// calculaing the reserved space in the overview. The reason to keep it at 1 is
// to allow its visibility change to trigger an allocaion of the appGrid which
// in turn is triggergin the appsIcon spring animation, required when no other
// actors has this effect, i.e in horizontal mode and without the workspaceThumnails
// 1 static workspace only)
toggleDash(visible) {
if (visible === undefined) { if (visible === undefined) {
visible = false; visible = false;
} }
let visibilityFunc = visible ? 'show' : 'hide'; let visibilityFunc = visible ? 'show' : 'hide';
let width = visible ? -1 : 1; let height = visible ? -1 : LABEL_MARGIN * Utils.getScaleFactor();
let overviewControls = Main.overview._overview._controls || Main.overview._controls; let overviewControls = Main.overview._overview._controls;
overviewControls.dash.actor[visibilityFunc](); overviewControls.dash[visibilityFunc]();
overviewControls.dash.actor.set_width(width); overviewControls.dash.set_height(height);
}
// This force the recalculation of the icon size _adaptAlloc() {
overviewControls.dash._maxHeight = -1; let overviewControls = Main.overview._overview._controls
},
this._injectionManager.overrideMethod(Object.getPrototypeOf(overviewControls), 'vfunc_allocate',
(originalAllocate) =>
(box) => {
let focusedPanel = this._panel.panelManager.focusedMonitorPanel
if (focusedPanel) {
let position = focusedPanel.geom.position
let isBottom = position == St.Side.BOTTOM
if (focusedPanel.intellihide?.enabled) {
// Panel intellihide is enabled (struts aren't taken into account on overview allocation),
// dynamically modify the overview box to follow the reveal/hide animation
let { transitioning, finalState, progress } = overviewControls._stateAdjustment.getStateTransitionParams()
let size = focusedPanel.geom[focusedPanel.checkIfVertical() ? 'w' : 'h'] *
(transitioning ? Math.abs((finalState != 0 ? 0 : 1) - progress) : 1)
if (isBottom || position == St.Side.RIGHT)
box[focusedPanel.fixedCoord.c2] -= size
else
box[focusedPanel.fixedCoord.c1] += size
} else if (isBottom)
// The default overview allocation is very good and takes into account external
// struts, everywhere but the bottom where the dash is usually fixed anyway.
// If there is a bottom panel under the dash location, give it some space here
box.y2 -= focusedPanel.geom.h
}
originalAllocate.call(overviewControls, box)
}
);
}
/** /**
* Isolate overview to open new windows for inactive apps * Isolate overview to open new windows for inactive apps
*/ */
_optionalWorkspaceIsolation: function() { _optionalWorkspaceIsolation() {
let label = 'optionalWorkspaceIsolation'; let label = 'optionalWorkspaceIsolation';
this._signalsHandler.add([ let enable = () => {
Me.settings,
'changed::isolate-workspaces',
Lang.bind(this, function() {
this._panel.panelManager.allPanels.forEach(p => p.taskbar.resetAppIcons());
if (Me.settings.get_boolean('isolate-workspaces'))
Lang.bind(this, enable)();
else
Lang.bind(this, disable)();
})
]);
if (Me.settings.get_boolean('isolate-workspaces'))
Lang.bind(this, enable)();
function enable() {
this._injectionsHandler.removeWithLabel(label); this._injectionsHandler.removeWithLabel(label);
this._injectionsHandler.addWithLabel(label, [ this._injectionsHandler.addWithLabel(label, [
@@ -139,7 +162,7 @@ var dtpOverview = Utils.defineClass({
]); ]);
} }
function disable() { let disable = () => {
this._signalsHandler.removeWithLabel(label); this._signalsHandler.removeWithLabel(label);
this._injectionsHandler.removeWithLabel(label); this._injectionsHandler.removeWithLabel(label);
} }
@@ -156,15 +179,31 @@ var dtpOverview = Utils.defineClass({
return this.open_new_window(-1); return this.open_new_window(-1);
} }
},
this._signalsHandler.add([
SETTINGS,
'changed::isolate-workspaces',
() => {
this._panel.panelManager.allPanels.forEach(p => p.taskbar.resetAppIcons());
if (SETTINGS.get_boolean('isolate-workspaces'))
enable();
else
disable();
}
]);
if (SETTINGS.get_boolean('isolate-workspaces'))
enable();
}
// Hotkeys // Hotkeys
_activateApp: function(appIndex) { _activateApp(appIndex, modifiers) {
let seenApps = {}; let seenApps = {};
let apps = []; let apps = [];
this.taskbar._getAppIcons().forEach(function(appIcon) { this.taskbar._getAppIcons().forEach(appIcon => {
if (!seenApps[appIcon.app]) { if (!seenApps[appIcon.app] || this.taskbar.allowSplitApps) {
apps.push(appIcon); apps.push(appIcon);
} }
@@ -178,8 +217,8 @@ var dtpOverview = Utils.defineClass({
let seenAppCount = seenApps[appIcon.app]; let seenAppCount = seenApps[appIcon.app];
let windowCount = appIcon.window || appIcon._hotkeysCycle ? seenAppCount : appIcon._nWindows; let windowCount = appIcon.window || appIcon._hotkeysCycle ? seenAppCount : appIcon._nWindows;
if (Me.settings.get_boolean('shortcut-previews') && windowCount > 1 && if (SETTINGS.get_boolean('shortcut-previews') && windowCount > 1 &&
!(Clutter.get_current_event().get_state() & ~(Clutter.ModifierType.MOD1_MASK | Clutter.ModifierType.MOD4_MASK))) { //ignore the alt (MOD1_MASK) and super key (MOD4_MASK) !(modifiers & ~(Clutter.ModifierType.MOD1_MASK | Clutter.ModifierType.SUPER_MASK))) { //ignore the alt (MOD1_MASK) and super key (SUPER_MASK)
if (this._hotkeyPreviewCycleInfo && this._hotkeyPreviewCycleInfo.appIcon != appIcon) { if (this._hotkeyPreviewCycleInfo && this._hotkeyPreviewCycleInfo.appIcon != appIcon) {
this._endHotkeyPreviewCycle(); this._endHotkeyPreviewCycle();
} }
@@ -188,7 +227,7 @@ var dtpOverview = Utils.defineClass({
this._hotkeyPreviewCycleInfo = { this._hotkeyPreviewCycleInfo = {
appIcon: appIcon, appIcon: appIcon,
currentWindow: appIcon.window, currentWindow: appIcon.window,
keyFocusOutId: appIcon.actor.connect('key-focus-out', () => appIcon.actor.grab_key_focus()), keyFocusOutId: appIcon.connect('key-focus-out', () => appIcon.grab_key_focus()),
capturedEventId: global.stage.connect('captured-event', (actor, e) => { capturedEventId: global.stage.connect('captured-event', (actor, e) => {
if (e.type() == Clutter.EventType.KEY_RELEASE && e.get_key_symbol() == (Clutter.KEY_Super_L || Clutter.Super_L)) { if (e.type() == Clutter.EventType.KEY_RELEASE && e.get_key_symbol() == (Clutter.KEY_Super_L || Clutter.Super_L)) {
this._endHotkeyPreviewCycle(true); this._endHotkeyPreviewCycle(true);
@@ -200,8 +239,8 @@ var dtpOverview = Utils.defineClass({
appIcon._hotkeysCycle = appIcon.window; appIcon._hotkeysCycle = appIcon.window;
appIcon.window = null; appIcon.window = null;
appIcon._previewMenu.open(appIcon); appIcon._previewMenu.open(appIcon, true);
appIcon.actor.grab_key_focus(); appIcon.grab_key_focus();
} }
appIcon._previewMenu.focusNext(); appIcon._previewMenu.focusNext();
@@ -209,49 +248,50 @@ var dtpOverview = Utils.defineClass({
// Activate with button = 1, i.e. same as left click // Activate with button = 1, i.e. same as left click
let button = 1; let button = 1;
this._endHotkeyPreviewCycle(); this._endHotkeyPreviewCycle();
appIcon.activate(button, true); appIcon.activate(button, modifiers, !this.taskbar.allowSplitApps);
} }
} }
}, }
_endHotkeyPreviewCycle: function(focusWindow) { _endHotkeyPreviewCycle(focusWindow) {
if (this._hotkeyPreviewCycleInfo) { if (this._hotkeyPreviewCycleInfo) {
global.stage.disconnect(this._hotkeyPreviewCycleInfo.capturedEventId); global.stage.disconnect(this._hotkeyPreviewCycleInfo.capturedEventId);
this._hotkeyPreviewCycleInfo.appIcon.actor.disconnect(this._hotkeyPreviewCycleInfo.keyFocusOutId); this._hotkeyPreviewCycleInfo.appIcon.disconnect(this._hotkeyPreviewCycleInfo.keyFocusOutId);
if (focusWindow) { if (focusWindow) {
this._hotkeyPreviewCycleInfo.appIcon._previewMenu.activateFocused(); this._hotkeyPreviewCycleInfo.appIcon._previewMenu.activateFocused();
} } else
this._hotkeyPreviewCycleInfo.appIcon._previewMenu.close()
this._hotkeyPreviewCycleInfo.appIcon.window = this._hotkeyPreviewCycleInfo.currentWindow; this._hotkeyPreviewCycleInfo.appIcon.window = this._hotkeyPreviewCycleInfo.currentWindow;
delete this._hotkeyPreviewCycleInfo.appIcon._hotkeysCycle; delete this._hotkeyPreviewCycleInfo.appIcon._hotkeysCycle;
this._hotkeyPreviewCycleInfo = 0; this._hotkeyPreviewCycleInfo = 0;
} }
}, }
_optionalHotKeys: function() { _optionalHotKeys() {
this._hotKeysEnabled = false; this._hotKeysEnabled = false;
if (Me.settings.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys'))
this._enableHotKeys(); this._enableHotKeys();
this._signalsHandler.add([ this._signalsHandler.add([
Me.settings, SETTINGS,
'changed::hot-keys', 'changed::hot-keys',
Lang.bind(this, function() { () => {
if (Me.settings.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys'))
Lang.bind(this, this._enableHotKeys)(); this._enableHotKeys();
else else
Lang.bind(this, this._disableHotKeys)(); this._disableHotKeys();
}) }
]); ]);
}, }
_resetHotkeys: function() { _resetHotkeys() {
this._disableHotKeys(); this._disableHotKeys();
this._enableHotKeys(); this._enableHotKeys();
}, }
_enableHotKeys: function() { _enableHotKeys() {
if (this._hotKeysEnabled) if (this._hotKeysEnabled)
return; return;
@@ -263,9 +303,13 @@ var dtpOverview = Utils.defineClass({
} }
// Setup keyboard bindings for taskbar elements // Setup keyboard bindings for taskbar elements
let shortcutNumKeys = Me.settings.get_string('shortcut-num-keys'); let shortcutNumKeys = SETTINGS.get_string('shortcut-num-keys');
let bothNumKeys = shortcutNumKeys == 'BOTH'; let bothNumKeys = shortcutNumKeys == 'BOTH';
let keys = []; let keys = [];
let prefixModifiers = Clutter.ModifierType.SUPER_MASK
if (SETTINGS.get_string('hotkey-prefix-text') == 'SuperAlt')
prefixModifiers |= Clutter.ModifierType.MOD1_MASK
if (bothNumKeys || shortcutNumKeys == 'NUM_ROW') { if (bothNumKeys || shortcutNumKeys == 'NUM_ROW') {
keys.push('app-hotkey-', 'app-shift-hotkey-', 'app-ctrl-hotkey-'); // Regular numbers keys.push('app-hotkey-', 'app-shift-hotkey-', 'app-ctrl-hotkey-'); // Regular numbers
@@ -276,20 +320,27 @@ var dtpOverview = Utils.defineClass({
} }
keys.forEach( function(key) { keys.forEach( function(key) {
let modifiers = prefixModifiers
// for some reason, in gnome-shell >= 40 Clutter.get_current_event() is now empty
// for keyboard events. Create here the modifiers that are needed in appicon.activate
modifiers |= (key.indexOf('-shift-') >= 0 ? Clutter.ModifierType.SHIFT_MASK : 0)
modifiers |= (key.indexOf('-ctrl-') >= 0 ? Clutter.ModifierType.CONTROL_MASK : 0)
for (let i = 0; i < this._numHotkeys; i++) { for (let i = 0; i < this._numHotkeys; i++) {
let appNum = i; let appNum = i;
Utils.addKeybinding(key + (i + 1), Me.settings, () => this._activateApp(appNum)); Utils.addKeybinding(key + (i + 1), SETTINGS, () => this._activateApp(appNum, modifiers));
} }
}, this); }, this);
this._hotKeysEnabled = true; this._hotKeysEnabled = true;
if (Me.settings.get_string('hotkeys-overlay-combo') === 'ALWAYS') if (SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS')
this.taskbar.toggleNumberOverlay(true); this.taskbar.toggleNumberOverlay(true);
}, }
_disableHotKeys: function() { _disableHotKeys() {
if (!this._hotKeysEnabled) if (!this._hotKeysEnabled)
return; return;
@@ -302,7 +353,7 @@ var dtpOverview = Utils.defineClass({
}, this); }, this);
if (Main.wm._switchToApplication) { if (Main.wm._switchToApplication) {
let gsSettings = new Gio.Settings({ schema_id: imports.ui.windowManager.SHELL_KEYBINDINGS_SCHEMA }); let gsSettings = new Gio.Settings({ schema_id: WindowManager.SHELL_KEYBINDINGS_SCHEMA });
for (let i = 1; i < 10; ++i) { for (let i = 1; i < 10; ++i) {
Utils.addKeybinding(GS_HOTKEYS_KEY + i, gsSettings, Main.wm._switchToApplication.bind(Main.wm)); Utils.addKeybinding(GS_HOTKEYS_KEY + i, gsSettings, Main.wm._switchToApplication.bind(Main.wm));
@@ -312,61 +363,56 @@ var dtpOverview = Utils.defineClass({
this._hotKeysEnabled = false; this._hotKeysEnabled = false;
this.taskbar.toggleNumberOverlay(false); this.taskbar.toggleNumberOverlay(false);
}, }
_optionalNumberOverlay: function() { _optionalNumberOverlay() {
// Enable extra shortcut // Enable extra shortcut
if (Me.settings.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys'))
this._enableExtraShortcut(); this._enableExtraShortcut();
this._signalsHandler.add([ this._signalsHandler.add([
Me.settings, SETTINGS,
'changed::hot-keys', 'changed::hot-keys',
Lang.bind(this, this._checkHotkeysOptions) this._checkHotkeysOptions.bind(this)
], [ ], [
Me.settings, SETTINGS,
'changed::hotkeys-overlay-combo', 'changed::hotkeys-overlay-combo',
Lang.bind(this, function() { () => {
if (Me.settings.get_boolean('hot-keys') && Me.settings.get_string('hotkeys-overlay-combo') === 'ALWAYS') if (SETTINGS.get_boolean('hot-keys') && SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS')
this.taskbar.toggleNumberOverlay(true); this.taskbar.toggleNumberOverlay(true);
else else
this.taskbar.toggleNumberOverlay(false); this.taskbar.toggleNumberOverlay(false);
}) }
], [ ], [
Me.settings, SETTINGS,
'changed::shortcut-num-keys', 'changed::shortcut-num-keys',
() => this._resetHotkeys() () => this._resetHotkeys()
]); ]);
}, }
_checkHotkeysOptions: function() { _checkHotkeysOptions() {
if (Me.settings.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys'))
this._enableExtraShortcut(); this._enableExtraShortcut();
else else
this._disableExtraShortcut(); this._disableExtraShortcut();
}, }
_enableExtraShortcut: function() { _enableExtraShortcut() {
Utils.addKeybinding('shortcut', Me.settings, () => this._showOverlay(true)); Utils.addKeybinding('shortcut', SETTINGS, () => this._showOverlay(true));
}, }
_disableExtraShortcut: function() { _disableExtraShortcut() {
Utils.removeKeybinding('shortcut'); Utils.removeKeybinding('shortcut');
}, }
_showOverlay: function(overlayFromShortcut) { _showOverlay(overlayFromShortcut) {
//wait for intellihide timeout initialization //wait for intellihide timeout initialization
if (!this._panel.intellihide) { if (!this._panel.intellihide) {
return; return;
} }
// Restart the counting if the shortcut is pressed again // Restart the counting if the shortcut is pressed again
if (this._numberOverlayTimeoutId) { let hotkey_option = SETTINGS.get_string('hotkeys-overlay-combo');
Mainloop.source_remove(this._numberOverlayTimeoutId);
this._numberOverlayTimeoutId = 0;
}
let hotkey_option = Me.settings.get_string('hotkeys-overlay-combo');
if (hotkey_option === 'NEVER') if (hotkey_option === 'NEVER')
return; return;
@@ -383,14 +429,27 @@ var dtpOverview = Utils.defineClass({
} }
// Hide the overlay/dock after the timeout // Hide the overlay/dock after the timeout
this._numberOverlayTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, function() { this._timeoutsHandler.add([T2, timeout, () => {
this._numberOverlayTimeoutId = 0;
if (hotkey_option != 'ALWAYS') { if (hotkey_option != 'ALWAYS') {
this.taskbar.toggleNumberOverlay(false); this.taskbar.toggleNumberOverlay(false);
} }
this._panel.intellihide.release(Intellihide.Hold.TEMPORARY); this._panel.intellihide.release(Intellihide.Hold.TEMPORARY);
})); }]);
} }
});
_onSwipeBegin() {
this._swiping = true;
return true;
}
_onSwipeEnd() {
this._timeoutsHandler.add([
T1,
0,
() => this._swiping = false
]);
return true;
}
}

889
panel.js

File diff suppressed because it is too large Load Diff

621
panelManager.js Executable file → Normal file
View File

@@ -27,63 +27,54 @@
* Some code was also adapted from the upstream Gnome Shell source code. * Some code was also adapted from the upstream Gnome Shell source code.
*/ */
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Overview from './overview.js';
const Overview = Me.imports.overview; import * as Panel from './panel.js';
const Panel = Me.imports.panel; import * as PanelSettings from './panelSettings.js';
const Pos = Me.imports.panelPositions; import * as Proximity from './proximity.js';
const Proximity = Me.imports.proximity; import * as Utils from './utils.js';
const Taskbar = Me.imports.taskbar; import * as DesktopIconsIntegration from './desktopIconsIntegration.js';
const Utils = Me.imports.utils;
const Config = imports.misc.config; import GLib from 'gi://GLib';
const Lang = imports.lang; import GObject from 'gi://GObject';
const Gi = imports._gi; import Clutter from 'gi://Clutter';
const GLib = imports.gi.GLib; import Meta from 'gi://Meta';
const Clutter = imports.gi.Clutter; import Shell from 'gi://Shell';
const Meta = imports.gi.Meta; import St from 'gi://St';
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const AppDisplay = imports.ui.appDisplay; import * as BoxPointer from 'resource:///org/gnome/shell/ui/boxpointer.js';
const BoxPointer = imports.ui.boxpointer; import * as LookingGlass from 'resource:///org/gnome/shell/ui/lookingGlass.js';
const Dash = imports.ui.dash; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const IconGrid = imports.ui.iconGrid; import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
const LookingGlass = imports.ui.lookingGlass; import * as Layout from 'resource:///org/gnome/shell/ui/layout.js';
const Main = imports.ui.main; import {InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js';
const PanelMenu = imports.ui.panelMenu; import {SETTINGS} from './extension.js';
const Layout = imports.ui.layout; import {SecondaryMonitorDisplay, WorkspacesView} from 'resource:///org/gnome/shell/ui/workspacesView.js';
const WM = imports.ui.windowManager;
const WorkspacesView = imports.ui.workspacesView;
var dtpPanelManager = Utils.defineClass({
Name: 'ZorinTaskbar.PanelManager',
_init: function() { export const PanelManager = class {
this.overview = new Overview.dtpOverview();
constructor() {
this.overview = new Overview.Overview();
this.panelsElementPositions = {}; this.panelsElementPositions = {};
this._injectionManager = new InjectionManager();
this._saveMonitors(); this._saveMonitors();
}
Utils.getAppDisplayViews().forEach(v => { enable(reset) {
Utils.wrapActor(v.view); this.allPanels = [];
Utils.wrapActor(v.view._grid);
});
},
enable: function(reset) {
this.panelPositions = Pos.getSettingsPositions(Me.settings, 'panel-positions');
this.dtpPrimaryMonitor = Main.layoutManager.primaryMonitor; // The real primary monitor should always have the main panel this.dtpPrimaryMonitor = Main.layoutManager.primaryMonitor; // The real primary monitor should always have the main panel
this.proximityManager = new Proximity.ProximityManager(); this.proximityManager = new Proximity.ProximityManager();
Utils.wrapActor(Main.panel); if (this.dtpPrimaryMonitor) {
Utils.wrapActor(Main.overview.dash || 0); this.primaryPanel = this._createPanel(this.dtpPrimaryMonitor, SETTINGS.get_boolean('stockgs-keep-top-panel'));
this.allPanels.push(this.primaryPanel);
this.overview.enable(this.primaryPanel);
this.primaryPanel = this._createPanel(this.dtpPrimaryMonitor, false); this.setFocusedMonitor(this.dtpPrimaryMonitor);
this.allPanels = [ this.primaryPanel ]; }
this.overview.enable(this.primaryPanel);
if (Me.settings.get_boolean('multi-monitors')) { if (SETTINGS.get_boolean('multi-monitors')) {
Main.layoutManager.monitors.filter(m => m != this.dtpPrimaryMonitor).forEach(m => { Main.layoutManager.monitors.filter(m => m != this.dtpPrimaryMonitor).forEach(m => {
this.allPanels.push(this._createPanel(m, true)); this.allPanels.push(this._createPanel(m, true));
}); });
@@ -106,11 +97,12 @@ var dtpPanelManager = Utils.defineClass({
p.taskbar.iconAnimator.start(); p.taskbar.iconAnimator.start();
}); });
this._setDesktopIconsMargins();
//in 3.32, BoxPointer now inherits St.Widget //in 3.32, BoxPointer now inherits St.Widget
if (BoxPointer.BoxPointer.prototype.vfunc_get_preferred_height) { if (BoxPointer.BoxPointer.prototype.vfunc_get_preferred_height) {
let panelManager = this; let panelManager = this;
Utils.hookVfunc(BoxPointer.BoxPointer.prototype, 'get_preferred_height', function(forWidth) { this._injectionManager.overrideMethod(BoxPointer.BoxPointer.prototype, 'vfunc_get_preferred_height', () => function(forWidth) {
let alloc = { min_size: 0, natural_size: 0 }; let alloc = { min_size: 0, natural_size: 0 };
[alloc.min_size, alloc.natural_size] = this.vfunc_get_preferred_height(forWidth); [alloc.min_size, alloc.natural_size] = this.vfunc_get_preferred_height(forWidth);
@@ -120,23 +112,10 @@ var dtpPanelManager = Utils.defineClass({
} }
this._updatePanelElementPositions(); this._updatePanelElementPositions();
this.setFocusedMonitor(this.dtpPrimaryMonitor);
if (this.primaryPanel.checkIfVertical()) {
Main.wm._getPositionForDirection = newGetPositionForDirection;
}
if (reset) return; if (reset) return;
this._oldViewSelectorAnimateIn = Main.overview.viewSelector._animateIn; this._desktopIconsUsableArea = new DesktopIconsIntegration.DesktopIconsUsableAreaClass();
Main.overview.viewSelector._animateIn = Lang.bind(this.primaryPanel, newViewSelectorAnimateIn);
this._oldViewSelectorAnimateOut = Main.overview.viewSelector._animateOut;
Main.overview.viewSelector._animateOut = Lang.bind(this.primaryPanel, newViewSelectorAnimateOut);
if (Config.PACKAGE_VERSION > '3.35.1') {
this._oldDoSpringAnimation = AppDisplay.BaseAppView.prototype._doSpringAnimation;
AppDisplay.BaseAppView.prototype._doSpringAnimation = newDoSpringAnimation;
}
this._oldUpdatePanelBarrier = Main.layoutManager._updatePanelBarrier; this._oldUpdatePanelBarrier = Main.layoutManager._updatePanelBarrier;
Main.layoutManager._updatePanelBarrier = (panel) => { Main.layoutManager._updatePanelBarrier = (panel) => {
@@ -147,32 +126,18 @@ var dtpPanelManager = Utils.defineClass({
Main.layoutManager._updatePanelBarrier(); Main.layoutManager._updatePanelBarrier();
this._oldUpdateHotCorners = Main.layoutManager._updateHotCorners; this._oldUpdateHotCorners = Main.layoutManager._updateHotCorners;
Main.layoutManager._updateHotCorners = Lang.bind(Main.layoutManager, newUpdateHotCorners); Main.layoutManager._updateHotCorners = newUpdateHotCorners.bind(Main.layoutManager);
Main.layoutManager._updateHotCorners(); Main.layoutManager._updateHotCorners();
if (Main.layoutManager._interfaceSettings) { if (Main.layoutManager._interfaceSettings) {
this._enableHotCornersId = Main.layoutManager._interfaceSettings.connect('changed::enable-hot-corners', () => Main.layoutManager._updateHotCorners()); this._enableHotCornersId = Main.layoutManager._interfaceSettings.connect('changed::enable-hot-corners', () => Main.layoutManager._updateHotCorners());
} }
this._oldOverviewRelayout = Main.overview._relayout; this._oldUpdateWorkspacesViews = Main.overview._overview._controls._workspacesDisplay._updateWorkspacesViews;
Main.overview._relayout = Lang.bind(Main.overview, this._newOverviewRelayout); Main.overview._overview._controls._workspacesDisplay._updateWorkspacesViews = this._newUpdateWorkspacesViews.bind(Main.overview._overview._controls._workspacesDisplay);
this._oldUpdateWorkspacesViews = Main.overview.viewSelector._workspacesDisplay._updateWorkspacesViews; this._oldSetPrimaryWorkspaceVisible = Main.overview._overview._controls._workspacesDisplay.setPrimaryWorkspaceVisible
Main.overview.viewSelector._workspacesDisplay._updateWorkspacesViews = Lang.bind(Main.overview.viewSelector._workspacesDisplay, this._newUpdateWorkspacesViews); Main.overview._overview._controls._workspacesDisplay.setPrimaryWorkspaceVisible = this._newSetPrimaryWorkspaceVisible.bind(Main.overview._overview._controls._workspacesDisplay);
this._oldGetShowAppsButton = Main.overview.getShowAppsButton;
Main.overview.getShowAppsButton = this._newGetShowAppsButton.bind(this);
this._needsDashItemContainerAllocate = !Dash.DashItemContainer.prototype.hasOwnProperty('vfunc_allocate');
if (this._needsDashItemContainerAllocate) {
Utils.hookVfunc(Dash.DashItemContainer.prototype, 'allocate', this._newDashItemContainerAllocate);
}
// Since Gnome 3.8 dragging an app without having opened the overview before cause the attemp to
//animate a null target since some variables are not initialized when the viewSelector is created
if(Main.overview.viewSelector._activePage == null)
Main.overview.viewSelector._activePage = Main.overview.viewSelector._workspacesPage;
LookingGlass.LookingGlass.prototype._oldResize = LookingGlass.LookingGlass.prototype._resize; LookingGlass.LookingGlass.prototype._oldResize = LookingGlass.LookingGlass.prototype._resize;
LookingGlass.LookingGlass.prototype._resize = _newLookingGlassResize; LookingGlass.LookingGlass.prototype._resize = _newLookingGlassResize;
@@ -182,74 +147,40 @@ var dtpPanelManager = Utils.defineClass({
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler();
if (Config.PACKAGE_VERSION > '3.35.9') {
let currentAppsView;
this._oldAnimateIconPosition = IconGrid.animateIconPosition;
IconGrid.animateIconPosition = newAnimateIconPosition.bind(this);
this._signalsHandler.add(
[
Utils.DisplayWrapper.getScreen(),
'window-entered-monitor',
() => this._needsIconAllocate = 1
]
);
Utils.getAppDisplayViews().forEach(v => {
if (!v.control || v.control.has_style_pseudo_class('checked')) {
currentAppsView = v;
}
if (v.control) {
this._signalsHandler.add(
[
v.control,
'clicked',
() => {
this._needsIconAllocate = currentAppsView != v;
currentAppsView = v;
}
]
);
}
this._signalsHandler.add(
[
v.view,
'notify::visible',
() => this._needsIconAllocate = !(currentAppsView != v && !v.view.visible)
],
[
v.view._grid,
'animation-done',
() => this._needsIconAllocate = 0
]
);
});
}
//listen settings //listen settings
this._signalsHandler.add( this._signalsHandler.add(
[ [
Me.settings, SETTINGS,
[ [
'changed::multi-monitors', 'changed::multi-monitors',
'changed::isolate-monitors', 'changed::isolate-monitors',
'changed::panel-positions' 'changed::panel-positions',
'changed::panel-lengths',
'changed::panel-anchors',
'changed::stockgs-keep-top-panel'
], ],
() => this._reset() () => this._reset()
], ],
[ [
Me.settings, SETTINGS,
'changed::panel-element-positions', 'changed::panel-element-positions',
() => this._updatePanelElementPositions() () => this._updatePanelElementPositions()
], ],
[ [
Me.settings, SETTINGS,
'changed::intellihide-key-toggle-text', 'changed::intellihide-key-toggle-text',
() => this._setKeyBindings(true) () => this._setKeyBindings(true)
], ],
[
SETTINGS,
'changed::panel-sizes',
() => {
GLib.idle_add(GLib.PRIORITY_LOW, () => {
this._setDesktopIconsMargins();
return GLib.SOURCE_REMOVE;
});
}
],
[ [
Utils.DisplayWrapper.getMonitorManager(), Utils.DisplayWrapper.getMonitorManager(),
'monitors-changed', 'monitors-changed',
@@ -263,19 +194,31 @@ var dtpPanelManager = Utils.defineClass({
); );
Panel.panelBoxes.forEach(c => this._signalsHandler.add( Panel.panelBoxes.forEach(c => this._signalsHandler.add(
[Main.panel[c], 'actor-added', (parent, child) => this._adjustPanelMenuButton(this._getPanelMenuButton(child), this.primaryPanel.monitor, this.primaryPanel.getPosition())] [
Main.panel[c],
'child-added',
(parent, child) => {
this.primaryPanel &&
child instanceof St.Bin &&
this._adjustPanelMenuButton(this._getPanelMenuButton(child.get_first_child()), this.primaryPanel.monitor, this.primaryPanel.getPosition())
}
]
)); ));
this._setKeyBindings(true); this._setKeyBindings(true);
},
disable: function(reset) { // keep GS overview.js from blowing away custom panel styles
this.overview.disable(); if(!SETTINGS.get_boolean('stockgs-keep-top-panel'))
Object.defineProperty(Main.panel, "style", {configurable: true, set(v) {}});
}
disable(reset) {
this.primaryPanel && this.overview.disable();
this.proximityManager.destroy(); this.proximityManager.destroy();
this.allPanels.forEach(p => { this.allPanels.forEach(p => {
p.taskbar.iconAnimator.pause(); p.taskbar.iconAnimator.pause();
this._findPanelMenuButtons(p.panelBox).forEach(pmb => { this._findPanelMenuButtons(p.panelBox).forEach(pmb => {
if (pmb.menu._boxPointer._dtpGetPreferredHeightId) { if (pmb.menu._boxPointer._dtpGetPreferredHeightId) {
pmb.menu._boxPointer._container.disconnect(pmb.menu._boxPointer._dtpGetPreferredHeightId); pmb.menu._boxPointer._container.disconnect(pmb.menu._boxPointer._dtpGetPreferredHeightId);
@@ -299,8 +242,8 @@ var dtpPanelManager = Utils.defineClass({
p.panelBox.destroy(); p.panelBox.destroy();
} else { } else {
p.panelBox.remove_child(p); p.panelBox.remove_child(p);
p.remove_child(p.panel.actor); p.remove_child(p.panel);
p.panelBox.add(p.panel.actor); p.panelBox.add_child(p.panel);
p.panelBox.set_position(clipContainer.x, clipContainer.y); p.panelBox.set_position(clipContainer.x, clipContainer.y);
@@ -309,11 +252,7 @@ var dtpPanelManager = Utils.defineClass({
} }
}); });
if (BoxPointer.BoxPointer.prototype.vfunc_get_preferred_height) { this._injectionManager.clear();
Utils.hookVfunc(BoxPointer.BoxPointer.prototype, 'get_preferred_height', BoxPointer.BoxPointer.prototype.vfunc_get_preferred_height);
}
delete Main.wm._getPositionForDirection;
if (Main.layoutManager.primaryMonitor) { if (Main.layoutManager.primaryMonitor) {
Main.layoutManager.panelBox.set_position(Main.layoutManager.primaryMonitor.x, Main.layoutManager.primaryMonitor.y); Main.layoutManager.panelBox.set_position(Main.layoutManager.primaryMonitor.x, Main.layoutManager.primaryMonitor.y);
@@ -336,67 +275,119 @@ var dtpPanelManager = Utils.defineClass({
Main.layoutManager._updatePanelBarrier = this._oldUpdatePanelBarrier; Main.layoutManager._updatePanelBarrier = this._oldUpdatePanelBarrier;
Main.layoutManager._updatePanelBarrier(); Main.layoutManager._updatePanelBarrier();
Main.overview.viewSelector._animateIn = this._oldViewSelectorAnimateIn; Main.overview._overview._controls._workspacesDisplay._updateWorkspacesViews = this._oldUpdateWorkspacesViews;
Main.overview.viewSelector._animateOut = this._oldViewSelectorAnimateOut; Main.overview._overview._controls._workspacesDisplay.setPrimaryWorkspaceVisible = this._oldSetPrimaryWorkspaceVisible;
Main.overview._relayout = this._oldOverviewRelayout;
Main.overview._relayout();
Main.overview.viewSelector._workspacesDisplay._updateWorkspacesViews = this._oldUpdateWorkspacesViews;
Utils.getPanelGhost().set_size(-1, -1);
if (this._needsDashItemContainerAllocate) {
Utils.hookVfunc(Dash.DashItemContainer.prototype, 'allocate', function(box, flags) { this.vfunc_allocate(box, flags); });
}
if (this._oldDoSpringAnimation) {
AppDisplay.BaseAppView.prototype._doSpringAnimation = this._oldDoSpringAnimation;
}
if (this._oldAnimateIconPosition) {
IconGrid.animateIconPosition = this._oldAnimateIconPosition;
}
LookingGlass.LookingGlass.prototype._resize = LookingGlass.LookingGlass.prototype._oldResize; LookingGlass.LookingGlass.prototype._resize = LookingGlass.LookingGlass.prototype._oldResize;
delete LookingGlass.LookingGlass.prototype._oldResize; delete LookingGlass.LookingGlass.prototype._oldResize;
LookingGlass.LookingGlass.prototype.open = LookingGlass.LookingGlass.prototype._oldOpen; LookingGlass.LookingGlass.prototype.open = LookingGlass.LookingGlass.prototype._oldOpen;
delete LookingGlass.LookingGlass.prototype._oldOpen delete LookingGlass.LookingGlass.prototype._oldOpen
},
setFocusedMonitor: function(monitor, ignoreRelayout) { delete Main.panel.style;
this._needsIconAllocate = 1; this._desktopIconsUsableArea.destroy();
this._desktopIconsUsableArea = null;
}
toggleDash() {
this.overview.toggleDash();
}
_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) {
this.focusedMonitorPanel = this.allPanels.find(p => p.monitor == monitor)
if (!this.checkIfFocusedMonitor(monitor)) { if (!this.checkIfFocusedMonitor(monitor)) {
Main.overview.viewSelector._workspacesDisplay._primaryIndex = monitor.index;
Main.overview._overview.clear_constraints(); Main.overview._overview.clear_constraints();
Main.overview._overview.add_constraint(new Layout.MonitorConstraint({ index: monitor.index })); Main.overview._overview.add_constraint(new Layout.MonitorConstraint({ index: monitor.index }));
if (ignoreRelayout) return;
this._newOverviewRelayout.call(Main.overview); Main.overview._overview._controls._workspacesDisplay._primaryIndex = monitor.index;
} }
}, }
_saveMonitors: function() { _newSetPrimaryWorkspaceVisible(visible) {
if (this._primaryVisible === visible)
return;
this._primaryVisible = visible;
const primaryIndex = Main.overview._overview._controls._workspacesDisplay._primaryIndex;
const primaryWorkspace = this._workspacesViews[primaryIndex];
if (primaryWorkspace)
primaryWorkspace.visible = visible;
}
_newUpdateWorkspacesViews() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].destroy();
this._workspacesViews = [];
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {
let view;
if (i === this._primaryIndex) {
view = new WorkspacesView(i,
this._controls,
this._scrollAdjustment,
this._fitModeAdjustment,
this._overviewAdjustment);
view.visible = this._primaryVisible;
this.bind_property('opacity', view, 'opacity', GObject.BindingFlags.SYNC_CREATE);
this.add_child(view);
} else {
// No idea why atm, but we need the import at the top of this file and to use the
// full imports ns here, otherwise SecondaryMonitorDisplay can't be used ¯\_(ツ)_/¯
view = new SecondaryMonitorDisplay(i,
this._controls,
this._scrollAdjustment,
this._fitModeAdjustment,
this._overviewAdjustment);
Main.layoutManager.overviewGroup.add_child(view);
}
this._workspacesViews.push(view);
}
}
_saveMonitors() {
//Mutter meta_monitor_manager_get_primary_monitor (global.display.get_primary_monitor()) doesn't return the same //Mutter meta_monitor_manager_get_primary_monitor (global.display.get_primary_monitor()) doesn't return the same
//monitor as GDK gdk_screen_get_primary_monitor (imports.gi.Gdk.Screen.get_default().get_primary_monitor()). //monitor as GDK gdk_screen_get_primary_monitor (imports.gi.Gdk.Screen.get_default().get_primary_monitor()).
//Since the Mutter function is what's used in gnome-shell and we can't access it from the settings dialog, store //Since the Mutter function is what's used in gnome-shell and we can't access it from the settings dialog, store
//the monitors information in a setting so we can use the same monitor indexes as the ones in gnome-shell //the monitors information in a setting so we can use the same monitor indexes as the ones in gnome-shell
let keyMonitors = 'available-monitors';
let primaryIndex = Main.layoutManager.primaryIndex; let primaryIndex = Main.layoutManager.primaryIndex;
let monitors = [primaryIndex]; let newMonitors = [primaryIndex];
Main.layoutManager.monitors.filter(m => m.index != primaryIndex).forEach(m => monitors.push(m.index)); Main.layoutManager.monitors.filter(m => m.index != primaryIndex).forEach(m => newMonitors.push(m.index));
Me.settings.set_value('available-monitors', new GLib.Variant('ai', monitors));
}, SETTINGS.set_value(keyMonitors, new GLib.Variant('ai', newMonitors));
}
checkIfFocusedMonitor: function(monitor) { checkIfFocusedMonitor(monitor) {
return Main.overview.viewSelector._workspacesDisplay._primaryIndex == monitor.index; return Main.overview._overview._controls._workspacesDisplay._primaryIndex == monitor.index;
}, }
_createPanel: function(monitor, isStandalone) { _createPanel(monitor, isStandalone) {
let panelBox; let panelBox;
let panel; let panel;
let clipContainer = new Clutter.Actor(); let clipContainer = new Clutter.Actor();
@@ -406,7 +397,7 @@ var dtpPanelManager = Utils.defineClass({
} else { } else {
panelBox = Main.layoutManager.panelBox; panelBox = Main.layoutManager.panelBox;
Main.layoutManager._untrackActor(panelBox); Main.layoutManager._untrackActor(panelBox);
panelBox.remove_child(Main.panel.actor); panelBox.remove_child(Main.panel);
Main.layoutManager.removeChrome(panelBox); Main.layoutManager.removeChrome(panelBox);
} }
@@ -414,8 +405,8 @@ var dtpPanelManager = Utils.defineClass({
clipContainer.add_child(panelBox); clipContainer.add_child(panelBox);
Main.layoutManager.trackChrome(panelBox, { trackFullscreen: true, affectsStruts: true, affectsInputRegion: true }); Main.layoutManager.trackChrome(panelBox, { trackFullscreen: true, affectsStruts: true, affectsInputRegion: true });
panel = new Panel.dtpPanel(this, monitor, panelBox, isStandalone); panel = new Panel.Panel(this, monitor, panelBox, isStandalone);
panelBox.add(panel); panelBox.add_child(panel);
panel.enable(); panel.enable();
panelBox.visible = true; panelBox.visible = true;
@@ -425,24 +416,23 @@ var dtpPanelManager = Utils.defineClass({
panelBox.set_position(0, 0); panelBox.set_position(0, 0);
return panel; return panel;
}, }
_reset: function() { _reset() {
this.disable(true); this.disable(true);
this.allPanels = []; this.allPanels = [];
this.enable(true); this.enable(true);
}, }
_updatePanelElementPositions: function() { _updatePanelElementPositions() {
this.panelsElementPositions = Pos.getSettingsPositions(Me.settings, 'panel-element-positions'); this.panelsElementPositions = PanelSettings.getSettingsJson(SETTINGS, 'panel-element-positions');
this.allPanels.forEach(p => p.updateElementPositions()); this.allPanels.forEach(p => p.updateElementPositions());
}, }
_adjustPanelMenuButton: function(button, monitor, arrowSide) { _adjustPanelMenuButton(button, monitor, arrowSide) {
if (button) { if (button) {
Utils.wrapActor(button);
button.menu._boxPointer._dtpSourceActor = button.menu._boxPointer.sourceActor; button.menu._boxPointer._dtpSourceActor = button.menu._boxPointer.sourceActor;
button.menu._boxPointer.sourceActor = button.actor; button.menu._boxPointer.sourceActor = button;
button.menu._boxPointer._userArrowSide = arrowSide; button.menu._boxPointer._userArrowSide = arrowSide;
button.menu._boxPointer._dtpInPanel = 1; button.menu._boxPointer._dtpInPanel = 1;
@@ -452,10 +442,10 @@ var dtpPanelManager = Utils.defineClass({
}); });
} }
} }
}, }
_getBoxPointerPreferredHeight: function(boxPointer, alloc, monitor) { _getBoxPointerPreferredHeight(boxPointer, alloc, monitor) {
if (boxPointer._dtpInPanel && boxPointer.sourceActor && Me.settings.get_boolean('intellihide')) { if (boxPointer._dtpInPanel && boxPointer.sourceActor && SETTINGS.get_boolean('intellihide')) {
monitor = monitor || Main.layoutManager.findMonitorForActor(boxPointer.sourceActor); monitor = monitor || Main.layoutManager.findMonitorForActor(boxPointer.sourceActor);
let panel = Utils.find(global.zorinTaskbar.panels, p => p.monitor == monitor); let panel = Utils.find(global.zorinTaskbar.panels, p => p.monitor == monitor);
let excess = alloc.natural_size + panel.dtpSize + 10 - monitor.height; // 10 is arbitrary let excess = alloc.natural_size + panel.dtpSize + 10 - monitor.height; // 10 is arbitrary
@@ -466,9 +456,9 @@ var dtpPanelManager = Utils.defineClass({
} }
return [alloc.min_size, alloc.natural_size]; return [alloc.min_size, alloc.natural_size];
}, }
_findPanelMenuButtons: function(container) { _findPanelMenuButtons(container) {
let panelMenuButtons = []; let panelMenuButtons = [];
let panelMenuButton; let panelMenuButton;
@@ -483,9 +473,9 @@ var dtpPanelManager = Utils.defineClass({
find(container); find(container);
return panelMenuButtons; return panelMenuButtons;
}, }
_removePanelBarriers: function(panel) { _removePanelBarriers(panel) {
if (panel.isStandalone && panel._rightPanelBarrier) { if (panel.isStandalone && panel._rightPanelBarrier) {
panel._rightPanelBarrier.destroy(); panel._rightPanelBarrier.destroy();
} }
@@ -494,13 +484,13 @@ var dtpPanelManager = Utils.defineClass({
panel._leftPanelBarrier.destroy(); panel._leftPanelBarrier.destroy();
delete panel._leftPanelBarrier; delete panel._leftPanelBarrier;
} }
}, }
_getPanelMenuButton: function(obj) { _getPanelMenuButton(obj) {
return obj._delegate && obj._delegate instanceof PanelMenu.Button ? obj._delegate : 0; return obj instanceof PanelMenu.Button && obj.menu?._boxPointer ? obj : 0;
}, }
_setKeyBindings: function(enable) { _setKeyBindings(enable) {
let keys = { let keys = {
'intellihide-key-toggle': () => this.allPanels.forEach(p => p.intellihide.toggle()) 'intellihide-key-toggle': () => this.allPanels.forEach(p => p.intellihide.toggle())
}; };
@@ -509,107 +499,18 @@ var dtpPanelManager = Utils.defineClass({
Utils.removeKeybinding(k); Utils.removeKeybinding(k);
if (enable) { if (enable) {
Utils.addKeybinding(k, Me.settings, keys[k], Shell.ActionMode.NORMAL); Utils.addKeybinding(k, SETTINGS, keys[k], Shell.ActionMode.NORMAL);
} }
}); });
}, }
_newOverviewRelayout: function() { };
// To avoid updating the position and size of the workspaces
// we just hide the overview. The positions will be updated
// when it is next shown.
this.hide();
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.overview.viewSelector._workspacesDisplay._primaryIndex);
this._coverPane.set_position(0, workArea.y);
this._coverPane.set_size(workArea.width, workArea.height);
this._updateBackgrounds();
},
_newUpdateWorkspacesViews: function() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].destroy();
this._workspacesViews = [];
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {
let workspaces;
let view;
if (this._workspacesOnlyOnPrimary && i != Main.layoutManager.primaryIndex) {
view = new WorkspacesView.ExtraWorkspaceView(i);
view.getActiveWorkspace = view.getActiveWorkspace || function() { return this._workspace; };
workspaces = [view._workspace];
} else {
view = new WorkspacesView.WorkspacesView(i, this._scrollAdjustment || 0);
workspaces = view._workspaces;
}
Utils.wrapActor(view);
view.actor.connect('scroll-event', this._onScrollEvent.bind(this));
if (i == Main.layoutManager.primaryIndex && view.scrollAdjustment) {
this._scrollAdjustment = view.scrollAdjustment;
this._scrollAdjustment.connect('notify::value',
this._scrollValueChanged.bind(this));
}
workspaces.forEach(w => w.setFullGeometry = geom => w._fullGeometry = geom);
this._workspacesViews.push(view);
}
this._workspacesViews.forEach(wv => Main.layoutManager.overviewGroup.add_actor(wv.actor));
if (this._syncWorkspacesFullGeometry) {
//gnome-shell 3.36.4
if (this._fullGeometry)
this._syncWorkspacesFullGeometry();
if (this._actualGeometry)
this._syncWorkspacesActualGeometry();
} else if (this._updateWorkspacesFullGeometry) {
this._updateWorkspacesFullGeometry();
this._updateWorkspacesActualGeometry();
}
},
_newGetShowAppsButton: function() {
let focusedMonitorIndex = Utils.findIndex(this.allPanels, p => this.checkIfFocusedMonitor(p.monitor));
return this.allPanels[focusedMonitorIndex].taskbar.showAppsButton;
},
_newDashItemContainerAllocate: function(box, flags) {
if (this.child == null)
return;
Utils.setAllocation(this, box, flags);
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let [minChildWidth, minChildHeight, natChildWidth, natChildHeight] = this.child.get_preferred_size();
let [childScaleX, childScaleY] = this.child.get_scale();
let childWidth = Math.min(natChildWidth * childScaleX, availWidth);
let childHeight = Math.min(natChildHeight * childScaleY, availHeight);
let childBox = new Clutter.ActorBox();
childBox.x1 = (availWidth - childWidth) / 2;
childBox.y1 = (availHeight - childHeight) / 2;
childBox.x2 = childBox.x1 + childWidth;
childBox.y2 = childBox.y1 + childHeight;
Utils.allocate(this.child, childBox, flags);
},
});
// This class drives long-running icon animations, to keep them running in sync // This class drives long-running icon animations, to keep them running in sync
// with each other. // with each other.
var IconAnimator = Utils.defineClass({ export const IconAnimator = class {
Name: 'ZorinTaskbar.IconAnimator',
_init: function(actor) { constructor(actor) {
this._count = 0; this._count = 0;
this._started = false; this._started = false;
this._animations = { this._animations = {
@@ -632,12 +533,12 @@ var IconAnimator = Utils.defineClass({
dancers[i].target.rotation_angle_z = danceRotation; dancers[i].target.rotation_angle_z = danceRotation;
} }
}); });
}, }
destroy: function() { destroy() {
this._timeline.stop(); this._timeline.stop();
this._timeline = null; this._timeline = null;
for (const name in this._animations) { for (let name in this._animations) {
const pairs = this._animations[name]; const pairs = this._animations[name];
for (let i = 0, iMax = pairs.length; i < iMax; i++) { for (let i = 0, iMax = pairs.length; i < iMax; i++) {
const pair = pairs[i]; const pair = pairs[i];
@@ -645,32 +546,32 @@ var IconAnimator = Utils.defineClass({
} }
} }
this._animations = null; this._animations = null;
}, }
pause: function() { pause() {
if (this._started && this._count > 0) { if (this._started && this._count > 0) {
this._timeline.stop(); this._timeline.stop();
} }
this._started = false; this._started = false;
}, }
start: function() { start() {
if (!this._started && this._count > 0) { if (!this._started && this._count > 0) {
this._timeline.start(); this._timeline.start();
} }
this._started = true; this._started = true;
}, }
addAnimation: function(target, name) { addAnimation(target, name) {
const targetDestroyId = target.connect('destroy', () => this.removeAnimation(target, name)); const targetDestroyId = target.connect('destroy', () => this.removeAnimation(target, name));
this._animations[name].push({ target, targetDestroyId }); this._animations[name].push({ target: target, targetDestroyId: targetDestroyId });
if (this._started && this._count === 0) { if (this._started && this._count === 0) {
this._timeline.start(); this._timeline.start();
} }
this._count++; this._count++;
}, }
removeAnimation: function(target, name) { removeAnimation(target, name) {
const pairs = this._animations[name]; const pairs = this._animations[name];
for (let i = 0, iMax = pairs.length; i < iMax; i++) { for (let i = 0, iMax = pairs.length; i < iMax; i++) {
const pair = pairs[i]; const pair = pairs[i];
@@ -685,77 +586,7 @@ var IconAnimator = Utils.defineClass({
} }
} }
} }
}); };
function newViewSelectorAnimateIn(oldPage) {
if (oldPage)
oldPage.hide();
let vs = Main.overview.viewSelector;
vs.emit('page-empty');
vs._activePage.show();
if (vs._activePage == vs._appsPage && oldPage == vs._workspacesPage) {
// Restore opacity, in case we animated via _fadePageOut
vs._activePage.opacity = 255;
let animate = Me.settings.get_boolean('animate-show-apps');
if(animate)
vs.appDisplay.animate(IconGrid.AnimationDirection.IN);
} else {
vs._fadePageIn();
}
}
function newViewSelectorAnimateOut(page) {
let oldPage = page;
let vs = Main.overview.viewSelector;
if (page == vs._appsPage &&
vs._activePage == vs._workspacesPage &&
!Main.overview.animationInProgress) {
let animate = Me.settings.get_boolean('animate-show-apps');
if(animate)
vs.appDisplay.animate(IconGrid.AnimationDirection.OUT, Lang.bind(this,
function() {
vs._animateIn(oldPage)
}));
else
vs._animateIn(oldPage)
} else {
vs._fadePageOut(page);
}
}
function newGetPositionForDirection(direction, fromWs, toWs) {
let [xDest, yDest] = WM.WindowManager.prototype._getPositionForDirection(direction, fromWs, toWs);
if (direction == Meta.MotionDirection.UP ||
direction == Meta.MotionDirection.UP_LEFT ||
direction == Meta.MotionDirection.UP_RIGHT) {
yDest -= Main.panel.height;
} else if (direction != Meta.MotionDirection.LEFT &&
direction != Meta.MotionDirection.RIGHT) {
yDest += Main.panel.height;
}
return [xDest, yDest];
}
function newDoSpringAnimation(animationDirection) {
this._grid.opacity = 255;
this._grid.animateSpring(animationDirection, Main.overview.getShowAppsButton());
}
function newAnimateIconPosition(icon, box, flags, nChangedIcons) {
if (this._needsIconAllocate) {
Utils.allocate(icon, box, flags);
return;
}
return this._oldAnimateIconPosition(icon, box, flags, nChangedIcons);;
}
function newUpdateHotCorners() { function newUpdateHotCorners() {
// destroy old hot corners // destroy old hot corners
@@ -820,7 +651,7 @@ function newUpdateHotCorners() {
if (haveTopLeftCorner) { if (haveTopLeftCorner) {
let corner = new Layout.HotCorner(this, monitor, cornerX, cornerY); let corner = new Layout.HotCorner(this, monitor, cornerX, cornerY);
corner.setBarrierSize = size => corner.__proto__.setBarrierSize.call(corner, Math.min(size, 32)); corner.setBarrierSize = size => Object.getPrototypeOf(corner).setBarrierSize.call(corner, Math.min(size, 32));
corner.setBarrierSize(panel ? panel.dtpSize : 32); corner.setBarrierSize(panel ? panel.dtpSize : 32);
this.hotCorners.push(corner); this.hotCorners.push(corner);
} else { } else {
@@ -855,8 +686,8 @@ function newUpdatePanelBarrier(panel) {
let fixed2 = panel.monitor.y + barrierSize; let fixed2 = panel.monitor.y + barrierSize;
if (panel.checkIfVertical()) { if (panel.checkIfVertical()) {
barriers._rightPanelBarrier.push(panel.monitor.y + panel.monitor.height, Meta.BarrierDirection.POSITIVE_Y); barriers._rightPanelBarrier.push(panel.monitor.y + panel.monitor.height, Meta.BarrierDirection.NEGATIVE_Y);
barriers._leftPanelBarrier.push(panel.monitor.y, Meta.BarrierDirection.NEGATIVE_Y); barriers._leftPanelBarrier.push(panel.monitor.y, Meta.BarrierDirection.POSITIVE_Y);
} else { } else {
barriers._rightPanelBarrier.push(panel.monitor.x + panel.monitor.width, Meta.BarrierDirection.NEGATIVE_X); barriers._rightPanelBarrier.push(panel.monitor.x + panel.monitor.width, Meta.BarrierDirection.NEGATIVE_X);
barriers._leftPanelBarrier.push(panel.monitor.x, Meta.BarrierDirection.POSITIVE_X); barriers._leftPanelBarrier.push(panel.monitor.x, Meta.BarrierDirection.POSITIVE_X);
@@ -869,12 +700,12 @@ function newUpdatePanelBarrier(panel) {
fixed2 = panel.monitor.y + panel.monitor.height; fixed2 = panel.monitor.y + panel.monitor.height;
break; break;
case St.Side.LEFT: case St.Side.LEFT:
fixed1 = panel.monitor.x; fixed1 = panel.monitor.x + barrierSize;
fixed2 = panel.monitor.x + barrierSize; fixed2 = panel.monitor.x;
break; break;
case St.Side.RIGHT: case St.Side.RIGHT:
fixed1 = panel.monitor.x + panel.monitor.width; fixed1 = panel.monitor.x + panel.monitor.width - barrierSize;
fixed2 = panel.monitor.x + panel.monitor.width - barrierSize; fixed2 = panel.monitor.x + panel.monitor.width;
break; break;
} }
@@ -891,7 +722,7 @@ function newUpdatePanelBarrier(panel) {
Object.keys(barriers).forEach(k => { Object.keys(barriers).forEach(k => {
let barrierOptions = { let barrierOptions = {
display: global.display, backend: global.backend,
directions: barriers[k][2] directions: barriers[k][2]
}; };
@@ -908,14 +739,12 @@ function _newLookingGlassResize() {
let topOffset = primaryMonitorPanel.getPosition() == St.Side.TOP ? primaryMonitorPanel.dtpSize + 8 : 32; let topOffset = primaryMonitorPanel.getPosition() == St.Side.TOP ? primaryMonitorPanel.dtpSize + 8 : 32;
this._oldResize(); this._oldResize();
Utils.wrapActor(this);
Utils.wrapActor(this._objInspector);
this._hiddenY = Main.layoutManager.primaryMonitor.y + topOffset - this.actor.height; this._hiddenY = Main.layoutManager.primaryMonitor.y + topOffset - this.height;
this._targetY = this._hiddenY + this.actor.height; this._targetY = this._hiddenY + this.height;
this.actor.y = this._hiddenY; this.y = this._hiddenY;
this._objInspector.actor.set_position(this.actor.x + Math.floor(this.actor.width * 0.1), this._targetY + Math.floor(this.actor.height * 0.1)); this._objInspector.set_position(this.x + Math.floor(this.width * 0.1), this._targetY + Math.floor(this.height * 0.1));
} }
function _newLookingGlassOpen() { function _newLookingGlassOpen() {

View File

@@ -18,27 +18,31 @@
* This file is based on code from the Dash to Panel extension * This file is based on code from the Dash to Panel extension
*/ */
var SHOW_APPS_BTN = 'showAppsButton'; export const SHOW_APPS_BTN = 'showAppsButton';
var ACTIVITIES_BTN = 'activitiesButton'; export const ACTIVITIES_BTN = 'activitiesButton';
var TASKBAR = 'taskbar'; export const TASKBAR = 'taskbar';
var DATE_MENU = 'dateMenu'; export const DATE_MENU = 'dateMenu';
var SYSTEM_MENU = 'systemMenu'; export const SYSTEM_MENU = 'systemMenu';
var LEFT_BOX = 'leftBox'; export const LEFT_BOX = 'leftBox';
var CENTER_BOX = 'centerBox'; export const CENTER_BOX = 'centerBox';
var RIGHT_BOX = 'rightBox'; export const RIGHT_BOX = 'rightBox';
var DESKTOP_BTN = 'desktopButton'; export const DESKTOP_BTN = 'desktopButton';
var STACKED_TL = 'stackedTL'; export const STACKED_TL = 'stackedTL';
var STACKED_BR = 'stackedBR'; export const STACKED_BR = 'stackedBR';
var CENTERED = 'centered'; export const CENTERED = 'centered';
var CENTERED_MONITOR = 'centerMonitor'; export const CENTERED_MONITOR = 'centerMonitor';
var TOP = 'TOP'; export const TOP = 'TOP';
var BOTTOM = 'BOTTOM'; export const BOTTOM = 'BOTTOM';
var LEFT = 'LEFT'; export const LEFT = 'LEFT';
var RIGHT = 'RIGHT'; export const RIGHT = 'RIGHT';
var defaults = [ export const START = 'START';
export const MIDDLE = 'MIDDLE';
export const END = 'END';
export const defaults = [
{ element: LEFT_BOX, visible: true, position: STACKED_TL }, { element: LEFT_BOX, visible: true, position: STACKED_TL },
{ element: SHOW_APPS_BTN, visible: false, position: STACKED_TL }, { element: SHOW_APPS_BTN, visible: false, position: STACKED_TL },
{ element: ACTIVITIES_BTN, visible: true, position: STACKED_TL }, { element: ACTIVITIES_BTN, visible: true, position: STACKED_TL },
@@ -50,24 +54,11 @@ var defaults = [
{ element: DESKTOP_BTN, visible: false, position: STACKED_BR }, { element: DESKTOP_BTN, visible: false, position: STACKED_BR },
]; ];
var optionDialogFunctions = {}; export const optionDialogFunctions = {};
optionDialogFunctions[SHOW_APPS_BTN] = '_showShowAppsButtonOptions';
optionDialogFunctions[DATE_MENU] = '_showDateMenuOptions'; optionDialogFunctions[DATE_MENU] = '_showDateMenuOptions';
optionDialogFunctions[DESKTOP_BTN] = '_showDesktopButtonOptions'; optionDialogFunctions[DESKTOP_BTN] = '_showDesktopButtonOptions';
function getSettingsPositions(settings, setting) { export function checkIfCentered(position) {
var positions = null;
try {
positions = JSON.parse(settings.get_string(setting));
} catch(e) {
log('Error parsing positions: ' + e.message);
}
return positions;
}
function checkIfCentered(position) {
return position == CENTERED || position == CENTERED_MONITOR; return position == CENTERED || position == CENTERED_MONITOR;
} }

111
panelSettings.js Normal file
View File

@@ -0,0 +1,111 @@
/*
* This file is part of the Zorin Taskbar extension for Zorin OS.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
import * as Pos from './panelPositions.js';
/** Return object representing a settings value that is stored as JSON. */
export function getSettingsJson(settings, setting) {
try {
return JSON.parse(settings.get_string(setting));
} catch(e) {
log('Error parsing positions: ' + e.message);
}
}
/** Write value object as JSON to setting in settings. */
export function setSettingsJson(settings, setting, value) {
try {
const json = JSON.stringify(value);
settings.set_string(setting, json);
} catch(e) {
log('Error serializing setting: ' + e.message);
}
}
/** Returns size of panel on a specific monitor, in pixels. */
export function getPanelSize(settings, monitorIndex) {
const sizes = getSettingsJson(settings, 'panel-sizes');
// Pull in deprecated setting if panel-sizes does not have setting for monitor.
const fallbackSize = settings.get_int('panel-size');
const theDefault = 48;
return sizes[monitorIndex] || fallbackSize || theDefault;
}
export function setPanelSize(settings, monitorIndex, value) {
if (!(Number.isInteger(value) && value <= 128 && value >= 16)) {
log('Not setting invalid panel size: ' + value);
return;
}
let sizes = getSettingsJson(settings, 'panel-sizes');
sizes[monitorIndex] = value;
setSettingsJson(settings, 'panel-sizes', sizes);
}
/**
* Returns length of panel on a specific monitor, as a whole number percent,
* from settings. e.g. 100
*/
export function getPanelLength(settings, monitorIndex) {
const lengths = getSettingsJson(settings, 'panel-lengths');
const theDefault = 100;
return lengths[monitorIndex] || theDefault;
}
export function setPanelLength(settings, monitorIndex, value) {
if (!(Number.isInteger(value) && value <= 100 && value >= 0)) {
log('Not setting invalid panel length: ' + value);
return;
}
let lengths = getSettingsJson(settings, 'panel-lengths');
lengths[monitorIndex] = value;
setSettingsJson(settings, 'panel-lengths', lengths);
}
/** Returns position of panel on a specific monitor. */
export function getPanelPosition(settings, monitorIndex) {
const positions = getSettingsJson(settings, 'panel-positions');
const fallbackPosition = settings.get_string('panel-position');
const theDefault = Pos.BOTTOM;
return positions[monitorIndex] || fallbackPosition || theDefault;
}
export function setPanelPosition(settings, monitorIndex, value) {
if (!(value === Pos.TOP || value === Pos.BOTTOM || value === Pos.LEFT
|| value === Pos.RIGHT)) {
log('Not setting invalid panel position: ' + value);
return;
}
const positions = getSettingsJson(settings, 'panel-positions');
positions[monitorIndex] = value;
setSettingsJson(settings, 'panel-positions', positions);
}
/** Returns anchor location of panel on a specific monitor. */
export function getPanelAnchor(settings, monitorIndex) {
const anchors = getSettingsJson(settings, 'panel-anchors');
const theDefault = Pos.MIDDLE;
return anchors[monitorIndex] || theDefault;
}
export function setPanelAnchor(settings, monitorIndex, value) {
if (!(value === Pos.START || value === Pos.MIDDLE || value === Pos.END)) {
log('Not setting invalid panel anchor: ' + value);
return;
}
const anchors = getSettingsJson(settings, 'panel-anchors');
anchors[monitorIndex] = value;
setSettingsJson(settings, 'panel-anchors', anchors);
}

View File

@@ -22,38 +22,23 @@
* mathematical.coffee@gmail.com * mathematical.coffee@gmail.com
*/ */
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Utils from './utils.js';
const ExtensionUtils = imports.misc.extensionUtils;
const Lang = imports.lang;
const Main = imports.ui.main;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Panel = Me.imports.panel; export const PanelStyle = class {
const Taskbar = Me.imports.taskbar;
const Utils = Me.imports.utils;
var dtpPanelStyle = Utils.defineClass({ enable(panel) {
Name: 'ZorinTaskbar.PanelStyle',
_init: function() {
},
enable : function(panel) {
this.panel = panel; this.panel = panel;
this._applyStyles(); this._applyStyles();
}, }
disable: function () { disable() {
this._removeStyles(); this._removeStyles();
}, }
_applyStyles: function() { _applyStyles() {
this._rightBoxOperations = []; this._rightBoxOperations = [];
// center box has been moved next to the right box and will be treated the same // center box has been moved next to the right box and will be treated the same
this._centerBoxOperations = this._rightBoxOperations; this._centerBoxOperations = this._rightBoxOperations;
@@ -62,31 +47,31 @@ var dtpPanelStyle = Utils.defineClass({
this._applyStylesRecursively(); this._applyStylesRecursively();
/* connect signal */ /* connect signal */
this._rightBoxActorAddedID = this.panel._rightBox.connect('actor-added', this._rightBoxActorAddedID = this.panel._rightBox.connect('child-added',
Lang.bind(this, function (container, actor) { (container, actor) => {
if(this._rightBoxOperations.length && !this._ignoreAddedChild) if(this._rightBoxOperations.length && !this._ignoreAddedChild)
this._recursiveApply(actor, this._rightBoxOperations); this._recursiveApply(actor, this._rightBoxOperations);
this._ignoreAddedChild = 0; this._ignoreAddedChild = 0;
}) }
); );
this._centerBoxActorAddedID = this.panel._centerBox.connect('actor-added', this._centerBoxActorAddedID = this.panel._centerBox.connect('child-added',
Lang.bind(this, function (container, actor) { (container, actor) => {
if(this._centerBoxOperations.length && !this._ignoreAddedChild) if(this._centerBoxOperations.length && !this._ignoreAddedChild)
this._recursiveApply(actor, this._centerBoxOperations); this._recursiveApply(actor, this._centerBoxOperations);
this._ignoreAddedChild = 0; this._ignoreAddedChild = 0;
}) }
); );
this._leftBoxActorAddedID = this.panel._leftBox.connect('actor-added', this._leftBoxActorAddedID = this.panel._leftBox.connect('child-added',
Lang.bind(this, function (container, actor) { (container, actor) => {
if(this._leftBoxOperations.length) if(this._leftBoxOperations.length)
this._recursiveApply(actor, this._leftBoxOperations); this._recursiveApply(actor, this._leftBoxOperations);
}) }
); );
}, }
_removeStyles: function() { _removeStyles() {
/* disconnect signal */ /* disconnect signal */
if (this._rightBoxActorAddedID) if (this._rightBoxActorAddedID)
this.panel._rightBox.disconnect(this._rightBoxActorAddedID); this.panel._rightBox.disconnect(this._rightBoxActorAddedID);
@@ -100,13 +85,13 @@ var dtpPanelStyle = Utils.defineClass({
this._restoreOriginalStyle(this.panel._leftBox); this._restoreOriginalStyle(this.panel._leftBox);
this._applyStylesRecursively(true); this._applyStylesRecursively(true);
}, }
_applyStylesRecursively: function(restore) { _applyStylesRecursively(restore) {
/*recurse actors */ /*recurse actors */
if(this._rightBoxOperations.length) { if(this._rightBoxOperations.length) {
// add the system menu as we move it from the rightbox to the panel to position it independently // add the system menu as we move it from the rightbox to the panel to position it independently
let children = this.panel._rightBox.get_children().concat([this.panel.statusArea.aggregateMenu.container]); let children = this.panel._rightBox.get_children().concat([this.panel.statusArea[Utils.getSystemMenuInfo().name].container]);
for(let i in children) for(let i in children)
this._recursiveApply(children[i], this._rightBoxOperations, restore); this._recursiveApply(children[i], this._rightBoxOperations, restore);
} }
@@ -123,9 +108,9 @@ var dtpPanelStyle = Utils.defineClass({
for(let i in children) for(let i in children)
this._recursiveApply(children[i], this._leftBoxOperations, restore); this._recursiveApply(children[i], this._leftBoxOperations, restore);
} }
}, }
_recursiveApply: function(actor, operations, restore) { _recursiveApply(actor, operations, restore) {
for(let i in operations) { for(let i in operations) {
let o = operations[i]; let o = operations[i];
if(o.compareFn(actor)) if(o.compareFn(actor))
@@ -141,9 +126,9 @@ var dtpPanelStyle = Utils.defineClass({
this._recursiveApply(children[i], operations, restore); this._recursiveApply(children[i], operations, restore);
} }
} }
}, }
_restoreOriginalStyle: function(actor) { _restoreOriginalStyle(actor) {
if (actor._dtp_original_inline_style !== undefined) { if (actor._dtp_original_inline_style !== undefined) {
actor.set_style(actor._dtp_original_inline_style); actor.set_style(actor._dtp_original_inline_style);
delete actor._dtp_original_inline_style; delete actor._dtp_original_inline_style;
@@ -153,10 +138,10 @@ var dtpPanelStyle = Utils.defineClass({
if (actor.has_style_class_name('panel-button')) { if (actor.has_style_class_name('panel-button')) {
this._refreshPanelButton(actor); this._refreshPanelButton(actor);
} }
}, }
_refreshPanelButton: function(actor) { _refreshPanelButton(actor) {
if (actor.visible && imports.misc.config.PACKAGE_VERSION >= '3.34.0') { if (actor.visible) {
//force gnome 3.34+ to refresh (having problem with the -natural-hpadding) //force gnome 3.34+ to refresh (having problem with the -natural-hpadding)
let parent = actor.get_parent(); let parent = actor.get_parent();
let children = parent.get_children(); let children = parent.get_children();
@@ -173,4 +158,4 @@ var dtpPanelStyle = Utils.defineClass({
} }
} }
}); }

View File

@@ -24,3 +24,6 @@ msgstr "أظهر زر سطح المكتب المساحة المتروكة (بي
msgid "Floating rounded theme" msgid "Floating rounded theme"
msgstr "مظهر دائري عائم" msgstr "مظهر دائري عائم"
msgid "Isolate Workspaces and Monitors in Application Switching settings"
msgstr "عزل مساحات العمل والشاشات في إعدادات تبديل التطبيقات"

2187
po/cs.po

File diff suppressed because it is too large Load Diff

2301
po/de.po

File diff suppressed because it is too large Load Diff

2063
po/es.po

File diff suppressed because it is too large Load Diff

1488
po/fa.po

File diff suppressed because it is too large Load Diff

2310
po/fr.po

File diff suppressed because it is too large Load Diff

2241
po/gl.po

File diff suppressed because it is too large Load Diff

View File

@@ -24,3 +24,6 @@ msgstr "डेस्कटॉप बटन दिखाएं पैडिंग
msgid "Floating rounded theme" msgid "Floating rounded theme"
msgstr "फ़्लोटिंग गोलाकार थीम" msgstr "फ़्लोटिंग गोलाकार थीम"
msgid "Isolate Workspaces and Monitors in Application Switching settings"
msgstr "एप्लिकेशन स्विचिंग सेटिंग्स में कार्यस्थलों और मॉनिटर को अलग करें"

2088
po/hu.po

File diff suppressed because it is too large Load Diff

View File

@@ -24,3 +24,6 @@ msgstr "Tampilkan tombol desktop padding (px)"
msgid "Floating rounded theme" msgid "Floating rounded theme"
msgstr "Tema bulat mengambang" msgstr "Tema bulat mengambang"
msgid "Isolate Workspaces and Monitors in Application Switching settings"
msgstr "Isolasi Ruang Kerja dan Monitor dalam pengaturan Pengalihan Aplikasi"

2195
po/it.po

File diff suppressed because it is too large Load Diff

2316
po/ja.po

File diff suppressed because it is too large Load Diff

1732
po/kk.po

File diff suppressed because it is too large Load Diff

1813
po/ko.po

File diff suppressed because it is too large Load Diff

1633
po/nl.po

File diff suppressed because it is too large Load Diff

2225
po/pl.po

File diff suppressed because it is too large Load Diff

View File

@@ -24,3 +24,6 @@ msgstr "Preenchimento do botão Mostrar Área de Trabalho (px)"
msgid "Floating rounded theme" msgid "Floating rounded theme"
msgstr "Tema arredondado flutuante" msgstr "Tema arredondado flutuante"
msgid "Isolate Workspaces and Monitors in Application Switching settings"
msgstr "Isolar espaços de trabalho e monitores nas configurações de Comutação de aplicações"

File diff suppressed because it is too large Load Diff

2126
po/ru.po

File diff suppressed because it is too large Load Diff

1454
po/sk.po

File diff suppressed because it is too large Load Diff

2241
po/sv.po

File diff suppressed because it is too large Load Diff

2322
po/tr.po

File diff suppressed because it is too large Load Diff

1655
po/uk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1047
prefs.js

File diff suppressed because it is too large Load Diff

View File

@@ -20,20 +20,21 @@
* and code from the Dash to Panel extension * and code from the Dash to Panel extension
*/ */
const Me = imports.misc.extensionUtils.getCurrentExtension(); import Cairo from 'cairo';
const Gio = imports.gi.Gio; import Gio from 'gi://Gio';
const Cairo = imports.cairo; import Clutter from 'gi://Clutter';
const Clutter = imports.gi.Clutter; import Pango from 'gi://Pango';
const Pango = imports.gi.Pango; import St from 'gi://St';
const St = imports.gi.St; import * as Utils from './utils.js';
const Signals = imports.signals; import {SETTINGS} from './extension.js';
const Utils = Me.imports.utils;
import {EventEmitter} from 'resource:///org/gnome/shell/misc/signals.js';
var ProgressManager = Utils.defineClass({ export const ProgressManager = class extends EventEmitter {
Name: 'ZorinTaskbar.ProgressManager',
_init: function() { constructor() {
super();
this._entriesByDBusName = {}; this._entriesByDBusName = {};
@@ -56,9 +57,9 @@ var ProgressManager = Utils.defineClass({
this._onDBusNameOwnerChanged.bind(this)); this._onDBusNameOwnerChanged.bind(this));
this._acquireUnityDBus(); this._acquireUnityDBus();
}, }
destroy: function() { destroy() {
if (this._launcher_entry_dbus_signal_id) { if (this._launcher_entry_dbus_signal_id) {
Gio.DBus.session.signal_unsubscribe(this._launcher_entry_dbus_signal_id); Gio.DBus.session.signal_unsubscribe(this._launcher_entry_dbus_signal_id);
} }
@@ -68,17 +69,17 @@ var ProgressManager = Utils.defineClass({
} }
this._releaseUnityDBus(); this._releaseUnityDBus();
}, }
size: function() { size() {
return Object.keys(this._entriesByDBusName).length; return Object.keys(this._entriesByDBusName).length;
}, }
lookupByDBusName: function(dbusName) { lookupByDBusName(dbusName) {
return this._entriesByDBusName.hasOwnProperty(dbusName) ? this._entriesByDBusName[dbusName] : null; return this._entriesByDBusName.hasOwnProperty(dbusName) ? this._entriesByDBusName[dbusName] : null;
}, }
lookupById: function(appId) { lookupById(appId) {
let ret = []; let ret = [];
for (let dbusName in this._entriesByDBusName) { for (let dbusName in this._entriesByDBusName) {
let entry = this._entriesByDBusName[dbusName]; let entry = this._entriesByDBusName[dbusName];
@@ -88,9 +89,9 @@ var ProgressManager = Utils.defineClass({
} }
return ret; return ret;
}, }
addEntry: function(entry) { addEntry(entry) {
let existingEntry = this.lookupByDBusName(entry.dbusName()); let existingEntry = this.lookupByDBusName(entry.dbusName());
if (existingEntry) { if (existingEntry) {
existingEntry.update(entry); existingEntry.update(entry);
@@ -98,28 +99,28 @@ var ProgressManager = Utils.defineClass({
this._entriesByDBusName[entry.dbusName()] = entry; this._entriesByDBusName[entry.dbusName()] = entry;
this.emit('progress-entry-added', entry); this.emit('progress-entry-added', entry);
} }
}, }
removeEntry: function(entry) { removeEntry(entry) {
delete this._entriesByDBusName[entry.dbusName()] delete this._entriesByDBusName[entry.dbusName()]
this.emit('progress-entry-removed', entry); this.emit('progress-entry-removed', entry);
}, }
_acquireUnityDBus: function() { _acquireUnityDBus() {
if (!this._unity_bus_id) { if (!this._unity_bus_id) {
Gio.DBus.session.own_name('com.canonical.Unity', Gio.DBus.session.own_name('com.canonical.Unity',
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null); Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null);
} }
}, }
_releaseUnityDBus: function() { _releaseUnityDBus() {
if (this._unity_bus_id) { if (this._unity_bus_id) {
Gio.DBus.session.unown_name(this._unity_bus_id); Gio.DBus.session.unown_name(this._unity_bus_id);
this._unity_bus_id = 0; this._unity_bus_id = 0;
} }
}, }
_onEntrySignalReceived: function(connection, sender_name, object_path, _onEntrySignalReceived(connection, sender_name, object_path,
interface_name, signal_name, parameters, user_data) { interface_name, signal_name, parameters, user_data) {
if (!parameters || !signal_name) if (!parameters || !signal_name)
return; return;
@@ -131,9 +132,9 @@ var ProgressManager = Utils.defineClass({
this._handleUpdateRequest(sender_name, parameters); this._handleUpdateRequest(sender_name, parameters);
} }
}, }
_onDBusNameOwnerChanged: function(connection, sender_name, object_path, _onDBusNameOwnerChanged(connection, sender_name, object_path,
interface_name, signal_name, parameters, user_data) { interface_name, signal_name, parameters, user_data) {
if (!parameters || !this.size()) if (!parameters || !this.size())
return; return;
@@ -145,9 +146,9 @@ var ProgressManager = Utils.defineClass({
this.removeEntry(this._entriesByDBusName[before]); this.removeEntry(this._entriesByDBusName[before]);
} }
} }
}, }
_handleUpdateRequest: function(senderName, parameters) { _handleUpdateRequest(senderName, parameters) {
if (!senderName || !parameters) { if (!senderName || !parameters) {
return; return;
} }
@@ -164,13 +165,13 @@ var ProgressManager = Utils.defineClass({
this.addEntry(entry); this.addEntry(entry);
} }
} }
}); };
Signals.addSignalMethods(ProgressManager.prototype);
var AppProgress = Utils.defineClass({ export class AppProgress extends EventEmitter {
Name: 'ZorinTaskbar.AppProgress',
constructor(dbusName, appId, properties) {
super();
_init: function(dbusName, appId, properties) {
this._dbusName = dbusName; this._dbusName = dbusName;
this._appId = appId; this._appId = appId;
this._count = 0; this._count = 0;
@@ -179,80 +180,80 @@ var AppProgress = Utils.defineClass({
this._progressVisible = false; this._progressVisible = false;
this._urgent = false; this._urgent = false;
this.update(properties); this.update(properties);
}, }
appId: function() { appId() {
return this._appId; return this._appId;
}, }
dbusName: function() { dbusName() {
return this._dbusName; return this._dbusName;
}, }
count: function() { count() {
return this._count; return this._count;
}, }
setCount: function(count) { setCount(count) {
if (this._count != count) { if (this._count != count) {
this._count = count; this._count = count;
this.emit('count-changed', this._count); this.emit('count-changed', this._count);
} }
}, }
countVisible: function() { countVisible() {
return this._countVisible; return this._countVisible;
}, }
setCountVisible: function(countVisible) { setCountVisible(countVisible) {
if (this._countVisible != countVisible) { if (this._countVisible != countVisible) {
this._countVisible = countVisible; this._countVisible = countVisible;
this.emit('count-visible-changed', this._countVisible); this.emit('count-visible-changed', this._countVisible);
} }
}, }
progress: function() { progress() {
return this._progress; return this._progress;
}, }
setProgress: function(progress) { setProgress(progress) {
if (this._progress != progress) { if (this._progress != progress) {
this._progress = progress; this._progress = progress;
this.emit('progress-changed', this._progress); this.emit('progress-changed', this._progress);
} }
}, }
progressVisible: function() { progressVisible() {
return this._progressVisible; return this._progressVisible;
}, }
setProgressVisible: function(progressVisible) { setProgressVisible(progressVisible) {
if (this._progressVisible != progressVisible) { if (this._progressVisible != progressVisible) {
this._progressVisible = progressVisible; this._progressVisible = progressVisible;
this.emit('progress-visible-changed', this._progressVisible); this.emit('progress-visible-changed', this._progressVisible);
} }
}, }
urgent: function() {
return this._urgent;
},
setUrgent: function(urgent) { urgent() {
return this._urgent;
}
setUrgent(urgent) {
if (this._urgent != urgent) { if (this._urgent != urgent) {
this._urgent = urgent; this._urgent = urgent;
this.emit('urgent-changed', this._urgent); this.emit('urgent-changed', this._urgent);
} }
}, }
setDBusName: function(dbusName) { setDBusName(dbusName) {
if (this._dbusName != dbusName) { if (this._dbusName != dbusName) {
let oldName = this._dbusName; let oldName = this._dbusName;
this._dbusName = dbusName; this._dbusName = dbusName;
this.emit('dbus-name-changed', oldName); this.emit('dbus-name-changed', oldName);
} }
}, }
update: function(other) { update(other) {
if (other instanceof AppProgress) { if (other instanceof AppProgress) {
this.setDBusName(other.dbusName()) this.setDBusName(other.dbusName())
this.setCount(other.count()); this.setCount(other.count());
@@ -266,11 +267,11 @@ var AppProgress = Utils.defineClass({
if (property == 'count') { if (property == 'count') {
this.setCount(other[property].get_int64()); this.setCount(other[property].get_int64());
} else if (property == 'count-visible') { } else if (property == 'count-visible') {
this.setCountVisible(Me.settings.get_boolean('progress-show-count') && other[property].get_boolean()); this.setCountVisible(SETTINGS.get_boolean('progress-show-count') && other[property].get_boolean());
} else if (property == 'progress') { } else if (property == 'progress') {
this.setProgress(other[property].get_double()); this.setProgress(other[property].get_double());
} else if (property == 'progress-visible') { } else if (property == 'progress-visible') {
this.setProgressVisible(Me.settings.get_boolean('progress-show-bar') && other[property].get_boolean()); this.setProgressVisible(SETTINGS.get_boolean('progress-show-bar') && other[property].get_boolean());
} else if (property == 'urgent') { } else if (property == 'urgent') {
this.setUrgent(other[property].get_boolean()); this.setUrgent(other[property].get_boolean());
} else { } else {
@@ -280,19 +281,17 @@ var AppProgress = Utils.defineClass({
} }
} }
} }
}); }
Signals.addSignalMethods(AppProgress.prototype);
var ProgressIndicator = Utils.defineClass({ export const ProgressIndicator = class {
Name: 'ZorinTaskbar.ProgressIndicator',
_init: function(source, progressManager) { constructor(source, progressManager) {
this._source = source; this._source = source;
this._progressManager = progressManager; this._progressManager = progressManager;
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler();
this._sourceDestroyId = this._source.actor.connect('destroy', () => { this._sourceDestroyId = this._source.connect('destroy', () => {
this._signalsHandler.destroy(); this._signalsHandler.destroy();
}); });
@@ -326,36 +325,36 @@ var ProgressIndicator = Utils.defineClass({
'progress-entry-removed', 'progress-entry-removed',
this._onEntryRemoved.bind(this) this._onEntryRemoved.bind(this)
]); ]);
}, }
destroy: function() { destroy() {
this._source.actor.disconnect(this._sourceDestroyId); this._source.disconnect(this._sourceDestroyId);
this._signalsHandler.destroy(); this._signalsHandler.destroy();
}, }
_onEntryAdded: function(appProgress, entry) { _onEntryAdded(appProgress, entry) {
if (!entry || !entry.appId()) if (!entry || !entry.appId())
return; return;
if (this._source && this._source.app && this._source.app.id == entry.appId()) { if (this._source && this._source.app && this._source.app.id == entry.appId()) {
this.insertEntry(entry); this.insertEntry(entry);
} }
}, }
_onEntryRemoved: function(appProgress, entry) { _onEntryRemoved(appProgress, entry) {
if (!entry || !entry.appId()) if (!entry || !entry.appId())
return; return;
if (this._source && this._source.app && this._source.app.id == entry.appId()) { if (this._source && this._source.app && this._source.app.id == entry.appId()) {
this.removeEntry(entry); this.removeEntry(entry);
} }
}, }
updateNotificationBadge: function() { updateNotificationBadge() {
this._source.updateNumberOverlay(this._notificationBadgeBin); this._source.updateNumberOverlay(this._notificationBadgeBin);
this._notificationBadgeLabel.clutter_text.ellipsize = Pango.EllipsizeMode.MIDDLE; this._notificationBadgeLabel.clutter_text.ellipsize = Pango.EllipsizeMode.MIDDLE;
}, }
_notificationBadgeCountToText: function(count) { _notificationBadgeCountToText(count) {
if (count <= 9999) { if (count <= 9999) {
return count.toString(); return count.toString();
} else if (count < 1e5) { } else if (count < 1e5) {
@@ -374,24 +373,24 @@ var ProgressIndicator = Utils.defineClass({
let billions = count / 1e9; let billions = count / 1e9;
return billions.toFixed(1).toString() + "B"; return billions.toFixed(1).toString() + "B";
} }
}, }
setNotificationBadge: function(count) { setNotificationBadge(count) {
this._notificationBadgeCount = count; this._notificationBadgeCount = count;
let text = this._notificationBadgeCountToText(count); let text = this._notificationBadgeCountToText(count);
this._notificationBadgeLabel.set_text(text); this._notificationBadgeLabel.set_text(text);
}, }
toggleNotificationBadge: function(activate) { toggleNotificationBadge(activate) {
if (activate && this._notificationBadgeCount > 0) { if (activate && this._notificationBadgeCount > 0) {
this.updateNotificationBadge(); this.updateNotificationBadge();
this._notificationBadgeBin.show(); this._notificationBadgeBin.show();
} }
else else
this._notificationBadgeBin.hide(); this._notificationBadgeBin.hide();
}, }
_showProgressOverlay: function() { _showProgressOverlay() {
if (this._progressOverlayArea) { if (this._progressOverlayArea) {
this._updateProgressOverlay(); this._updateProgressOverlay();
return; return;
@@ -410,34 +409,34 @@ var ProgressIndicator = Utils.defineClass({
if (hasColor) if (hasColor)
this._progressbar_background = color this._progressbar_background = color
else else
this._progressbar_background = new Clutter.Color({red: 204, green: 204, blue: 204, alpha: 255}); this._progressbar_background = new Utils.ColorUtils.Color({red: 204, green: 204, blue: 204, alpha: 255});
[hasColor, color] = node.lookup_color('-progress-bar-border', false); [hasColor, color] = node.lookup_color('-progress-bar-border', false);
if (hasColor) if (hasColor)
this._progressbar_border = color; this._progressbar_border = color;
else else
this._progressbar_border = new Clutter.Color({red: 230, green: 230, blue: 230, alpha: 255}); this._progressbar_border = new Utils.ColorUtils.Color({red: 230, green: 230, blue: 230, alpha: 255});
this._updateProgressOverlay(); this._updateProgressOverlay();
}, }
_hideProgressOverlay: function() { _hideProgressOverlay() {
if (this._progressOverlayArea) if (this._progressOverlayArea)
this._progressOverlayArea.destroy(); this._progressOverlayArea.destroy();
this._progressOverlayArea = null; this._progressOverlayArea = null;
this._progressbar_background = null; this._progressbar_background = null;
this._progressbar_border = null; this._progressbar_border = null;
}, }
_updateProgressOverlay: function() { _updateProgressOverlay() {
if (this._progressOverlayArea) { if (this._progressOverlayArea) {
this._progressOverlayArea.queue_repaint(); this._progressOverlayArea.queue_repaint();
} }
}, }
_drawProgressOverlay: function(area) { _drawProgressOverlay(area) {
let scaleFactor = Utils.getScaleFactor(); let scaleFactor = Utils.getScaleFactor();
let [surfaceWidth, surfaceHeight] = area.get_surface_size(); let [surfaceWidth, surfaceHeight] = area.get_surface_size();
let cr = area.get_context(); let cr = area.get_context();
@@ -495,31 +494,31 @@ var ProgressIndicator = Utils.defineClass({
Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill); Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill);
cr.$dispose(); cr.$dispose();
}, }
setProgress: function(progress) { setProgress(progress) {
this._progress = Math.min(Math.max(progress, 0.0), 1.0); this._progress = Math.min(Math.max(progress, 0.0), 1.0);
this._updateProgressOverlay(); this._updateProgressOverlay();
}, }
toggleProgressOverlay: function(activate) { toggleProgressOverlay(activate) {
if (activate) { if (activate) {
this._showProgressOverlay(); this._showProgressOverlay();
} }
else { else {
this._hideProgressOverlay(); this._hideProgressOverlay();
} }
}, }
insertEntry: function(appProgress) { insertEntry(appProgress) {
if (!appProgress || this._progressManagerEntries.indexOf(appProgress) !== -1) if (!appProgress || this._progressManagerEntries.indexOf(appProgress) !== -1)
return; return;
this._progressManagerEntries.push(appProgress); this._progressManagerEntries.push(appProgress);
this._selectEntry(appProgress); this._selectEntry(appProgress);
}, }
removeEntry: function(appProgress) { removeEntry(appProgress) {
if (!appProgress || this._progressManagerEntries.indexOf(appProgress) == -1) if (!appProgress || this._progressManagerEntries.indexOf(appProgress) == -1)
return; return;
@@ -534,9 +533,9 @@ var ProgressIndicator = Utils.defineClass({
this.toggleProgressOverlay(false); this.toggleProgressOverlay(false);
this.setUrgent(false); this.setUrgent(false);
} }
}, }
_selectEntry: function(appProgress) { _selectEntry(appProgress) {
if (!appProgress) if (!appProgress)
return; return;
@@ -570,7 +569,9 @@ var ProgressIndicator = Utils.defineClass({
], [ ], [
appProgress, appProgress,
'urgent-changed', 'urgent-changed',
(appProgress, value) => this.setUrgent(value) (appProgress, value) => {
this.setUrgent(value)
}
]); ]);
this.setNotificationBadge(appProgress.count()); this.setNotificationBadge(appProgress.count());
@@ -579,8 +580,8 @@ var ProgressIndicator = Utils.defineClass({
this.toggleProgressOverlay(appProgress.progressVisible()); this.toggleProgressOverlay(appProgress.progressVisible());
this._isUrgent = false; this._isUrgent = false;
}, }
setUrgent(urgent) { setUrgent(urgent) {
const icon = this._source.icon._iconBin; const icon = this._source.icon._iconBin;
if (urgent) { if (urgent) {
@@ -597,4 +598,4 @@ var ProgressIndicator = Utils.defineClass({
icon.rotation_angle_z = 0; icon.rotation_angle_z = 0;
} }
} }
}); };

View File

@@ -18,14 +18,12 @@
* This file is based on code from the Dash to Panel extension * This file is based on code from the Dash to Panel extension
*/ */
const Lang = imports.lang; import Meta from 'gi://Meta';
const Meta = imports.gi.Meta; import Mtk from 'gi://Mtk';
const Layout = imports.ui.layout; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const Main = imports.ui.main;
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Utils from './utils.js';
const Utils = Me.imports.utils;
//timeout intervals //timeout intervals
const MIN_UPDATE_MS = 200; const MIN_UPDATE_MS = 200;
@@ -33,53 +31,46 @@ const MIN_UPDATE_MS = 200;
//timeout names //timeout names
const T1 = 'limitUpdateTimeout'; const T1 = 'limitUpdateTimeout';
var Mode = { export const Mode = {
ALL_WINDOWS: 0, ALL_WINDOWS: 0,
FOCUSED_WINDOWS: 1, FOCUSED_WINDOWS: 1,
MAXIMIZED_WINDOWS: 2 MAXIMIZED_WINDOWS: 2
}; };
var ProximityWatch = Utils.defineClass({ export class ProximityWatch {
Name: 'ZorinTaskbar.ProximityWatch',
_init: function(actor, mode, xThreshold, yThreshold, handler) { constructor(actor, monitorIndex, mode, xThreshold, yThreshold, handler) {
this.actor = actor; this.actor = actor;
this.overlap = 0; this.monitorIndex = monitorIndex
this.overlap = false;
this.mode = mode; this.mode = mode;
this.threshold = [xThreshold, yThreshold]; this.threshold = [xThreshold, yThreshold];
this.handler = handler; this.handler = handler;
this._allocationChangedId = actor.connect('notify::allocation', () => this._update()); this._allocationChangedId = actor.connect('notify::allocation', () => this._updateWatchRect());
this._update();
},
destroy: function() {
this.actor.disconnect(this._allocationChangedId);
},
_update: function() {
this.monitorIndex = Main.layoutManager.findIndexForActor(this.actor);
this._updateWatchRect(); this._updateWatchRect();
}, }
_updateWatchRect: function() { destroy() {
this.actor.disconnect(this._allocationChangedId);
}
_updateWatchRect() {
let [actorX, actorY] = this.actor.get_position(); let [actorX, actorY] = this.actor.get_position();
this.rect = new Meta.Rectangle({ this.rect = new Mtk.Rectangle({
x: actorX - this.threshold[0], x: actorX - this.threshold[0],
y: actorY - this.threshold[1], y: actorY - this.threshold[1],
width: this.actor.width + this.threshold[0] * 2, width: this.actor.width + this.threshold[0] * 2,
height: this.actor.height + this.threshold[1] * 2 height: this.actor.height + this.threshold[1] * 2
}); });
}, }
}); };
var ProximityManager = Utils.defineClass({ export const ProximityManager = class {
Name: 'ZorinTaskbar.ProximityManager',
_init: function() { constructor() {
this._counter = 1; this._counter = 1;
this._watches = {}; this._watches = {};
this._focusedWindowInfo = null; this._focusedWindowInfo = null;
@@ -89,41 +80,41 @@ var ProximityManager = Utils.defineClass({
this._bindSignals(); this._bindSignals();
this._setFocusedWindow(); this._setFocusedWindow();
}, }
createWatch: function(actor, mode, xThreshold, yThreshold, handler) { createWatch(actor, monitorIndex, mode, xThreshold, yThreshold, handler) {
let watch = new ProximityWatch(actor, mode, xThreshold, yThreshold, handler); let watch = new ProximityWatch(actor, monitorIndex, mode, xThreshold, yThreshold, handler);
this._watches[this._counter] = watch; this._watches[this._counter] = watch;
this.update(); this.update();
return this._counter++; return this._counter++;
}, }
removeWatch: function(id) { removeWatch(id) {
if (this._watches[id]) { if (this._watches[id]) {
this._watches[id].destroy(); this._watches[id].destroy();
delete this._watches[id]; delete this._watches[id];
} }
}, }
update: function() { update() {
this._queueUpdate(true); this._queueUpdate(true);
}, }
destroy: function() { destroy() {
this._signalsHandler.destroy(); this._signalsHandler.destroy();
this._timeoutsHandler.destroy(); this._timeoutsHandler.destroy();
this._disconnectFocusedWindow(); this._disconnectFocusedWindow();
Object.keys(this._watches).forEach(id => this.removeWatch(id)); Object.keys(this._watches).forEach(id => this.removeWatch(id));
}, }
_bindSignals: function() { _bindSignals() {
this._signalsHandler.add( this._signalsHandler.add(
[ [
global.window_manager, global.window_manager,
'switch-workspace', 'switch-workspace',
() => Object.keys(this._watches).forEach(id => this._watches[id].overlap = 0) () => this._queueUpdate()
], ],
[ [
Main.overview, Main.overview,
@@ -139,17 +130,14 @@ var ProximityManager = Utils.defineClass({
} }
], ],
[ [
global.window_group, global.display,
[ 'restacked',
'actor-added',
'actor-removed'
],
() => this._queueUpdate() () => this._queueUpdate()
] ]
); );
}, }
_setFocusedWindow: function() { _setFocusedWindow() {
this._disconnectFocusedWindow(); this._disconnectFocusedWindow();
let focusedWindow = global.display.focus_window; let focusedWindow = global.display.focus_window;
@@ -164,15 +152,15 @@ var ProximityManager = Utils.defineClass({
this._focusedWindowInfo = focusedWindowInfo; this._focusedWindowInfo = focusedWindowInfo;
} }
} }
}, }
_getFocusedWindowInfo: function(focusedWindow) { _getFocusedWindowInfo(focusedWindow) {
let window = focusedWindow.get_compositor_private(); let window = focusedWindow.get_compositor_private();
let focusedWindowInfo; let focusedWindowInfo;
if (window) { if (window) {
focusedWindowInfo = { window: window }; focusedWindowInfo = { window: window };
focusedWindowInfo.metaWindow = focusedWindowInfo.window.get_meta_window(); focusedWindowInfo.metaWindow = focusedWindow;
if (focusedWindow.is_attached_dialog()) { if (focusedWindow.is_attached_dialog()) {
let mainMetaWindow = focusedWindow.get_transient_for(); let mainMetaWindow = focusedWindow.get_transient_for();
@@ -185,38 +173,40 @@ var ProximityManager = Utils.defineClass({
} }
return focusedWindowInfo; return focusedWindowInfo;
}, }
_disconnectFocusedWindow: function(destroy) { _disconnectFocusedWindow(destroy) {
if (this._focusedWindowInfo && !destroy) { if (this._focusedWindowInfo && !destroy) {
this._focusedWindowInfo.window.disconnect(this._focusedWindowInfo.allocationId); this._focusedWindowInfo.window.disconnect(this._focusedWindowInfo.allocationId);
this._focusedWindowInfo.window.disconnect(this._focusedWindowInfo.destroyId); this._focusedWindowInfo.window.disconnect(this._focusedWindowInfo.destroyId);
} }
this._focusedWindowInfo = null; this._focusedWindowInfo = null;
}, }
_getHandledWindows: function() { _getHandledWindows() {
return global.get_window_actors() return Utils.getCurrentWorkspace()
.filter(w => w.visible) .list_windows()
.map(w => w.get_meta_window()) .filter(mw => this._checkIfHandledWindow(mw));
.filter(mw => this._checkIfHandledWindow(mw)); }
},
_checkIfHandledWindow: function(metaWindow) { _checkIfHandledWindow(metaWindow) {
return metaWindow && !metaWindow.minimized && return metaWindow &&
!metaWindow.minimized &&
!metaWindow.customJS_ding &&
metaWindow.window_type != Meta.WindowType.DESKTOP &&
this._checkIfHandledWindowType(metaWindow); this._checkIfHandledWindowType(metaWindow);
}, }
_checkIfHandledWindowType: function(metaWindow) { _checkIfHandledWindowType(metaWindow) {
let metaWindowType = metaWindow.get_window_type(); let metaWindowType = metaWindow.get_window_type();
//https://www.roojs.org/seed/gir-1.2-gtk-3.0/seed/Meta.WindowType.html //https://www.roojs.org/seed/gir-1.2-gtk-3.0/seed/Meta.WindowType.html
return metaWindowType <= Meta.WindowType.SPLASHSCREEN && return metaWindowType <= Meta.WindowType.SPLASHSCREEN &&
metaWindowType != Meta.WindowType.DESKTOP; metaWindowType != Meta.WindowType.DESKTOP;
}, }
_queueUpdate: function(noDelay) { _queueUpdate(noDelay) {
if (!noDelay && this._timeoutsHandler.getId(T1)) { if (!noDelay && this._timeoutsHandler.getId(T1)) {
//limit the number of updates //limit the number of updates
this._pendingUpdate = true; this._pendingUpdate = true;
@@ -226,40 +216,45 @@ var ProximityManager = Utils.defineClass({
this._timeoutsHandler.add([T1, MIN_UPDATE_MS, () => this._endLimitUpdate()]); this._timeoutsHandler.add([T1, MIN_UPDATE_MS, () => this._endLimitUpdate()]);
let metaWindows = this._getHandledWindows(); let metaWindows = this._getHandledWindows();
Object.keys(this._watches).forEach(id => { Object.keys(this._watches).forEach(id => {
let watch = this._watches[id]; let watch = this._watches[id];
let overlap = this._update(watch, metaWindows); let overlap = !!this._update(watch, metaWindows);
if (overlap !== watch.overlap) { if (overlap !== watch.overlap) {
watch.handler(overlap); watch.handler(overlap);
watch.overlap = overlap; watch.overlap = overlap;
} }
}); });
}, }
_endLimitUpdate: function() { _endLimitUpdate() {
if (this._pendingUpdate) { if (this._pendingUpdate) {
this._pendingUpdate = false; this._pendingUpdate = false;
this._queueUpdate(); this._queueUpdate();
} }
}, }
_update: function(watch, metaWindows) { _update(watch, metaWindows) {
if (watch.mode === Mode.FOCUSED_WINDOWS) { if (watch.mode === Mode.FOCUSED_WINDOWS)
return (this._focusedWindowInfo && return (this._focusedWindowInfo &&
this._checkIfHandledWindow(this._focusedWindowInfo.metaWindow) && this._checkIfHandledWindow(this._focusedWindowInfo.metaWindow) &&
this._checkProximity(this._focusedWindowInfo.metaWindow, watch)); this._checkProximity(this._focusedWindowInfo.metaWindow, watch));
} else if (watch.mode === Mode.MAXIMIZED_WINDOWS) {
if (watch.mode === Mode.MAXIMIZED_WINDOWS)
return metaWindows.some(mw => mw.maximized_vertically && mw.maximized_horizontally && return metaWindows.some(mw => mw.maximized_vertically && mw.maximized_horizontally &&
mw.get_monitor() == watch.monitorIndex); mw.get_monitor() == watch.monitorIndex);
}
//Mode.ALL_WINDOWS //Mode.ALL_WINDOWS
return metaWindows.some(mw => this._checkProximity(mw, watch)); return metaWindows.some(mw => this._checkProximity(mw, watch));
}, }
_checkProximity: function(metaWindow, watch) { _checkProximity(metaWindow, watch) {
return metaWindow.get_frame_rect().overlap(watch.rect); let windowRect = metaWindow.get_frame_rect();
},
}); return windowRect.overlap(watch.rect) &&
((!watch.threshold[0] && !watch.threshold[1]) ||
metaWindow.get_monitor() == watch.monitorIndex ||
windowRect.overlap(global.display.get_monitor_geometry(watch.monitorIndex)));
}
};

View File

@@ -17,6 +17,7 @@
<value value='4' nick='CYCLE-MIN'/> <value value='4' nick='CYCLE-MIN'/>
<value value='5' nick='QUIT'/> <value value='5' nick='QUIT'/>
<value value='6' nick='TOGGLE-SHOWPREVIEW'/> <value value='6' nick='TOGGLE-SHOWPREVIEW'/>
<value value='7' nick='TOGGLE-CYCLE'/>
</enum> </enum>
<enum id='org.gnome.shell.extensions.zorin-taskbar.scrollAction'> <enum id='org.gnome.shell.extensions.zorin-taskbar.scrollAction'>
<value value='0' nick='NOTHING'/> <value value='0' nick='NOTHING'/>
@@ -42,13 +43,6 @@
<value value='1' nick='FOCUSED_WINDOWS'/> <value value='1' nick='FOCUSED_WINDOWS'/>
<value value='2' nick='MAXIMIZED_WINDOWS'/> <value value='2' nick='MAXIMIZED_WINDOWS'/>
</enum> </enum>
<enum id='org.gnome.shell.extensions.zorin-taskbar.fontWeight'>
<value value='0' nick='inherit'/>
<value value='1' nick='normal'/>
<value value='2' nick='lighter'/>
<value value='3' nick='bold'/>
<value value='4' nick='bolder'/>
</enum>
<enum id='org.gnome.shell.extensions.zorin-taskbar.hotkeyNumberKeys'> <enum id='org.gnome.shell.extensions.zorin-taskbar.hotkeyNumberKeys'>
<value value='0' nick='NUM_ROW'/> <value value='0' nick='NUM_ROW'/>
<value value='1' nick='NUM_KEYPAD'/> <value value='1' nick='NUM_KEYPAD'/>
@@ -57,7 +51,7 @@
<schema path="/org/gnome/shell/extensions/zorin-taskbar/" id="org.gnome.shell.extensions.zorin-taskbar"> <schema path="/org/gnome/shell/extensions/zorin-taskbar/" id="org.gnome.shell.extensions.zorin-taskbar">
<key name="panel-position" enum="org.gnome.shell.extensions.zorin-taskbar.position"> <key name="panel-position" enum="org.gnome.shell.extensions.zorin-taskbar.position">
<default>'BOTTOM'</default> <default>'BOTTOM'</default>
<summary>Panel position</summary> <summary>Panel position (Deprecated)</summary>
<description>Panel is shown on the Bottom or Top of the screen.</description> <description>Panel is shown on the Bottom or Top of the screen.</description>
</key> </key>
<key name="panel-element-positions-monitors-sync" type="b"> <key name="panel-element-positions-monitors-sync" type="b">
@@ -75,9 +69,24 @@
<summary>Panel element positions</summary> <summary>Panel element positions</summary>
<description>Panel element positions (JSON).</description> <description>Panel element positions (JSON).</description>
</key> </key>
<key type="s" name="panel-lengths">
<default>'{}'</default>
<summary>Percentages of screen edge for panel to span</summary>
<description>Length of the panels, in percent (JSON).</description>
</key>
<key type="s" name="panel-anchors">
<default>'{}'</default>
<summary>Positions along screen edge</summary>
<description>Where to show the panels if it is not the full length of the screen edge (JSON).</description>
</key>
<key type="s" name="panel-sizes">
<default>'{}'</default>
<summary>Panel sizes</summary>
<description>Sizes of panels, in pixels.</description>
</key>
<key type="i" name="panel-size"> <key type="i" name="panel-size">
<default>48</default> <default>48</default>
<summary>Panel size</summary> <summary>Panel size (Deprecated)</summary>
<description>Set the size of the panel.</description> <description>Set the size of the panel.</description>
</key> </key>
<key name="dot-style-focused" enum="org.gnome.shell.extensions.zorin-taskbar.dotStyle"> <key name="dot-style-focused" enum="org.gnome.shell.extensions.zorin-taskbar.dotStyle">
@@ -95,6 +104,16 @@
<summary>Running indicator dominant color</summary> <summary>Running indicator dominant color</summary>
<description>Whether to use the app icon's dominant color for .app-well-running-dot</description> <description>Whether to use the app icon's dominant color for .app-well-running-dot</description>
</key> </key>
<key type="b" name="stockgs-keep-top-panel">
<default>false</default>
<summary>Keep top panel</summary>
<description>Whether to keep the stock gnome-shell top panel</description>
</key>
<key type="b" name="stockgs-panelbtn-click-only">
<default>false</default>
<summary>Panel menu buttons require click</summary>
<description>Whether to activate the panel menu buttons on hover or on click</description>
</key>
<key type="b" name="taskbar-locked"> <key type="b" name="taskbar-locked">
<default>false</default> <default>false</default>
<summary>Lock the taskbar</summary> <summary>Lock the taskbar</summary>
@@ -105,11 +124,31 @@
<summary>Custom background color</summary> <summary>Custom background color</summary>
<description>Replace current theme background color for the panel</description> <description>Replace current theme background color for the panel</description>
</key> </key>
<key type="b" name="trans-use-dynamic-opacity">
<default>false</default>
<summary>Dynamic opacity</summary>
<description>Enable dynamic opacity</description>
</key>
<key type="d" name="trans-panel-opacity"> <key type="d" name="trans-panel-opacity">
<default>0.4</default> <default>0.4</default>
<summary>Panel opacity</summary> <summary>Panel opacity</summary>
<description>Custom opacity for the panel</description> <description>Custom opacity for the panel</description>
</key> </key>
<key name="trans-dynamic-behavior" enum="org.gnome.shell.extensions.zorin-taskbar.proximityBehavior">
<default>'ALL_WINDOWS'</default>
<summary>Dynamic opacity behavior</summary>
<description>Dictates which window type affects the panel opacity</description>
</key>
<key type="i" name="trans-dynamic-distance">
<default>20</default>
<summary>Distance to change opacity</summary>
<description>The distance a window needs to be from the panel to change opacity</description>
</key>
<key type="d" name="trans-dynamic-anim-target">
<default>0.8</default>
<summary>Modified panel opacity</summary>
<description>Modified opacity for the panel when a window is near</description>
</key>
<key type="b" name="intellihide"> <key type="b" name="intellihide">
<default>false</default> <default>false</default>
<summary>Intellihide</summary> <summary>Intellihide</summary>
@@ -150,20 +189,10 @@
<summary>Keybinding toggle intellihide</summary> <summary>Keybinding toggle intellihide</summary>
<description>Keybinding to reveal the panel while in intellihide mode</description> <description>Keybinding to reveal the panel while in intellihide mode</description>
</key> </key>
<key type="b" name="intellihide-floating-rounded-theme"> <key type="b" name="floating-rounded-theme">
<default>true</default> <default>false</default>
<summary>Floating rounded theme</summary> <summary>Floating rounded theme</summary>
<description>Display the panel with a floating rounded theme while in intellihide mode</description> <description>Display the panel with a floating rounded theme</description>
</key>
<key type="b" name="show-apps-override-escape">
<default>true</default>
<summary>Override escape key</summary>
<description>Override the escape key to return to the desktop when entering the overview using the Show Applications button</description>
</key>
<key type="b" name="animate-show-apps">
<default>true</default>
<summary>Animate Show Applications from the desktop</summary>
<description>Animate Show Applications from the desktop</description>
</key> </key>
<key type="as" name="panel-context-menu-commands"> <key type="as" name="panel-context-menu-commands">
<default>[]</default> <default>[]</default>
@@ -216,7 +245,7 @@
<description>Peek a window upon hover for some time</description> <description>Peek a window upon hover for some time</description>
</key> </key>
<key type="i" name="window-preview-size"> <key type="i" name="window-preview-size">
<default>250</default> <default>200</default>
<summary>Window previews size</summary> <summary>Window previews size</summary>
<description>Preferred window previews size</description> <description>Preferred window previews size</description>
</key> </key>
@@ -339,7 +368,7 @@
<description>When multiple instances of the application are available, show their window previews</description> <description>When multiple instances of the application are available, show their window previews</description>
</key> </key>
<key name="shortcut-num-keys" enum="org.gnome.shell.extensions.zorin-taskbar.hotkeyNumberKeys"> <key name="shortcut-num-keys" enum="org.gnome.shell.extensions.zorin-taskbar.hotkeyNumberKeys">
<default>'BOTH'</default> <default>'NUM_ROW'</default>
<summary>Hotkeys number keys</summary> <summary>Hotkeys number keys</summary>
<description>Which number keys are used for the hotkeys</description> <description>Which number keys are used for the hotkeys</description>
</key> </key>

View File

@@ -21,34 +21,40 @@
* Some code was also adapted from the upstream Gnome Shell source code. * Some code was also adapted from the upstream Gnome Shell source code.
*/ */
#zorintaskbarTaskbar .dash-item-container > StWidget { #zorintaskbarTaskbar .dash-item-container > StWidget,
margin: 0; .zorintaskbarMainPanel .dash-item-container .show-apps {
padding: 0;
}
#zorintaskbarScrollview .app-well-app .overview-icon,
.zorintaskbarMainPanel .show-apps .overview-icon {
background: none;
border: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
#zorintaskbarScrollview .app-well-app .overview-label { #zorintaskbarScrollview .overview-tile,
.zorintaskbarMainPanel .overview-tile {
background: none;
}
#zorintaskbarScrollview .overview-tile .overview-label {
/* must match TITLE_RIGHT_PADDING in apppicons.js */ /* must match TITLE_RIGHT_PADDING in apppicons.js */
padding-right: 8px; padding-right: 8px;
text-align: left;
} }
#zorintaskbarScrollview .app-well-app .favorite { .zorintaskbarMainPanel .dash-item-container .show-apps .overview-icon {
background-color: rgba(80, 150, 255, 0.4); color: #FFF;
} }
#zorintaskbarScrollview .app-well-app-running-dot { #zorintaskbarTaskbar .dash-item-container .overview-tile:hover,
margin-bottom: 0; #zorintaskbarTaskbar .dash-item-container .overview-tile .dtp-container .overview-icon,
#zorintaskbarScrollview .overview-tile:hover .dtp-container.animate-appicon-hover,
.zorintaskbarMainPanel .dash-item-container .show-apps:hover .overview-icon {
background: none;
}
#zorintaskbarScrollview .overview-tile .favorite {
/*background-color: rgba(80, 150, 255, 0.4);*/
} }
#zorintaskbarTaskbar .scrollview-fade { #zorintaskbarTaskbar .scrollview-fade {
background-gradient-end: rgba(0, 0, 0, 0); background-gradient-end: rgba(0, 0, 0, 0);
} }
.zorintaskbarSecondaryMenu { .zorintaskbarSecondaryMenu {
@@ -56,19 +62,26 @@
} }
.zorintaskbarMainPanel.vertical .panel-button { .zorintaskbarMainPanel.vertical .panel-button {
text-align: center; text-align: center;
} }
.zorintaskbarMainPanel.vertical .panel-button.vertical *, .zorintaskbarMainPanel.vertical .panel-button.vertical *,
.zorintaskbarMainPanel.vertical .panel-button.clock-display * { .zorintaskbarMainPanel.vertical .panel-button.clock-display * {
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
.zorintaskbarMainPanel.vertical .panel-button > *, .zorintaskbarMainPanel.vertical .panel-button > *,
.zorintaskbarMainPanel.vertical .panel-button.vertical > *, .zorintaskbarMainPanel.vertical .panel-button.vertical > *,
.zorintaskbarMainPanel.vertical .panel-button.clock-display > * { .zorintaskbarMainPanel.vertical .panel-button.vertical .system-status-icon,
padding: 8px 0; .zorintaskbarMainPanel.vertical .panel-button.clock-display > *,
.zorintaskbarMainPanel.vertical .panel-button.clock-display .clock {
padding: 8px 0;
}
.zorintaskbarMainPanel.vertical .panel-button.clock-display {
-natural-hpadding: 0;
-minimum-hpadding: 0;
} }
#zorintaskbarThumbnailList { #zorintaskbarThumbnailList {
@@ -92,26 +105,35 @@
} }
.popup-menu.panel-menu { .popup-menu.panel-menu {
margin-bottom: 0; margin-bottom: 0;
} }
#panel #panelLeft, #panel #panelCenter { #panel #panelLeft, #panel #panelCenter {
spacing: 0px; spacing: 0px;
} }
#panelBox.floating { #panelBox.floating {
padding: 8px;
background: transparent; background: transparent;
} }
#panelBox.floating.top {
padding: 8px 8px 0 8px;
}
#panelBox.floating.right {
padding: 8px 8px 8px 0;
}
#panelBox.floating.bottom {
padding: 0 8px 8px 8px;
}
#panelBox.floating.left {
padding: 8px 0 8px 8px;
}
#panelBox.floating #panel, #panelBox.floating #panel,
#panelBox.floating .panel-button { #panelBox.floating .panel-button,
#panelBox.floating .panel-button.clock-display .clock {
border-radius: 10px; border-radius: 10px;
} }
.panel-corner.hidden:active, .panel-corner.hidden:overview, .panel-corner.hidden:focus {
-panel-corner-border-color: rgba(0, 0, 0, .001);
}
#zorintaskbarScrollview .badge { #zorintaskbarScrollview .badge {
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
font-weight: bold; font-weight: bold;
@@ -123,15 +145,14 @@
} }
#zorintaskbarScrollview .notification-badge { #zorintaskbarScrollview .notification-badge {
background-color: rgba(255,0,0,0.8); background-color: rgba(255,0,0,0.8);
margin: 2px; margin: 2px;
} }
#zorintaskbarScrollview .progress-bar { #zorintaskbarScrollview .progress-bar {
/* Customization of the progress bar style, e.g.: /* Customization of the progress bar style, e.g.:
-progress-bar-background: rgba(0.8, 0.8, 0.8, 1); -progress-bar-background: rgba(0.8, 0.8, 0.8, 1);
-progress-bar-border: rgba(0.9, 0.9, 0.9, 1); -progress-bar-border: rgba(0.9, 0.9, 0.9, 1); */
*/
} }
.preview-container, .preview-container,

File diff suppressed because it is too large Load Diff

View File

@@ -18,54 +18,46 @@
* This file is based on code from the Dash to Panel extension * This file is based on code from the Dash to Panel extension
*/ */
const Clutter = imports.gi.Clutter; import GdkPixbuf from 'gi://GdkPixbuf';
const GdkPixbuf = imports.gi.GdkPixbuf; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const Lang = imports.lang; import St from 'gi://St';
const Main = imports.ui.main;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Proximity from './proximity.js';
const Panel = Me.imports.panel; import * as Utils from './utils.js';
const Proximity = Me.imports.proximity; import {SETTINGS} from './extension.js';
const Utils = Me.imports.utils;
var DynamicTransparency = Utils.defineClass({ const TRANS_DYNAMIC_DISTANCE = 20;
Name: 'ZorinTaskbar.DynamicTransparency',
_init: function(dtpPanel) { export const DynamicTransparency = class {
constructor(dtpPanel) {
this._dtpPanel = dtpPanel; this._dtpPanel = dtpPanel;
this._proximityManager = dtpPanel.panelManager.proximityManager;
this._proximityWatchId = 0;
this.currentBackgroundColor = 0; this.currentBackgroundColor = 0;
this._initialPanelStyle = dtpPanel.panel.actor.get_style(); this._initialPanelStyle = dtpPanel.panel.get_style();
if (this._dtpPanel.geom.position == St.Side.TOP) {
this._initialPanelCornerStyle = dtpPanel.panel._leftCorner.actor.get_style();
}
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler();
this._bindSignals(); this._bindSignals();
this._updateAllAndSet(); this._updateAllAndSet();
}, this._updateProximityWatch();
}
destroy: function() { destroy() {
this._signalsHandler.destroy(); this._signalsHandler.destroy();
this._proximityManager.removeWatch(this._proximityWatchId);
this._dtpPanel.panel.actor.set_style(this._initialPanelStyle); this._dtpPanel.panel.set_style(this._initialPanelStyle);
}
if (this._dtpPanel.geom.position == St.Side.TOP) {
this._dtpPanel.panel._leftCorner.actor.set_style(this._initialPanelCornerStyle);
this._dtpPanel.panel._rightCorner.actor.set_style(this._initialPanelCornerStyle);
}
},
updateExternalStyle: function() { updateExternalStyle() {
this._updateComplementaryStyles(); this._updateComplementaryStyles();
this._setBackground(); this._setBackground();
}, }
_bindSignals: function() { _bindSignals() {
this._signalsHandler.add( this._signalsHandler.add(
[ [
Utils.getStageTheme(), Utils.getStageTheme(),
@@ -81,17 +73,51 @@ var DynamicTransparency = Utils.defineClass({
() => this._updateAlphaAndSet() () => this._updateAlphaAndSet()
], ],
[ [
Me.settings, SETTINGS,
[ [
'changed::trans-use-custom-opacity', 'changed::trans-use-custom-opacity',
'changed::trans-panel-opacity' 'changed::trans-panel-opacity',
'changed::trans-dynamic-anim-target',
'changed::trans-use-dynamic-opacity'
], ],
() => this._updateAlphaAndSet() () => this._updateAlphaAndSet()
],
[
SETTINGS,
[
'changed::trans-dynamic-behavior',
'changed::trans-use-dynamic-opacity'
],
() => this._updateProximityWatch()
] ]
); );
}, }
_updateAllAndSet: function() { _updateProximityWatch() {
this._proximityManager.removeWatch(this._proximityWatchId);
if (SETTINGS.get_boolean('trans-use-dynamic-opacity')) {
let isVertical = this._dtpPanel.checkIfVertical();
let threshold = TRANS_DYNAMIC_DISTANCE;
this._windowOverlap = false;
this._updateAlphaAndSet()
this._proximityWatchId = this._proximityManager.createWatch(
this._dtpPanel.panelBox.get_parent(),
this._dtpPanel.monitor.index,
Proximity.Mode[SETTINGS.get_string('trans-dynamic-behavior')],
isVertical ? threshold : 0,
isVertical ? 0 : threshold,
overlap => {
this._windowOverlap = overlap;
this._updateAlphaAndSet();
}
);
}
}
_updateAllAndSet() {
let themeBackground = this._getThemeBackground(true); let themeBackground = this._getThemeBackground(true);
this._updateColor(themeBackground); this._updateColor(themeBackground);
@@ -99,64 +125,63 @@ var DynamicTransparency = Utils.defineClass({
this._updateComplementaryStyles(); this._updateComplementaryStyles();
this._setBackground(); this._setBackground();
this._setActorStyle(); this._setActorStyle();
}, }
_updateAlphaAndSet: function() { _updateAlphaAndSet() {
this._updateAlpha(); this._updateAlpha();
this._setBackground(); this._setBackground();
}, }
_updateComplementaryStyles: function() { _updateComplementaryStyles() {
let panelThemeNode = this._dtpPanel.panel.actor.get_theme_node(); let panelThemeNode = this._dtpPanel.panel.get_theme_node();
this._complementaryStyles = 'border-radius: ' + panelThemeNode.get_border_radius(0) + 'px;'; this._complementaryStyles = 'border-radius: ' + panelThemeNode.get_border_radius(0) + 'px;';
}, }
_updateColor: function(themeBackground) { _updateColor(themeBackground) {
this.backgroundColorRgb = (themeBackground || this._getThemeBackground()); this.backgroundColorRgb = themeBackground || this._getThemeBackground();
}, }
_updateAlpha: function(themeBackground) { _updateAlpha(themeBackground) {
this.alpha = Me.settings.get_boolean('trans-use-custom-opacity') ? if (this._windowOverlap && !Main.overview.visibleTarget && SETTINGS.get_boolean('trans-use-dynamic-opacity')) {
Me.settings.get_double('trans-panel-opacity') : this.alpha = SETTINGS.get_double('trans-dynamic-anim-target');
(themeBackground || this._getThemeBackground()).alpha * 0.003921569; // 1 / 255 = 0.003921569 } else {
}, this.alpha = SETTINGS.get_boolean('trans-use-custom-opacity') ?
SETTINGS.get_double('trans-panel-opacity') :
(themeBackground || this._getThemeBackground()).alpha * 0.003921569; // 1 / 255 = 0.003921569
}
}
_setBackground: function() { _setBackground() {
this.currentBackgroundColor = Utils.getrgbaColor(this.backgroundColorRgb, this.alpha); this.currentBackgroundColor = Utils.getrgbaColor(this.backgroundColorRgb, this.alpha);
let transition = 'transition-duration: 200ms;'; let transition = 'transition-duration: 300ms;';
let cornerStyle = '-panel-corner-background-color: ' + this.currentBackgroundColor + transition;
this._dtpPanel.set_style('background-color: ' + this.currentBackgroundColor + transition + this._complementaryStyles); this._dtpPanel.set_style('background-color: ' + this.currentBackgroundColor + transition + this._complementaryStyles);
}
if (this._dtpPanel.geom.position == St.Side.TOP) {
this._dtpPanel.panel._leftCorner.actor.set_style(cornerStyle);
this._dtpPanel.panel._rightCorner.actor.set_style(cornerStyle);
}
},
_setActorStyle: function() { _setActorStyle() {
this._dtpPanel.panel.actor.set_style( this._dtpPanel.panel.set_style(
'background: none; ' + 'background: none; ' +
'border-image: none; ' + 'border-image: none; ' +
'background-image: none;' 'background-image: none; ' +
'transition-duration: 300ms;'
); );
}, }
_getThemeBackground: function(reload) { _getThemeBackground(reload) {
if (reload || !this._themeBackground) { if (reload || !this._themeBackground) {
let fakePanel = new St.Bin({ name: 'panel' }); let fakePanel = new St.Bin({ name: 'panel' });
Main.uiGroup.add_child(fakePanel); Main.uiGroup.add_child(fakePanel);
let fakeTheme = fakePanel.get_theme_node(); let fakeTheme = fakePanel.get_theme_node()
this._themeBackground = this._getBackgroundImageColor(fakeTheme) || fakeTheme.get_background_color(); this._themeBackground = this._getBackgroundImageColor(fakeTheme) || fakeTheme.get_background_color();
Main.uiGroup.remove_child(fakePanel); Main.uiGroup.remove_child(fakePanel);
} }
return this._themeBackground; return this._themeBackground;
}, }
_getBackgroundImageColor: function(theme) { _getBackgroundImageColor(theme) {
let bg = null; let bg = null;
try { try {
@@ -172,4 +197,4 @@ var DynamicTransparency = Utils.defineClass({
return bg; return bg;
} }
}); }

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="trans_opacity_min_adjustment">
<property name="upper">100</property>
<property name="step_increment">5</property>
<property name="page_increment">10</property>
</object>
<object class="GtkBox" id="box_dynamic_opacity_options">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">The panel background opacity is affected by</property>
<child>
<object class="GtkComboBoxText" id="trans_options_window_type_combo">
<property name="valign">center</property>
<items>
<item id="ALL_WINDOWS" translatable="yes">All windows</item>
<item id="FOCUSED_WINDOWS" translatable="yes">Focused windows</item>
<item id="MAXIMIZED_WINDOWS" translatable="yes">Maximized windows</item>
</items>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Change opacity to (%)</property>
<child>
<object class="GtkSpinButton" id="trans_options_min_opacity_spinbutton">
<property name="text" translatable="yes">0</property>
<property name="valign">center</property>
<property name="adjustment">trans_opacity_min_adjustment</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

72
ui/BoxGroupAppsOptions.ui Normal file
View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="group_apps_label_max_width_adjustment">
<property name="upper">1000</property>
<property name="step_increment">10</property>
<property name="page_increment">100</property>
</object>
<object class="GtkBox" id="box_group_apps_options">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Maximum width (px) of the application titles</property>
<property name="subtitle" translatable="yes">(default is 160)</property>
<child>
<object class="GtkSpinButton" id="group_apps_label_max_width_spinbutton">
<property name="valign">center</property>
<property name="width_chars">4</property>
<property name="text">0</property>
<property name="adjustment">group_apps_label_max_width_adjustment</property>
<property name="numeric">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Use a fixed width for the application titles</property>
<property name="subtitle" translatable="yes">The application titles all have the same width, even if their texts are shorter than the maximum width. The maximum width value is used as the fixed width.</property>
<child>
<object class="GtkSwitch" id="group_apps_use_fixed_width_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Use the favorite icons as application launchers</property>
<child>
<object class="GtkSwitch" id="group_apps_use_launchers_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

109
ui/BoxIntellihideOptions.ui Normal file
View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkBox" id="box_intellihide_options">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Only hide the panel when it is obstructed by windows</property>
<child>
<object class="GtkSwitch" id="intellihide_window_hide_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="intellihide_behaviour_options">
<property name="title" translatable="yes">The panel hides from</property>
<child>
<object class="GtkComboBoxText" id="intellihide_behaviour_combo">
<property name="valign">center</property>
<items>
<item id="ALL_WINDOWS" translatable="yes">All windows</item>
<item id="FOCUSED_WINDOWS" translatable="yes">Focused windows</item>
<item id="MAXIMIZED_WINDOWS" translatable="yes">Maximized windows</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Require pressure at the edge of the screen to reveal the panel</property>
<child>
<object class="GtkSwitch" id="intellihide_use_pressure_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Allow the panel to be revealed while in fullscreen mode</property>
<child>
<object class="GtkSwitch" id="intellihide_show_in_fullscreen_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="grid_intellihide_only_secondary">
<property name="title" translatable="yes">Only hide secondary panels</property>
<property name="subtitle" translatable="yes">(requires multi-monitors option)</property>
<child>
<object class="GtkSwitch" id="intellihide_only_secondary_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Keyboard shortcut to reveal and hold the panel</property>
<property name="subtitle" translatable="yes">Syntax: &amp;lt;Shift&amp;gt;, &amp;lt;Ctrl&amp;gt;, &amp;lt;Alt&amp;gt;, &amp;lt;Super&amp;gt;</property>
<child>
<object class="GtkEntry" id="intellihide_toggle_entry">
<property name="valign">center</property>
<property name="width_chars">12</property>
<property name="placeholder_text" translatable="yes">e.g. &lt;Super&gt;i</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

100
ui/BoxMiddleClickOptions.ui Normal file
View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkBox" id="box_middle_click_options">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Shift+Click action</property>
<property name="subtitle" translatable="yes">When set to minimize, double clicking minimizes all the windows of the application.</property>
<child>
<object class="GtkComboBoxText" id="shift_click_action_combo">
<property name="valign">center</property>
<items>
<item id="RAISE" translatable="yes">Raise windows</item>
<item id="MINIMIZE" translatable="yes">Minimize window</item>
<item id="LAUNCH" translatable="yes">Launch new instance</item>
<item id="CYCLE" translatable="yes">Cycle through windows</item>
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="QUIT" translatable="yes">Quit</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Middle-Click action</property>
<property name="subtitle" translatable="yes">Behavior for Middle-Click.</property>
<child>
<object class="GtkComboBoxText" id="middle_click_action_combo">
<property name="valign">center</property>
<items>
<item id="RAISE" translatable="yes">Raise windows</item>
<item id="MINIMIZE" translatable="yes">Minimize window</item>
<item id="LAUNCH" translatable="yes">Launch new instance</item>
<item id="CYCLE" translatable="yes">Cycle through windows</item>
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="QUIT" translatable="yes">Quit</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Shift+Middle-Click action</property>
<property name="subtitle" translatable="yes">Behavior for Shift+Middle-Click.</property>
<child>
<object class="GtkComboBoxText" id="shift_middle_click_action_combo">
<property name="valign">center</property>
<items>
<item id="RAISE" translatable="yes">Raise windows</item>
<item id="MINIMIZE" translatable="yes">Minimize window</item>
<item id="LAUNCH" translatable="yes">Launch new instance</item>
<item id="CYCLE" translatable="yes">Cycle through windows</item>
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="QUIT" translatable="yes">Quit</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

97
ui/BoxOverlayShortcut.ui Normal file
View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkBox" id="box_overlay_shortcut">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Hotkeys prefix</property>
<property name="subtitle" translatable="yes">Hotkeys will either be Super+Number or Super+Alt+Num</property>
<child>
<object class="GtkComboBoxText" id="hotkey_prefix_combo">
<property name="valign">center</property>
<items>
<item id="Super" translatable="yes">Super</item>
<item id="SuperAlt" translatable="yes">Super + Alt</item>
</items>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Number overlay</property>
<property name="subtitle" translatable="yes">Temporarily show the application numbers over the icons when using the hotkeys.</property>
<child>
<object class="GtkComboBoxText" id="overlay_combo">
<property name="valign">center</property>
<items>
<item id="NEVER" translatable="yes">Never</item>
<item id="TEMPORARILY" translatable="yes">Show temporarily</item>
<item id="ALWAYS" translatable="yes">Always visible</item>
</items>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Shortcut to show the overlay for 2 seconds</property>
<property name="subtitle" translatable="yes">Syntax: &amp;lt;Shift&amp;gt;, &amp;lt;Ctrl&amp;gt;, &amp;lt;Alt&amp;gt;, &amp;lt;Super&amp;gt;</property>
<child>
<object class="GtkEntry" id="shortcut_entry">
<property name="valign">center</property>
<property name="width_chars">12</property>
<property name="placeholder_text" translatable="yes">e.g. &lt;Super&gt;q</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show window previews on hotkey</property>
<property name="subtitle" translatable="yes">Show previews when the application have multiple instances</property>
<child>
<object class="GtkSwitch" id="shortcut_preview_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Hotkeys are activated with</property>
<property name="subtitle" translatable="yes">Select which keyboard number keys are used to activate the hotkeys</property>
<child>
<object class="GtkComboBoxText" id="shortcut_num_keys_combo">
<property name="valign">center</property>
<items>
<item id="NUM_ROW" translatable="yes">Number row</item>
<item id="NUM_KEYPAD" translatable="yes">Numeric keypad</item>
<item id="BOTH" translatable="yes">Both</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkBox" id="box_date_menu_options">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Date</property>
<child>
<object class="GtkSwitch" id="date_menu_date_switch">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Weekday</property>
<child>
<object class="GtkSwitch" id="date_menu_weekday_switch">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Seconds</property>
<child>
<object class="GtkSwitch" id="date_menu_seconds_switch">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="show_showdesktop_width_adjustment">
<property name="lower">1</property>
<property name="upper">40</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="show_showdesktop_delay_adjustment">
<property name="upper">5000</property>
<property name="step_increment">10</property>
<property name="page_increment">100</property>
</object>
<object class="GtkAdjustment" id="show_showdesktop_time_adjustment">
<property name="upper">5000</property>
<property name="step_increment">10</property>
<property name="page_increment">100</property>
</object>
<object class="GtkBox" id="box_show_showdesktop_options">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show Desktop icon</property>
<child>
<object class="GtkSwitch" id="show_showdesktop_icon_switch">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="show_showdesktop_width_label">
<child>
<object class="GtkSpinButton" id="show_showdesktop_width_spinbutton">
<property name="valign">center</property>
<property name="width_chars">4</property>
<property name="text">1</property>
<property name="adjustment">show_showdesktop_width_adjustment</property>
<property name="numeric">True</property>
<property name="value">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Reveal the desktop when hovering the Show Desktop button</property>
<child>
<object class="GtkSwitch" id="show_showdesktop_hide_switch">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="preview_size_adjustment">
<property name="lower">100</property>
<property name="upper">800</property>
<property name="step_increment">10</property>
<property name="page_increment">50</property>
</object>
<object class="GtkScrolledWindow" id="box_window_preview_options">
<property name="width-request">680</property>
<property name="height-request">280</property>
<property name="vexpand">True</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="width-request">600</property>
<property name="spacing">24</property>
<property name="margin-top">32</property>
<property name="margin-bottom">32</property>
<property name="margin-start">32</property>
<property name="margin-end">32</property>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Middle click on the preview to close the window</property>
<child>
<object class="GtkSwitch" id="preview_middle_click_close_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Window previews preferred size (px)</property>
<child>
<object class="GtkSpinButton" id="preview_size_spinbutton">
<property name="valign">center</property>
<property name="width_chars">4</property>
<property name="text">100</property>
<property name="adjustment">preview_size_adjustment</property>
<property name="numeric">True</property>
<property name="value">100</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Enable window peeking</property>
<property name="subtitle" translatable="yes">When hovering over a window preview for some time, the window gets distinguished.</property>
<child>
<object class="GtkSwitch" id="peek_mode_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

143
ui/SettingsAction.ui Normal file
View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="AdwPreferencesPage" id="action">
<property name="title" translatable="yes">Action</property>
<property name="icon_name">view-pin-symbolic</property>
<!-- group click action -->
<child>
<object class="AdwPreferencesGroup" id="action_group_click_action">
<property name="title" translatable="yes">Click action</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Click action</property>
<property name="subtitle" translatable="yes">Behaviour when clicking on the icon of a running application.</property>
<child>
<object class="GtkButton" id="middle_click_options_button">
<property name="receives_default">True</property>
<property name="valign">center</property>
<child>
<object class="GtkImage" id="middle_click_image">
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="click_action_combo">
<property name="valign">center</property>
<items>
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="CYCLE" translatable="yes">Cycle through windows</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="MINIMIZE" translatable="yes">Toggle windows</item>
<item id="RAISE" translatable="yes">Raise windows</item>
<item id="LAUNCH" translatable="yes">Launch new instance</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group scroll action -->
<child>
<object class="AdwPreferencesGroup" id="action_group_scroll_action">
<property name="title" translatable="yes">Scroll action</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Scroll icon action</property>
<property name="subtitle" translatable="yes">Behavior when mouse scrolling over an application icon.</property>
<child>
<object class="GtkComboBoxText" id="scroll_icon_combo">
<property name="valign">center</property>
<property name="hexpand">True</property>
<items>
<item id="NOTHING" translatable="yes">Do nothing</item>
<item id="CYCLE_WINDOWS" translatable="yes">Cycle windows</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group hotkey -->
<child>
<object class="AdwPreferencesGroup" id="action_group_hotkry">
<property name="title" translatable="yes">Hotkey overlay</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Use hotkeys to activate apps</property>
<property name="subtitle" translatable="yes">Enable Super+(0-9) as shortcuts to activate apps. It can also be used together with Shift and Ctrl.</property>
<child>
<object class="GtkButton" id="overlay_button">
<property name="receives_default">True</property>
<property name="valign">center</property>
<child>
<object class="GtkImage" id="image_overlay">
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkSwitch" id="hot_keys_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group gnome -->
<child>
<object class="AdwPreferencesGroup" id="finetune_group_gnome">
<property name="title" translatable="yes">Gnome functionality</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Keep original gnome-shell top panel</property>
<child>
<object class="GtkSwitch" id="stockgs_top_panel_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Activate panel menu buttons on click only</property>
<property name="subtitle" translatable="yes">(e.g. date menu)</property>
<child>
<object class="GtkSwitch" id="stockgs_panelbtn_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

151
ui/SettingsBehavior.ui Normal file
View File

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="AdwPreferencesPage" id="behavior">
<property name="title" translatable="yes">Behavior</property>
<property name="icon_name">preferences-system-symbolic</property>
<!-- group applications -->
<child>
<object class="AdwPreferencesGroup" id="behavior_group_applications">
<property name="title" translatable="yes">Applications</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show favorite applications</property>
<child>
<object class="GtkSwitch" id="show_favorite_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show favorite applications on secondary panels</property>
<child>
<object class="GtkSwitch" id="multimon_multi_show_favorites_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show running applications</property>
<child>
<object class="GtkSwitch" id="show_runnning_apps_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Ungroup applications</property>
<child>
<object class="GtkButton" id="show_group_apps_options_button">
<property name="receives_default">True</property>
<property name="valign">center</property>
<child>
<object class="GtkImage" id="image_show_group_apps_options">
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkSwitch" id="group_apps_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show notification counter badge</property>
<child>
<object class="GtkSwitch" id="show_notification_badge_switch">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group hover -->
<child>
<object class="AdwPreferencesGroup" id="behavior_group_hover">
<property name="title" translatable="yes">Hover</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show window previews on hover</property>
<child>
<object class="GtkButton" id="show_window_previews_button">
<property name="receives_default">True</property>
<property name="valign">center</property>
<child>
<object class="GtkImage" id="image_window_previews_options">
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkSwitch" id="show_window_previews_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Show tooltip on hover</property>
<child>
<object class="GtkSwitch" id="show_tooltip_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group isolate -->
<child>
<object class="AdwPreferencesGroup" id="behavior_group_isolate">
<property name="title" translatable="yes">Isolate</property>
<child>
<object class="AdwActionRow" id="display_multitasking_settings">
<property name="title" translatable="yes">Isolate Workspaces and Monitors in Application Switching settings</property>
<property name="activatable">True</property>
<child>
<object class="GtkImage" id="image_display_multitasking_settings">
<property name="icon_name">adw-external-link-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

201
ui/SettingsPosition.ui Normal file
View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="panel_size_adjustment">
<property name="lower">0.33</property>
<property name="upper">1</property>
<property name="step_increment">0.01</property>
<property name="page_increment">0.1</property>
</object>
<object class="GtkAdjustment" id="panel_length_adjustment">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="AdwPreferencesPage" id="position">
<property name="title" translatable="yes">Position</property>
<property name="icon_name">find-location-symbolic</property>
<!-- group panel -->
<child>
<object class="AdwPreferencesGroup" id="position_group_panel">
<property name="title" translatable="yes">Panel</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Display panels on all monitors</property>
<child>
<object class="GtkSwitch" id="multimon_multi_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group order and positions -->
<child>
<object class="AdwPreferencesGroup" id="position_group_on_monitor">
<property name="title" translatable="yes">Order and Position on monitors</property>
<child>
<object class="AdwPreferencesRow">
<property name="title" translatable="yes">Monitor</property>
<child>
<object class="GtkBox">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<child>
<object class="GtkCheckButton" id="taskbar_position_sync_button">
<property name="label" translatable="yes">Apply changes to all monitors</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="taskbar_position_monitor_combo">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group order and positions 2 -->
<child>
<object class="AdwPreferencesGroup" id="position_group_on_monitor2">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Panel screen position</property>
<child>
<object class="GtkToggleButton" id="position_bottom_button">
<property name="label" translatable="yes">Bottom</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="active">True</property>
<signal name="clicked" handler="position_bottom_button_clicked_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="position_top_button">
<property name="label" translatable="yes">Top</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="group">position_bottom_button</property>
<signal name="clicked" handler="position_top_button_clicked_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="position_left_button">
<property name="label" translatable="yes">Left</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="group">position_bottom_button</property>
<signal name="clicked" handler="position_left_button_clicked_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="position_right_button">
<property name="label" translatable="yes">Right</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="group">position_bottom_button</property>
<signal name="clicked" handler="position_right_button_clicked_cb" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Panel thickness</property>
<property name="subtitle" translatable="yes">(default is 48)</property>
<child>
<object class="GtkScale" id="panel_size_scale">
<property name="width-request">350</property>
<property name="adjustment">panel_size_adjustment</property>
<property name="round_digits">0</property>
<property name="digits">0</property>
<property name="value_pos">right</property>
<property name="draw_value">True</property>
<signal name="value-changed" handler="panel_size_scale_value_changed_cb" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Panel length (%)</property>
<property name="subtitle" translatable="yes">(default is 100)</property>
<child>
<object class="GtkScale" id="panel_length_scale">
<property name="width-request">350</property>
<property name="adjustment">panel_length_adjustment</property>
<property name="round_digits">0</property>
<property name="digits">0</property>
<property name="value_pos">right</property>
<property name="draw_value">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="panel_anchor_label">
<property name="title" translatable="yes">Anchor</property>
<child>
<object class="GtkComboBoxText" id="panel_anchor_combo">
<property name="valign">center</property>
<items>
<item id="START" translatable="yes">Start</item>
<item id="MIDDLE" translatable="yes">Middle</item>
<item id="END" translatable="yes">End</item>
</items>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group order and positions 3 -->
<child>
<object class="AdwPreferencesGroup" id="position_group_on_monitor3">
<child>
<object class="AdwPreferencesRow">
<property name="title" translatable="yes">Taskbar Display</property>
<child>
<object class="GtkListBox" id="taskbar_display_listbox">
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="visible">True</property>
<property name="selection_mode">none</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

118
ui/SettingsStyle.ui Normal file
View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="trans_opacity_adjustment">
<property name="upper">100</property>
<property name="step_increment">5</property>
<property name="page_increment">10</property>
</object>
<object class="AdwPreferencesPage" id="style">
<property name="title" translatable="yes">Style</property>
<property name="icon_name">applications-graphics-symbolic</property>
<!-- group panel intellihide -->
<child>
<object class="AdwPreferencesGroup" id="position_group_panel2">
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Panel Intellihide</property>
<property name="subtitle" translatable="yes">Hide and reveal the panel according to preferences</property>
<child>
<object class="GtkButton" id="intellihide_options_button">
<property name="receives_default">True</property>
<property name="valign">center</property>
<child>
<object class="GtkImage" id="image_intellihide_options">
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkSwitch" id="intellihide_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- group dynamic trans2 -->
<child>
<object class="AdwPreferencesGroup" id="style_group_dynamic_trans2">
<property name="title" translatable="yes">Panel style</property>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Floating rounded theme</property>
<child>
<object class="GtkSwitch" id="floating_rounded_theme_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Override panel theme background opacity</property>
<child>
<object class="GtkSwitch" id="trans_opacity_override_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="trans_opacity_box">
<property name="title" translatable="yes">Panel background opacity (%)</property>
<child>
<object class="GtkSpinButton" id="trans_opacity_spinbutton">
<property name="valign">center</property>
<property name="text" translatable="yes">0</property>
<property name="adjustment">trans_opacity_adjustment</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="trans_opacity_box2">
<property name="title" translatable="yes">Dynamic background opacity</property>
<property name="subtitle" translatable="yes">Change opacity when a window gets close to the panel</property>
<child>
<object class="GtkButton" id="trans_dyn_options_button">
<property name="receives_default">True</property>
<property name="valign">center</property>
<child>
<object class="GtkImage" id="image_trans_dyn_options">
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
</style>
</object>
</child>
<child>
<object class="GtkSwitch" id="trans_dyn_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

506
utils.js
View File

@@ -21,119 +21,43 @@
* Some code was also adapted from the upstream Gnome Shell source code. * Some code was also adapted from the upstream Gnome Shell source code.
*/ */
const Clutter = imports.gi.Clutter; import Clutter from 'gi://Clutter';
const Config = imports.misc.config; import Cogl from 'gi://Cogl';
const GdkPixbuf = imports.gi.GdkPixbuf import GdkPixbuf from 'gi://GdkPixbuf';
const Gi = imports._gi; import Gio from 'gi://Gio';
const Gio = imports.gi.Gio; import GLib from 'gi://GLib';
const GLib = imports.gi.GLib; import Graphene from 'gi://Graphene';
const GObject = imports.gi.GObject; import Meta from 'gi://Meta';
const Gtk = imports.gi.Gtk; import Shell from 'gi://Shell';
const Meta = imports.gi.Meta; import St from 'gi://St';
const Shell = imports.gi.Shell; import * as Util from 'resource:///org/gnome/shell/misc/util.js';
const St = imports.gi.St; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const Mainloop = imports.mainloop; import * as MessageTray from 'resource:///org/gnome/shell/ui/messageTray.js';
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Util = imports.misc.util;
var TRANSLATION_DOMAIN = imports.misc.extensionUtils.getCurrentExtension().metadata['gettext-domain']; const SCROLL_TIME = Util.SCROLL_TIME / (Util.SCROLL_TIME > 1 ? 1000 : 1);
var SCROLL_TIME = Util.SCROLL_TIME / (Util.SCROLL_TIME > 1 ? 1000 : 1);
//Clutter implicit animations are available since 3.34
//prefer those over Tweener if available
if (Config.PACKAGE_VERSION < '3.34') {
var Tweener = imports.ui.tweener;
}
var defineClass = function (classDef) {
let parentProto = classDef.Extends ? classDef.Extends.prototype : null;
if (Config.PACKAGE_VERSION < '3.31.9') {
if (parentProto && (classDef.Extends.name || classDef.Extends.toString()).indexOf('ZorinTaskbar.') < 0) {
classDef.callParent = function() {
let args = Array.prototype.slice.call(arguments);
let func = args.shift();
classDef.Extends.prototype[func].apply(this, args);
};
}
return new imports.lang.Class(classDef);
}
let isGObject = parentProto instanceof GObject.Object;
let needsSuper = parentProto && !isGObject;
let getParentArgs = function(args) {
let parentArgs = [];
(classDef.ParentConstrParams || parentArgs).forEach(p => {
if (p.constructor === Array) {
let param = args[p[0]];
parentArgs.push(p[1] ? param[p[1]] : param);
} else {
parentArgs.push(p);
}
});
return parentArgs;
};
let C = eval(
'(class C ' + (needsSuper ? 'extends Object' : '') + ' { ' +
' constructor(...args) { ' +
(needsSuper ? 'super(...getParentArgs(args));' : '') +
(needsSuper || !parentProto ? 'this._init(...args);' : '') +
' }' +
' callParent(...args) { ' +
' let func = args.shift(); ' +
' if (!(func === \'_init\' && needsSuper))' +
' super[func](...args); ' +
' }' +
'})'
);
if (parentProto) {
Object.setPrototypeOf(C.prototype, parentProto);
Object.setPrototypeOf(C, classDef.Extends);
}
Object.defineProperty(C, 'name', { value: classDef.Name });
Object.keys(classDef)
.filter(k => classDef.hasOwnProperty(k) && classDef[k] instanceof Function)
.forEach(k => C.prototype[k] = classDef[k]);
if (isGObject) {
C = GObject.registerClass({ Signals: classDef.Signals || {} }, C);
}
return C;
};
// simplify global signals and function injections handling // simplify global signals and function injections handling
// abstract class // abstract class
var BasicHandler = defineClass({ export const BasicHandler = class {
Name: 'ZorinTaskbar.BasicHandler',
_init: function(){ constructor() {
this._storage = new Object(); this._storage = new Object();
}, }
add: function(/*unlimited 3-long array arguments*/){ add(/*unlimited 3-long array arguments*/){
// convert arguments object to array, concatenate with generic // convert arguments object to array, concatenate with generic
let args = [].concat('generic', [].slice.call(arguments)); let args = [].concat('generic', [].slice.call(arguments));
// call addWithLabel with ags as if they were passed arguments // call addWithLabel with ags as if they were passed arguments
this.addWithLabel.apply(this, args); this.addWithLabel.apply(this, args);
}, }
destroy: function() { destroy() {
for( let label in this._storage ) for( let label in this._storage )
this.removeWithLabel(label); this.removeWithLabel(label);
}, }
addWithLabel: function( label /* plus unlimited 3-long array arguments*/) { addWithLabel( label /* plus unlimited 3-long array arguments*/) {
if(this._storage[label] == undefined) if(this._storage[label] == undefined)
this._storage[label] = new Array(); this._storage[label] = new Array();
@@ -148,9 +72,9 @@ var BasicHandler = defineClass({
} }
} }
}, }
removeWithLabel: function(label){ removeWithLabel(label){
if(this._storage[label]) { if(this._storage[label]) {
for( let i = 0; i < this._storage[label].length; i++ ) { for( let i = 0; i < this._storage[label].length; i++ ) {
@@ -159,26 +83,24 @@ var BasicHandler = defineClass({
delete this._storage[label]; delete this._storage[label];
} }
}, }
/* Virtual methods to be implemented by subclass */ /* Virtual methods to be implemented by subclass */
// create single element to be stored in the storage structure // create single element to be stored in the storage structure
_create: function(item){ _create(item){
throw new Error('no implementation of _create in ' + this); throw new Error('no implementation of _create in ' + this);
}, }
// correctly delete single element // correctly delete single element
_remove: function(item){ _remove(item){
throw new Error('no implementation of _remove in ' + this); throw new Error('no implementation of _remove in ' + this);
} }
}); }
// Manage global signals // Manage global signals
var GlobalSignalsHandler = defineClass({ export const GlobalSignalsHandler = class extends BasicHandler {
Name: 'ZorinTaskbar.GlobalSignalsHandler',
Extends: BasicHandler,
_create: function(item) { _create(item) {
let handlers = []; let handlers = [];
item[1] = [].concat(item[1]); item[1] = [].concat(item[1]);
@@ -187,28 +109,31 @@ var GlobalSignalsHandler = defineClass({
let object = item[0]; let object = item[0];
let event = item[1][i]; let event = item[1][i];
let callback = item[2] let callback = item[2]
let id = object.connect(event, callback); try {
let id = object.connect(event, callback);
handlers.push([object, id]); handlers.push([object, id]);
} catch (e)
{
}
} }
return handlers; return handlers;
}, }
_remove: function(item){ _remove(item){
item[0].disconnect(item[1]); item[0].disconnect(item[1]);
} }
}); };
/** /**
* Manage function injection: both instances and prototype can be overridden * Manage function injection: both instances and prototype can be overridden
* and restored * and restored
*/ */
var InjectionsHandler = defineClass({ export const InjectionsHandler = class extends BasicHandler {
Name: 'ZorinTaskbar.InjectionsHandler',
Extends: BasicHandler,
_create: function(item) { _create(item) {
let object = item[0]; let object = item[0];
let name = item[1]; let name = item[1];
let injectedFunction = item[2]; let injectedFunction = item[2];
@@ -216,112 +141,126 @@ var InjectionsHandler = defineClass({
object[name] = injectedFunction; object[name] = injectedFunction;
return [[object, name, injectedFunction, original]]; return [[object, name, injectedFunction, original]];
}, }
_remove: function(item) { _remove(item) {
let object = item[0]; let object = item[0];
let name = item[1]; let name = item[1];
let original = item[3]; let original = item[3];
object[name] = original; object[name] = original;
} }
}); };
/** /**
* Manage timeouts: the added timeouts have their id reset on completion * Manage timeouts: the added timeouts have their id reset on completion
*/ */
var TimeoutsHandler = defineClass({ export const TimeoutsHandler = class extends BasicHandler {
Name: 'ZorinTaskbar.TimeoutsHandler',
Extends: BasicHandler,
_create: function(item) { _create(item) {
let name = item[0]; let name = item[0];
let delay = item[1]; let delay = item[1];
let timeoutHandler = item[2]; let timeoutHandler = item[2];
this._remove(item); this._remove(item);
this[name] = Mainloop.timeout_add(delay, () => { this[name] = GLib.timeout_add(GLib.PRIORITY_DEFAULT, delay, () => {
this[name] = 0; this[name] = 0;
timeoutHandler(); timeoutHandler();
return GLib.SOURCE_REMOVE;
}); });
return [[name]]; return [[name]];
}, }
remove: function(name) { remove(name) {
this._remove([name]) this._remove([name])
}, }
_remove: function(item) { _remove(item) {
let name = item[0]; let name = item[0];
if (this[name]) { if (this[name]) {
Mainloop.source_remove(this[name]); GLib.Source.remove(this[name]);
this[name] = 0; this[name] = 0;
} }
}, }
getId: function(name) { getId(name) {
return this[name] ? this[name] : 0; return this[name] ? this[name] : 0;
} }
}); };
// This is wrapper to maintain compatibility with GNOME-Shell 3.30+ as well as // This is wrapper to maintain compatibility with GNOME-Shell 3.30+ as well as
// previous versions. // previous versions.
var DisplayWrapper = { export const DisplayWrapper = {
getScreen: function() { getScreen() {
return global.screen || global.display; return global.screen || global.display;
}, },
getWorkspaceManager: function() { getWorkspaceManager() {
return global.screen || global.workspace_manager; return global.screen || global.workspace_manager;
}, },
getMonitorManager: function() { getMonitorManager() {
return global.screen || Meta.MonitorManager.get(); return global.screen || global.backend.get_monitor_manager();
} }
}; };
var getCurrentWorkspace = function() { let unredirectEnabled = true
export const setDisplayUnredirect = (enable) => {
if (enable && !unredirectEnabled)
Meta.enable_unredirect_for_display(global.display);
else if (!enable && unredirectEnabled)
Meta.disable_unredirect_for_display(global.display);
unredirectEnabled = enable;
};
export const getSystemMenuInfo = function() {
return {
name: 'quickSettings',
constructor: Main.panel.statusArea.quickSettings.constructor
};
}
export const getCurrentWorkspace = function() {
return DisplayWrapper.getWorkspaceManager().get_active_workspace(); return DisplayWrapper.getWorkspaceManager().get_active_workspace();
}; };
var getWorkspaceByIndex = function(index) { export const getWorkspaceByIndex = function(index) {
return DisplayWrapper.getWorkspaceManager().get_workspace_by_index(index); return DisplayWrapper.getWorkspaceManager().get_workspace_by_index(index);
}; };
var getWorkspaceCount = function() { export const getWorkspaceCount = function() {
return DisplayWrapper.getWorkspaceManager().n_workspaces; return DisplayWrapper.getWorkspaceManager().n_workspaces;
}; };
var getStageTheme = function() { export const getStageTheme = function() {
return St.ThemeContext.get_for_stage(global.stage); return St.ThemeContext.get_for_stage(global.stage);
}; };
var getScaleFactor = function() { export const getScaleFactor = function() {
return getStageTheme().scale_factor || 1; return getStageTheme().scale_factor || 1;
}; };
var getAppDisplayViews = function() { export const findIndex = function(array, predicate) {
//gnome-shell 3.38 only has one view and it is now the appDisplay if (array) {
return Main.overview.viewSelector.appDisplay._views || [{ view: Main.overview.viewSelector.appDisplay }]; if (Array.prototype.findIndex) {
}; return array.findIndex(predicate);
}
var findIndex = function(array, predicate) { for (let i = 0, l = array.length; i < l; ++i) {
if (Array.prototype.findIndex) { if (predicate(array[i])) {
return array.findIndex(predicate); return i;
} }
for (let i = 0, l = array.length; i < l; ++i) {
if (predicate(array[i])) {
return i;
} }
} }
return -1; return -1;
}; };
var find = function(array, predicate) { export const find = function(array, predicate) {
let index = findIndex(array, predicate); let index = findIndex(array, predicate);
if (index > -1) { if (index > -1) {
@@ -329,8 +268,8 @@ var find = function(array, predicate) {
} }
}; };
var mergeObjects = function(main, bck) { export const mergeObjects = function(main, bck) {
for (var prop in bck) { for (const prop in bck) {
if (!main.hasOwnProperty(prop) && bck.hasOwnProperty(prop)) { if (!main.hasOwnProperty(prop) && bck.hasOwnProperty(prop)) {
main[prop] = bck[prop]; main[prop] = bck[prop];
} }
@@ -339,30 +278,14 @@ var mergeObjects = function(main, bck) {
return main; return main;
}; };
var hookVfunc = function(proto, symbol, func) { export const getTrackedActorData = (actor) => {
if (Gi.hook_up_vfunc_symbol) { let trackedIndex = Main.layoutManager._findActor(actor);
//gjs > 1.53.3
proto[Gi.hook_up_vfunc_symbol](symbol, func); if (trackedIndex >= 0)
} else { return Main.layoutManager._trackedActors[trackedIndex]
//On older gjs, this is how to hook vfunc. It is buggy and can't be used reliably to replace }
//already hooked functions. Since it's our only use for it, disabled for now (and probably forever)
//Gi.hook_up_vfunc(proto, symbol, func);
}
};
var wrapActor = function(actor) {
if (actor) {
Object.defineProperty(actor, 'actor', {
value: actor instanceof Clutter.Actor ? actor : actor.actor
});
}
};
var getTransformedAllocation = function(actor) {
if (Config.PACKAGE_VERSION < '3.37') {
return Shell.util_get_transformed_allocation(actor);
}
export const getTransformedAllocation = function(actor) {
let extents = actor.get_transformed_extents(); let extents = actor.get_transformed_extents();
let topLeft = extents.get_top_left(); let topLeft = extents.get_top_left();
let bottomRight = extents.get_bottom_right(); let bottomRight = extents.get_bottom_right();
@@ -370,33 +293,13 @@ var getTransformedAllocation = function(actor) {
return { x1: topLeft.x, x2: bottomRight.x, y1: topLeft.y, y2: bottomRight.y }; return { x1: topLeft.x, x2: bottomRight.x, y1: topLeft.y, y2: bottomRight.y };
}; };
var allocate = function(actor, box, flags, useParent) { export const setClip = function(actor, x, y, width, height) {
let allocateObj = useParent ? actor.__proto__ : actor;
allocateObj.allocate.apply(actor, getAllocationParams(box, flags));
};
var setAllocation = function(actor, box, flags) {
actor.set_allocation.apply(actor, getAllocationParams(box, flags));
};
var getAllocationParams = function(box, flags) {
let params = [box];
if (Config.PACKAGE_VERSION < '3.37') {
params.push(flags);
}
return params;
};
var setClip = function(actor, x, y, width, height) {
actor.set_clip(0, 0, width, height); actor.set_clip(0, 0, width, height);
actor.set_position(x, y); actor.set_position(x, y);
actor.set_size(width, height); actor.set_size(width, height);
}; };
var addKeybinding = function(key, settings, handler, modes) { export const addKeybinding = function(key, settings, handler, modes) {
if (!Main.wm._allowedKeybindings[key]) { if (!Main.wm._allowedKeybindings[key]) {
Main.wm.addKeybinding( Main.wm.addKeybinding(
key, key,
@@ -408,19 +311,19 @@ var addKeybinding = function(key, settings, handler, modes) {
} }
}; };
var removeKeybinding = function(key) { export const removeKeybinding = function(key) {
if (Main.wm._allowedKeybindings[key]) { if (Main.wm._allowedKeybindings[key]) {
Main.wm.removeKeybinding(key); Main.wm.removeKeybinding(key);
} }
}; };
var getrgbColor = function(color) { export const getrgbColor = function(color) {
color = typeof color === 'string' ? Clutter.color_from_string(color)[1] : color; color = typeof color === 'string' ? ColorUtils.color_from_string(color)[1] : color;
return { red: color.red, green: color.green, blue: color.blue }; return { red: color.red, green: color.green, blue: color.blue };
}; };
var getrgbaColor = function(color, alpha, offset) { export const getrgbaColor = function(color, alpha, offset) {
if (alpha <= 0) { if (alpha <= 0) {
return 'transparent; '; return 'transparent; ';
} }
@@ -440,14 +343,14 @@ var getrgbaColor = function(color, alpha, offset) {
return 'rgba(' + rgb.red + ',' + rgb.green + ',' + rgb.blue + ',' + (Math.floor(alpha * 100) * 0.01) + '); ' ; return 'rgba(' + rgb.red + ',' + rgb.green + ',' + rgb.blue + ',' + (Math.floor(alpha * 100) * 0.01) + '); ' ;
}; };
var checkIfColorIsBright = function(color) { export const checkIfColorIsBright = function(color) {
let rgb = getrgbColor(color); let rgb = getrgbColor(color);
let brightness = 0.2126 * rgb.red + 0.7152 * rgb.green + 0.0722 * rgb.blue; let brightness = 0.2126 * rgb.red + 0.7152 * rgb.green + 0.0722 * rgb.blue;
return brightness > 128; return brightness > 128;
}; };
var getMouseScrollDirection = function(event) { export const getMouseScrollDirection = function(event) {
let direction; let direction;
switch (event.get_scroll_direction()) { switch (event.get_scroll_direction()) {
@@ -464,7 +367,7 @@ var getMouseScrollDirection = function(event) {
return direction; return direction;
}; };
var checkIfWindowHasTransient = function(window) { export const checkIfWindowHasTransient = function(window) {
let hasTransient; let hasTransient;
window.foreach_transient(t => !(hasTransient = true)); window.foreach_transient(t => !(hasTransient = true));
@@ -472,11 +375,11 @@ var checkIfWindowHasTransient = function(window) {
return hasTransient; return hasTransient;
}; };
var activateSiblingWindow = function(windows, direction, startWindow) { export const activateSiblingWindow = function(windows, direction, startWindow) {
let windowIndex = windows.indexOf(global.display.focus_window); let windowIndex = windows.indexOf(global.display.focus_window);
let nextWindowIndex = windowIndex < 0 ? let nextWindowIndex = windowIndex < 0 ?
startWindow ? windows.indexOf(startWindow) : 0 : startWindow ? windows.indexOf(startWindow) : 0 :
windowIndex + (direction == 'up' ? 1 : -1); windowIndex + (direction == 'up' ? -1 : 1);
if (nextWindowIndex == windows.length) { if (nextWindowIndex == windows.length) {
nextWindowIndex = 0; nextWindowIndex = 0;
@@ -489,49 +392,39 @@ var activateSiblingWindow = function(windows, direction, startWindow) {
} }
}; };
var animateWindowOpacity = function(window, tweenOpts) { export const animateWindowOpacity = function(window, tweenOpts) {
//there currently is a mutter bug with the windowactor opacity, starting with 3.34 //there currently is a mutter bug with the windowactor opacity, starting with 3.34
//https://gitlab.gnome.org/GNOME/mutter/issues/836 //https://gitlab.gnome.org/GNOME/mutter/issues/836
if (Config.PACKAGE_VERSION > '3.35') { //since 3.36, a workaround is to use the windowactor's child for the fade animation
//on 3.36, a workaround is to use the windowactor's child for the fade animation //this leaves a "shadow" on the desktop, so the windowactor needs to be hidden
//this leaves a "shadow" on the desktop, so the windowactor needs to be hidden //when the animation is complete
//when the animation is complete let visible = tweenOpts.opacity > 0;
let visible = tweenOpts.opacity > 0; let windowActor = window;
let windowActor = window; let initialOpacity = window.opacity;
window = windowActor.get_first_child() || windowActor;
if (!windowActor.visible && visible) { window = windowActor.get_first_child() || windowActor;
window.opacity = 0;
windowActor.visible = visible;
}
if (!visible) {
let initialOpacity = window.opacity;
tweenOpts.onComplete = () => { if (!windowActor.visible && visible) {
windowActor.visible = visible; window.opacity = 0;
window.opacity = initialOpacity; windowActor.visible = visible;
}; tweenOpts.opacity = Math.min(initialOpacity, tweenOpts.opacity);
} }
} else if (Config.PACKAGE_VERSION > '3.33') {
//the workaround only works on 3.35+, so on 3.34, let's just hide the if (!visible) {
//window without animation tweenOpts.onComplete = () => {
return window.visible = (tweenOpts.opacity == 255); windowActor.visible = visible;
window.opacity = initialOpacity;
};
} }
animate(window, tweenOpts); animate(window, tweenOpts);
}; };
var animate = function(actor, options) { export const animate = function(actor, options) {
if (Tweener) { //the original animations used Tweener instead of Clutter animations, so we
return Tweener.addTween(actor, options); //use "time" and "delay" properties defined in seconds, as opposed to Clutter
} //animations "duration" and "delay" which are defined in milliseconds
//to support both Tweener and Clutter animations, we use Tweener "time"
//and "delay" properties defined in seconds, as opposed to Clutter animations
//"duration" and "delay" which are defined in milliseconds
if (options.delay) { if (options.delay) {
options.delay = options.delay * 1000; options.delay = options.delay * 1000;
} }
@@ -561,23 +454,15 @@ var animate = function(actor, options) {
actor.ease.apply(actor, params); actor.ease.apply(actor, params);
} }
var isAnimating = function(actor, prop) { export const isAnimating = function(actor, prop) {
if (Tweener) {
return Tweener.isTweening(actor);
}
return !!actor.get_transition(prop); return !!actor.get_transition(prop);
} }
var stopAnimations = function(actor) { export const stopAnimations = function(actor) {
if (Tweener) {
return Tweener.removeTweens(actor);
}
actor.remove_all_transitions(); actor.remove_all_transitions();
} }
var getIndicators = function(delegate) { export const getIndicators = function(delegate) {
if (delegate instanceof St.BoxLayout) { if (delegate instanceof St.BoxLayout) {
return delegate; return delegate;
} }
@@ -585,23 +470,11 @@ var getIndicators = function(delegate) {
return delegate.indicators; return delegate.indicators;
} }
var getPoint = function(coords) { export const getPoint = function(coords) {
if (Config.PACKAGE_VERSION > '3.35.1') { return new Graphene.Point(coords);
return new imports.gi.Graphene.Point(coords);
}
return new Clutter.Point(coords);
} }
var getPanelGhost = function() { export const notify = function(text, iconName, action, isTransient) {
if (!Main.overview._panelGhost) {
return Main.overview._overview.get_first_child();
}
return Main.overview._panelGhost;
}
var notify = function(text, iconName, action, isTransient) {
let source = new MessageTray.SystemNotificationSource(); let source = new MessageTray.SystemNotificationSource();
let notification = new MessageTray.Notification(source, 'Dash to Panel', text); let notification = new MessageTray.Notification(source, 'Dash to Panel', text);
let notifyFunc = source.showNotification || source.notify; let notifyFunc = source.showNotification || source.notify;
@@ -632,9 +505,9 @@ var notify = function(text, iconName, action, isTransient) {
* it would be clamp to the current one in any case. * it would be clamp to the current one in any case.
* Return the amount of shift applied * Return the amount of shift applied
*/ */
var ensureActorVisibleInScrollView = function(scrollView, actor, fadeSize, onComplete) { export const ensureActorVisibleInScrollView = function(scrollView, actor, fadeSize, onComplete) {
let vadjustment = scrollView.vscroll.adjustment; const vadjustment = scrollView.vadjustment;
let hadjustment = scrollView.hscroll.adjustment; const hadjustment = scrollView.hadjustment;
let [vvalue, vlower, vupper, vstepIncrement, vpageIncrement, vpageSize] = vadjustment.get_values(); let [vvalue, vlower, vupper, vstepIncrement, vpageIncrement, vpageSize] = vadjustment.get_values();
let [hvalue, hlower, hupper, hstepIncrement, hpageIncrement, hpageSize] = hadjustment.get_values(); let [hvalue, hlower, hupper, hstepIncrement, hpageIncrement, hpageSize] = hadjustment.get_values();
@@ -689,8 +562,13 @@ var ensureActorVisibleInScrollView = function(scrollView, actor, fadeSize, onCom
/** /**
* ColorUtils is adapted from https://github.com/micheleg/dash-to-dock * ColorUtils is adapted from https://github.com/micheleg/dash-to-dock
*/ */
var ColorUtils = { let colorNs = Clutter.Color ? Clutter : Cogl
colorLuminance: function(r, g, b, dlum) {
export const ColorUtils = {
color_from_string: colorNs.color_from_string,
Color: colorNs.Color,
colorLuminance(r, g, b, dlum) {
// Darken or brighten color by a fraction dlum // Darken or brighten color by a fraction dlum
// Each rgb value is modified by the same fraction. // Each rgb value is modified by the same fraction.
// Return "#rrggbb" strin // Return "#rrggbb" strin
@@ -704,7 +582,7 @@ var ColorUtils = {
return rgbString; return rgbString;
}, },
_decimalToHex: function(d, padding) { _decimalToHex(d, padding) {
// Convert decimal to an hexadecimal string adding the desired padding // Convert decimal to an hexadecimal string adding the desired padding
let hex = d.toString(16); let hex = d.toString(16);
@@ -713,7 +591,7 @@ var ColorUtils = {
return hex; return hex;
}, },
HSVtoRGB: function(h, s, v) { HSVtoRGB(h, s, v) {
// Convert hsv ([0-1, 0-1, 0-1]) to rgb ([0-255, 0-255, 0-255]). // Convert hsv ([0-1, 0-1, 0-1]) to rgb ([0-255, 0-255, 0-255]).
// Following algorithm in https://en.wikipedia.org/wiki/HSL_and_HSV // Following algorithm in https://en.wikipedia.org/wiki/HSL_and_HSV
// here with h = [0,1] instead of [0, 360] // here with h = [0,1] instead of [0, 360]
@@ -752,7 +630,7 @@ var ColorUtils = {
}; };
}, },
RGBtoHSV: function(r, g, b) { RGBtoHSV(r, g, b) {
// Convert rgb ([0-255, 0-255, 0-255]) to hsv ([0-1, 0-1, 0-1]). // Convert rgb ([0-255, 0-255, 0-255]) to hsv ([0-1, 0-1, 0-1]).
// Following algorithm in https://en.wikipedia.org/wiki/HSL_and_HSV // Following algorithm in https://en.wikipedia.org/wiki/HSL_and_HSV
// here with h = [0,1] instead of [0, 360] // here with h = [0,1] instead of [0, 360]
@@ -800,24 +678,20 @@ const MAX_CACHED_ITEMS = 1000;
const BATCH_SIZE_TO_DELETE = 50; const BATCH_SIZE_TO_DELETE = 50;
const DOMINANT_COLOR_ICON_SIZE = 64; const DOMINANT_COLOR_ICON_SIZE = 64;
var DominantColorExtractor = defineClass({ export const DominantColorExtractor = class {
Name: 'ZorinTaskbar.DominantColorExtractor',
_init: function(app){ constructor(app){
this._app = app; this._app = app;
}, }
/** /**
* Try to get the pixel buffer for the current icon, if not fail gracefully * Try to get the pixel buffer for the current icon, if not fail gracefully
*/ */
_getIconPixBuf: function() { _getIconPixBuf() {
let iconTexture = this._app.create_icon_texture(16); let iconTexture = this._app.create_icon_texture(16);
if (themeLoader === null) { if (themeLoader === null) {
let ifaceSettings = new Gio.Settings({ schema: "org.gnome.desktop.interface" }); themeLoader = new St.IconTheme();
themeLoader = new Gtk.IconTheme(),
themeLoader.set_custom_theme(ifaceSettings.get_string('icon-theme')); // Make sure the correct theme is loaded
} }
// Unable to load the icon texture, use fallback // Unable to load the icon texture, use fallback
@@ -838,12 +712,17 @@ var DominantColorExtractor = defineClass({
} }
// Get the pixel buffer from the icon theme // Get the pixel buffer from the icon theme
let icon_info = themeLoader.lookup_icon(iconTexture.get_names()[0], DOMINANT_COLOR_ICON_SIZE, 0); if (iconTexture instanceof Gio.ThemedIcon) {
if (icon_info !== null) let icon_info = themeLoader.lookup_icon(iconTexture.get_names()[0],
return icon_info.load_icon(); DOMINANT_COLOR_ICON_SIZE, 0);
else
return null; if (icon_info !== null) {
}, return icon_info.load_icon();
}
}
return null;
}
/** /**
* The backlight color choosing algorithm was mostly ported to javascript from the * The backlight color choosing algorithm was mostly ported to javascript from the
@@ -851,7 +730,7 @@ var DominantColorExtractor = defineClass({
* https://bazaar.launchpad.net/~unity-team/unity/trunk/view/head:/launcher/LauncherIcon.cpp * https://bazaar.launchpad.net/~unity-team/unity/trunk/view/head:/launcher/LauncherIcon.cpp
* so it more or less works the same way. * so it more or less works the same way.
*/ */
_getColorPalette: function() { _getColorPalette() {
if (iconCacheMap.get(this._app.get_id())) { if (iconCacheMap.get(this._app.get_id())) {
// We already know the answer // We already know the answer
return iconCacheMap.get(this._app.get_id()); return iconCacheMap.get(this._app.get_id());
@@ -944,7 +823,7 @@ var DominantColorExtractor = defineClass({
iconCacheMap.set(this._app.get_id(), backgroundColor); iconCacheMap.set(this._app.get_id(), backgroundColor);
return backgroundColor; return backgroundColor;
}, }
/** /**
* Downsample large icons before scanning for the backlight color to * Downsample large icons before scanning for the backlight color to
@@ -957,7 +836,7 @@ var DominantColorExtractor = defineClass({
* *
* @return []; * @return [];
*/ */
_resamplePixels: function (pixels, resampleX, resampleY) { _resamplePixels(pixels, resampleX, resampleY) {
let resampledPixels = []; let resampledPixels = [];
// computing the limit outside the for (where it would be repeated at each iteration) // computing the limit outside the for (where it would be repeated at each iteration)
// for performance reasons // for performance reasons
@@ -974,9 +853,9 @@ var DominantColorExtractor = defineClass({
return resampledPixels; return resampledPixels;
} }
}); };
var drawRoundedLine = function(cr, x, y, width, height, isRoundLeft, isRoundRight, stroke, fill) { export const drawRoundedLine = function(cr, x, y, width, height, isRoundLeft, isRoundRight, stroke, fill) {
if (height > width) { if (height > width) {
y += Math.floor((height - width) / 2.0); y += Math.floor((height - width) / 2.0);
height = width; height = width;
@@ -984,8 +863,8 @@ var drawRoundedLine = function(cr, x, y, width, height, isRoundLeft, isRoundRigh
height = 2.0 * Math.floor(height / 2.0); height = 2.0 * Math.floor(height / 2.0);
var leftRadius = isRoundLeft ? height / 2.0 : 0.0; const leftRadius = isRoundLeft ? height / 2.0 : 0.0;
var rightRadius = isRoundRight ? height / 2.0 : 0.0; const rightRadius = isRoundRight ? height / 2.0 : 0.0;
cr.moveTo(x + width - rightRadius, y); cr.moveTo(x + width - rightRadius, y);
cr.lineTo(x + leftRadius, y); cr.lineTo(x + leftRadius, y);
@@ -1008,28 +887,3 @@ var drawRoundedLine = function(cr, x, y, width, height, isRoundLeft, isRoundRigh
cr.setSource(stroke); cr.setSource(stroke);
cr.stroke(); cr.stroke();
} }
/**
* Check if an app exists in the system.
*/
var checkedCommandsMap = new Map();
function checkIfCommandExists(app) {
let answer = checkedCommandsMap.get(app);
if (answer === undefined) {
// Command is a shell built in, use shell to call it.
// Quotes around app value are important. They let command operate
// on the whole value, instead of having shell interpret it.
let cmd = "sh -c 'command -v \"" + app + "\"'";
try {
let out = GLib.spawn_command_line_sync(cmd);
// out contains 1: stdout, 2: stderr, 3: exit code
answer = out[3] == 0;
} catch (ex) {
answer = false;
}
checkedCommandsMap.set(app, answer);
}
return answer;
}

View File

@@ -18,23 +18,19 @@
* This file is based on code from the Dash to Panel extension * This file is based on code from the Dash to Panel extension
*/ */
const Clutter = imports.gi.Clutter; import GObject from 'gi://GObject';
const Config = imports.misc.config; import Clutter from 'gi://Clutter';
const GLib = imports.gi.GLib; import GLib from 'gi://GLib';
const Gtk = imports.gi.Gtk; import Graphene from 'gi://Graphene';
const Main = imports.ui.main; import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const Mainloop = imports.mainloop; import Meta from 'gi://Meta';
const Meta = imports.gi.Meta; import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
const PopupMenu = imports.ui.popupMenu; import St from 'gi://St';
const Signals = imports.signals;
const St = imports.gi.St;
const WindowManager = imports.ui.windowManager;
const Workspace = imports.ui.workspace;
const Me = imports.misc.extensionUtils.getCurrentExtension(); import * as Taskbar from './taskbar.js';
const Panel = Me.imports.panel; import * as Utils from './utils.js';
const Taskbar = Me.imports.taskbar; import {SETTINGS} from './extension.js';
const Utils = Me.imports.utils; import {gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
//timeout intervals //timeout intervals
const ENSURE_VISIBLE_MS = 200; const ENSURE_VISIBLE_MS = 200;
@@ -55,14 +51,14 @@ const PEEK_INDEX_PROP = '_dtpPeekInitialIndex';
const MARGIN_SIZE = 8; const MARGIN_SIZE = 8;
const SHOW_WINDOW_PREVIEWS_TIMEOUT = 400; const SHOW_WINDOW_PREVIEWS_TIMEOUT = 400;
const ENTER_PEEK_MODE_TIMEOUT = 500; const LEAVE_TIMEOUT = 250;
const LEAVE_TIMEOUT = 100;
const WINDOW_PREVIEW_ANIMATION_TIME = 200; const WINDOW_PREVIEW_ANIMATION_TIME = 200;
const WINDOW_PREVIEW_ASPECT_RATIO_X = 16; const WINDOW_PREVIEW_ASPECT_RATIO_X = 16;
const WINDOW_PREVIEW_FIXED_X = false; const WINDOW_PREVIEW_FIXED_X = false;
const WINDOW_PREVIEW_ASPECT_RATIO_Y = 9; const WINDOW_PREVIEW_ASPECT_RATIO_Y = 9;
const WINDOW_PREVIEW_FIXED_Y = true; const WINDOW_PREVIEW_FIXED_Y = true;
const WINDOW_PREVIEW_PADDING = 8; const WINDOW_PREVIEW_PADDING = 8;
const ENTER_PEEK_MODE_TIMEOUT = 500;
const PEEK_MODE_OPACITY = 40; const PEEK_MODE_OPACITY = 40;
let headerHeight = 0; let headerHeight = 0;
@@ -73,19 +69,19 @@ let scaleFactor = 1;
let animationTime = 0; let animationTime = 0;
let aspectRatio = {}; let aspectRatio = {};
var PreviewMenu = Utils.defineClass({ export const PreviewMenu = GObject.registerClass({
Name: 'ZorinTaskbar-PreviewMenu', Signals: { 'open-state-changed': {} }
Extends: St.Widget, }, class PreviewMenu extends St.Widget {
Signals: { 'open-state-changed': {} },
_init: function(panel) { _init(panel) {
this.callParent('_init', { layout_manager: new Clutter.BinLayout() }); super._init({ layout_manager: new Clutter.BinLayout() });
let geom = panel.geom; let geom = panel.geom;
this.panel = panel; this.panel = panel;
this.currentAppIcon = null; this.currentAppIcon = null;
this._focusedPreview = null; this._focusedPreview = null;
this._peekedWindow = null; this._peekedWindow = null;
this.allowCloseWindow = true;
this.peekInitialWorkspaceIndex = -1; this.peekInitialWorkspaceIndex = -1;
this.opened = false; this.opened = false;
this.isVertical = geom.position == St.Side.LEFT || geom.position == St.Side.RIGHT; this.isVertical = geom.position == St.Side.LEFT || geom.position == St.Side.RIGHT;
@@ -107,18 +103,18 @@ var PreviewMenu = Utils.defineClass({
this._box = new St.BoxLayout({ vertical: this.isVertical }); this._box = new St.BoxLayout({ vertical: this.isVertical });
this._scrollView = new St.ScrollView({ this._scrollView = new St.ScrollView({
name: 'zorintaskbarPreviewScrollview', name: 'zorintaskbarPreviewScrollview',
hscrollbar_policy: Gtk.PolicyType.NEVER, hscrollbar_policy: St.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.NEVER, vscrollbar_policy: St.PolicyType.NEVER,
enable_mouse_scrolling: true, enable_mouse_scrolling: true,
y_expand: !this.isVertical y_expand: !this.isVertical
}); });
this._scrollView.add_actor(this._box); this._scrollView.add_child(this._box);
this.menu.add_child(this._scrollView); this.menu.add_child(this._scrollView);
this.add_child(this.menu); this.add_child(this.menu);
}, }
enable: function() { enable() {
this._timeoutsHandler = new Utils.TimeoutsHandler(); this._timeoutsHandler = new Utils.TimeoutsHandler();
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler();
@@ -156,9 +152,9 @@ var PreviewMenu = Utils.defineClass({
} }
], ],
[ [
Me.settings, SETTINGS,
[ [
'changed::panel-size', 'changed::panel-sizes',
'changed::window-preview-size' 'changed::window-preview-size'
], ],
() => { () => {
@@ -167,9 +163,9 @@ var PreviewMenu = Utils.defineClass({
} }
] ]
); );
}, }
disable: function() { disable() {
this._timeoutsHandler.destroy(); this._timeoutsHandler.destroy();
this._signalsHandler.destroy(); this._signalsHandler.destroy();
@@ -177,9 +173,9 @@ var PreviewMenu = Utils.defineClass({
Main.layoutManager.untrackChrome(this.menu); Main.layoutManager.untrackChrome(this.menu);
Main.layoutManager.removeChrome(this); Main.layoutManager.removeChrome(this);
}, }
requestOpen: function(appIcon) { requestOpen(appIcon) {
let timeout = SHOW_WINDOW_PREVIEWS_TIMEOUT; let timeout = SHOW_WINDOW_PREVIEWS_TIMEOUT;
if (this.opened) { if (this.opened) {
@@ -188,23 +184,24 @@ var PreviewMenu = Utils.defineClass({
this._endOpenCloseTimeouts(); this._endOpenCloseTimeouts();
this._timeoutsHandler.add([T1, timeout, () => this.open(appIcon)]); this._timeoutsHandler.add([T1, timeout, () => this.open(appIcon)]);
}, }
requestClose: function() { requestClose() {
this._endOpenCloseTimeouts(); this._endOpenCloseTimeouts();
this._addCloseTimeout(); this._addCloseTimeout();
}, }
open: function(appIcon) { open(appIcon, preventCloseWindow) {
if (this.currentAppIcon != appIcon) { if (this.currentAppIcon != appIcon) {
this.currentAppIcon = appIcon; this.currentAppIcon = appIcon;
this.allowCloseWindow = !preventCloseWindow;
if (!this.opened) { if (!this.opened) {
this._refreshGlobals(); this._refreshGlobals();
this.set_height(this.clipHeight); this.set_height(this.clipHeight);
this.menu.show(); this.menu.show();
setStyle(this.menu, 'padding: 0; margin: 0; border: none; background-image: none;'); setStyle(this.menu, 'padding: 0; margin: 0; border: none; background-image: none;');
} }
@@ -215,9 +212,9 @@ var PreviewMenu = Utils.defineClass({
this._setReactive(true); this._setReactive(true);
this._setOpenedState(true); this._setOpenedState(true);
} }
}, }
close: function(immediate) { close(immediate) {
this._endOpenCloseTimeouts(); this._endOpenCloseTimeouts();
this._removeFocus(); this._removeFocus();
this._endPeek(); this._endPeek();
@@ -231,9 +228,9 @@ var PreviewMenu = Utils.defineClass({
this._setReactive(false); this._setReactive(false);
this.currentAppIcon = null; this.currentAppIcon = null;
}, }
update: function(appIcon, windows) { update(appIcon, windows) {
if (this.currentAppIcon == appIcon) { if (this.currentAppIcon == appIcon) {
if (windows && !windows.length) { if (windows && !windows.length) {
this.close(); this.close();
@@ -242,13 +239,13 @@ var PreviewMenu = Utils.defineClass({
this._updatePosition(); this._updatePosition();
} }
} }
}, }
updatePosition: function() { updatePosition() {
this._updatePosition(); this._updatePosition();
}, }
focusNext: function() { focusNext() {
let previews = this._box.get_children(); let previews = this._box.get_children();
let currentIndex = this._focusedPreview ? previews.indexOf(this._focusedPreview) : -1; let currentIndex = this._focusedPreview ? previews.indexOf(this._focusedPreview) : -1;
let nextIndex = currentIndex + 1; let nextIndex = currentIndex + 1;
@@ -262,31 +259,31 @@ var PreviewMenu = Utils.defineClass({
} }
return nextIndex; return nextIndex;
}, }
activateFocused: function() { activateFocused() {
if (this.opened && this._focusedPreview) { if (this.opened && this._focusedPreview) {
this._focusedPreview.activate(); this._focusedPreview.activate();
} }
}, }
requestPeek: function(window) { requestPeek(window) {
this._timeoutsHandler.remove(T3); this._timeoutsHandler.remove(T3);
if (Me.settings.get_boolean('peek-mode')) { if (SETTINGS.get_boolean('peek-mode')) {
if (this.peekInitialWorkspaceIndex < 0) { if (this.peekInitialWorkspaceIndex < 0) {
this._timeoutsHandler.add([T3, ENTER_PEEK_MODE_TIMEOUT, () => this._peek(window)]); this._timeoutsHandler.add([T3, ENTER_PEEK_MODE_TIMEOUT, () => this._peek(window)]);
} else { } else {
this._peek(window); this._peek(window);
} }
} }
}, }
endPeekHere: function() { endPeekHere() {
this._endPeek(true); this._endPeek(true);
}, }
ensureVisible: function(preview) { ensureVisible(preview) {
let [ , upper, pageSize] = this._getScrollAdjustmentValues(); let [ , upper, pageSize] = this._getScrollAdjustmentValues();
if (upper > pageSize) { if (upper > pageSize) {
@@ -296,39 +293,39 @@ var PreviewMenu = Utils.defineClass({
() => Utils.ensureActorVisibleInScrollView(this._scrollView, preview, MIN_DIMENSION, () => this._updateScrollFade()) () => Utils.ensureActorVisibleInScrollView(this._scrollView, preview, MIN_DIMENSION, () => this._updateScrollFade())
]); ]);
} }
}, }
getCurrentAppIcon: function() { getCurrentAppIcon() {
return this.currentAppIcon; return this.currentAppIcon;
}, }
_setReactive: function(reactive) {  _setReactive(reactive) {
this._box.get_children().forEach(c => c.reactive = reactive); this._box.get_children().forEach(c => c.reactive = reactive);
this.menu.reactive = reactive; this.menu.reactive = reactive;
}, }
_setOpenedState: function(opened) { _setOpenedState(opened) {
this.opened = opened; this.opened = opened;
this.emit('open-state-changed'); this.emit('open-state-changed');
}, }
_resetHiddenState: function() { _resetHiddenState() {
this.menu.hide(); this.menu.hide();
this.set_height(0); this.set_height(0);
this._setOpenedState(false); this._setOpenedState(false);
this.menu.opacity = 0; this.menu.opacity = 0;
this.menu[this._translationProp] = this._translationOffset; this.menu[this._translationProp] = this._translationOffset;
this._box.get_children().forEach(c => c.destroy()); this._box.get_children().forEach(c => c.destroy());
}, }
_removeFocus: function() { _removeFocus() {
if (this._focusedPreview) { if (this._focusedPreview) {
this._focusedPreview.setFocus(false); this._focusedPreview.setFocus(false);
this._focusedPreview = null; this._focusedPreview = null;
} }
}, }
_mergeWindows: function(appIcon, windows) { _mergeWindows(appIcon, windows) {
windows = windows || (appIcon.window ? [appIcon.window] : appIcon.getAppIconInterestingWindows()); windows = windows || (appIcon.window ? [appIcon.window] : appIcon.getAppIconInterestingWindows());
windows.sort(Taskbar.sortWindowsCompareFunction); windows.sort(Taskbar.sortWindowsCompareFunction);
@@ -344,9 +341,9 @@ var PreviewMenu = Utils.defineClass({
currentPreviews[i][!this.opened ? 'destroy' : 'animateOut'](); currentPreviews[i][!this.opened ? 'destroy' : 'animateOut']();
} }
} }
}, }
_addAndRemoveWindows: function(windows) { _addAndRemoveWindows(windows) {
let currentPreviews = this._box.get_children(); let currentPreviews = this._box.get_children();
windows.sort(Taskbar.sortWindowsCompareFunction); windows.sort(Taskbar.sortWindowsCompareFunction);
@@ -367,30 +364,34 @@ var PreviewMenu = Utils.defineClass({
} }
currentPreviews.forEach(c => c.animateOut()); currentPreviews.forEach(c => c.animateOut());
}, }
_addNewPreview: function(window) { _addNewPreview(window) {
let preview = new Preview(this); let preview = new Preview(this);
this._box.add_child(preview); this._box.add_child(preview);
preview.adjustOnStage(); preview.adjustOnStage();
preview.assignWindow(window, this.opened); preview.assignWindow(window, this.opened);
}, }
_addCloseTimeout: function() { _addCloseTimeout() {
this._timeoutsHandler.add([T2, LEAVE_TIMEOUT, () => this.close()]); this._timeoutsHandler.add([T2, LEAVE_TIMEOUT, () => this.close()]);
}, }
_onHoverChanged: function() { _onHoverChanged() {
this._endOpenCloseTimeouts(); this._endOpenCloseTimeouts();
if (this.currentAppIcon && !this.menu.hover) { if (this.currentAppIcon) {
this._addCloseTimeout(); this.menu.sync_hover(); // See dash-to-panel issue #2169
this._endPeek();
if (!this.menu.hover) {
this._addCloseTimeout();
this._endPeek();
}
} }
}, }
_onScrollEvent: function(actor, event) { _onScrollEvent(actor, event) {
if (!event.is_pointer_emulated()) { if (!event.is_pointer_emulated()) {
let vOrh = this.isVertical ? 'v' : 'h'; let vOrh = this.isVertical ? 'v' : 'h';
let adjustment = this._scrollView['get_' + vOrh + 'scroll_bar']().get_adjustment(); let adjustment = this._scrollView['get_' + vOrh + 'scroll_bar']().get_adjustment();
@@ -413,15 +414,15 @@ var PreviewMenu = Utils.defineClass({
} }
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
}, }
_endOpenCloseTimeouts: function() { _endOpenCloseTimeouts() {
this._timeoutsHandler.remove(T1); this._timeoutsHandler.remove(T1);
this._timeoutsHandler.remove(T2); this._timeoutsHandler.remove(T2);
this._timeoutsHandler.remove(T4); this._timeoutsHandler.remove(T4);
}, }
_refreshGlobals: function() { _refreshGlobals() {
isLeftButtons = Meta.prefs_get_button_layout().left_buttons.indexOf(Meta.ButtonFunction.CLOSE) >= 0; isLeftButtons = Meta.prefs_get_button_layout().left_buttons.indexOf(Meta.ButtonFunction.CLOSE) >= 0;
scaleFactor = Utils.getScaleFactor(); scaleFactor = Utils.getScaleFactor();
headerHeight = HEADER_HEIGHT * scaleFactor; headerHeight = HEADER_HEIGHT * scaleFactor;
@@ -436,14 +437,13 @@ var PreviewMenu = Utils.defineClass({
}; };
alphaBg = this._getThemeBackground().alpha; alphaBg = this._getThemeBackground().alpha;
}, }
_updateClip: function() { _updateClip() {
let x, y, w; let x, y, w;
let geom = this.panel.getGeometry(); let geom = this.panel.getGeometry();
let panelBoxTheme = this.panel.panelBox.get_theme_node(); let panelBoxTheme = this.panel.panelBox.get_theme_node();
let themeBackground = this._getThemeBackground(true); let previewSize = (SETTINGS.get_int('window-preview-size') +
let previewSize = (Me.settings.get_int('window-preview-size') +
WINDOW_PREVIEW_PADDING * 2) * scaleFactor; WINDOW_PREVIEW_PADDING * 2) * scaleFactor;
if (this.isVertical) { if (this.isVertical) {
@@ -467,12 +467,12 @@ var PreviewMenu = Utils.defineClass({
} }
Utils.setClip(this, x, y, w, this.clipHeight); Utils.setClip(this, x, y, w, this.clipHeight);
}, }
_updatePosition: function() { _updatePosition() {
let sourceNode = this.currentAppIcon.actor.get_theme_node(); let sourceNode = this.currentAppIcon.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(this.currentAppIcon.actor.get_allocation_box()); let sourceContentBox = sourceNode.get_content_box(this.currentAppIcon.get_allocation_box());
let sourceAllocation = Utils.getTransformedAllocation(this.currentAppIcon.actor); let sourceAllocation = Utils.getTransformedAllocation(this.currentAppIcon);
let [previewsWidth, previewsHeight] = this._getPreviewsSize(); let [previewsWidth, previewsHeight] = this._getPreviewsSize();
let appIconMargin = Taskbar.APPICON_MARGIN / scaleFactor; let appIconMargin = Taskbar.APPICON_MARGIN / scaleFactor;
let x = 0, y = 0; let x = 0, y = 0;
@@ -497,9 +497,9 @@ var PreviewMenu = Utils.defineClass({
} else { } else {
Utils.animate(this.menu, getTweenOpts({ x: x, y: y, width: previewsWidth, height: previewsHeight })); Utils.animate(this.menu, getTweenOpts({ x: x, y: y, width: previewsWidth, height: previewsHeight }));
} }
}, }
_updateScrollFade: function(remove) { _updateScrollFade(remove) {
let [value, upper, pageSize] = this._getScrollAdjustmentValues(); let [value, upper, pageSize] = this._getScrollAdjustmentValues();
let needsFade = Math.round(upper) > Math.round(pageSize); let needsFade = Math.round(upper) > Math.round(pageSize);
let fadeWidgets = this.menu.get_children().filter(c => c != this._scrollView); let fadeWidgets = this.menu.get_children().filter(c => c != this._scrollView);
@@ -518,15 +518,15 @@ var PreviewMenu = Utils.defineClass({
} else if (remove || (!needsFade && fadeWidgets.length)) { } else if (remove || (!needsFade && fadeWidgets.length)) {
fadeWidgets.forEach(fw => fw.destroy()); fadeWidgets.forEach(fw => fw.destroy());
} }
}, }
_getScrollAdjustmentValues: function() { _getScrollAdjustmentValues() {
let [value , , upper, , , pageSize] = this._scrollView[(this.isVertical ? 'v' : 'h') + 'scroll'].adjustment.get_values(); let [value , , upper, , , pageSize] = this._scrollView[(this.isVertical ? 'v' : 'h') + 'adjustment'].get_values();
return [value, upper, pageSize]; return [value, upper, pageSize];
}, }
_getFadeWidget: function(end) { _getFadeWidget(end) {
let x = 0, y = 0; let x = 0, y = 0;
let startBg = Utils.getrgbaColor(this._getThemeBackground(), Math.min(alphaBg + .1, 1)); let startBg = Utils.getrgbaColor(this._getThemeBackground(), Math.min(alphaBg + .1, 1));
let endBg = Utils.getrgbaColor(this._getThemeBackground(), 0) let endBg = Utils.getrgbaColor(this._getThemeBackground(), 0)
@@ -542,7 +542,7 @@ var PreviewMenu = Utils.defineClass({
let fadeWidget = new St.Widget({ let fadeWidget = new St.Widget({
reactive: false, reactive: false,
pivot_point: Utils.getPoint({ x: .5, y: .5 }), pivot_point: new Graphene.Point({ x: .5, y: .5 }),
rotation_angle_z: end ? 180 : 0, rotation_angle_z: end ? 180 : 0,
style: fadeStyle, style: fadeStyle,
x: x, y: y, x: x, y: y,
@@ -551,9 +551,9 @@ var PreviewMenu = Utils.defineClass({
}); });
return fadeWidget; return fadeWidget;
}, }
_getPreviewsSize: function() { _getPreviewsSize() {
let previewsWidth = 0; let previewsWidth = 0;
let previewsHeight = 0; let previewsHeight = 0;
@@ -572,9 +572,9 @@ var PreviewMenu = Utils.defineClass({
}); });
return [previewsWidth, previewsHeight]; return [previewsWidth, previewsHeight];
}, }
_getThemeBackground: function(reload) { _getThemeBackground(reload) {
if (reload || !this._themeBackground) { if (reload || !this._themeBackground) {
let fakeTooltip = new St.Bin({ style_class: 'dash-label' }); let fakeTooltip = new St.Bin({ style_class: 'dash-label' });
Main.uiGroup.add_child(fakeTooltip); Main.uiGroup.add_child(fakeTooltip);
@@ -584,9 +584,9 @@ var PreviewMenu = Utils.defineClass({
} }
return this._themeBackground; return this._themeBackground;
}, }
_animateOpenOrClose: function(show, onComplete) { _animateOpenOrClose(show, onComplete) {
let isTranslationAnimation = this.menu[this._translationProp] != 0; let isTranslationAnimation = this.menu[this._translationProp] != 0;
let tweenOpts = { let tweenOpts = {
opacity: show ? 255 : 0, opacity: show ? 255 : 0,
@@ -603,14 +603,19 @@ var PreviewMenu = Utils.defineClass({
tweenOpts[this._translationProp] = show ? this._translationDirection : this._translationOffset; tweenOpts[this._translationProp] = show ? this._translationDirection : this._translationOffset;
Utils.animate(this.menu, getTweenOpts(tweenOpts)); Utils.animate(this.menu, getTweenOpts(tweenOpts));
}, }
_peek: function(window) { _peek(window) {
let currentWorkspace = Utils.getCurrentWorkspace(); let currentWorkspace = Utils.getCurrentWorkspace();
let windowWorkspace = window.get_workspace(); let windowWorkspace = window.get_workspace();
let focusWindow = () => this._focusMetaWindow(PEEK_MODE_OPACITY, window); let focusWindow = () => this._focusMetaWindow(PEEK_MODE_OPACITY, window);
this._restorePeekedWindowStack(); this._restorePeekedWindowStack();
if (this._peekedWindow && windowWorkspace != currentWorkspace) {
currentWorkspace.list_windows().forEach(mw => this.animateWindowOpacity(mw, null, 255))
}
this._peekedWindow = window; this._peekedWindow = window;
if (currentWorkspace != windowWorkspace) { if (currentWorkspace != windowWorkspace) {
@@ -623,9 +628,9 @@ var PreviewMenu = Utils.defineClass({
if (this.peekInitialWorkspaceIndex < 0) { if (this.peekInitialWorkspaceIndex < 0) {
this.peekInitialWorkspaceIndex = currentWorkspace.index(); this.peekInitialWorkspaceIndex = currentWorkspace.index();
} }
}, }
_endPeek: function(stayHere) { _endPeek(stayHere) {
this._timeoutsHandler.remove(T3); this._timeoutsHandler.remove(T3);
if (this._peekedWindow) { if (this._peekedWindow) {
@@ -641,9 +646,9 @@ var PreviewMenu = Utils.defineClass({
this.peekInitialWorkspaceIndex = -1; this.peekInitialWorkspaceIndex = -1;
} }
}, }
_switchToWorkspaceImmediate: function(workspaceIndex) { _switchToWorkspaceImmediate(workspaceIndex) {
let workspace = Utils.getWorkspaceByIndex(workspaceIndex); let workspace = Utils.getWorkspaceByIndex(workspaceIndex);
let shouldAnimate = Main.wm._shouldAnimate; let shouldAnimate = Main.wm._shouldAnimate;
@@ -655,9 +660,9 @@ var PreviewMenu = Utils.defineClass({
Main.wm._shouldAnimate = () => false; Main.wm._shouldAnimate = () => false;
workspace.activate(global.display.get_current_time_roundtrip()); workspace.activate(global.display.get_current_time_roundtrip());
Main.wm._shouldAnimate = shouldAnimate; Main.wm._shouldAnimate = shouldAnimate;
}, }
_focusMetaWindow: function(dimOpacity, window, immediate, ignoreFocus) { _focusMetaWindow(dimOpacity, window, immediate, ignoreFocus) {
window.get_workspace().list_windows().forEach(mw => { window.get_workspace().list_windows().forEach(mw => {
let wa = mw.get_compositor_private(); let wa = mw.get_compositor_private();
let isFocused = !ignoreFocus && mw == window; let isFocused = !ignoreFocus && mw == window;
@@ -671,21 +676,27 @@ var PreviewMenu = Utils.defineClass({
if (isFocused && mw.minimized) { if (isFocused && mw.minimized) {
wa.show(); wa.show();
} }
if (!mw.minimized) { this.animateWindowOpacity(mw, wa, isFocused ? 255 : dimOpacity, immediate)
let tweenOpts = getTweenOpts({ opacity: isFocused ? 255 : dimOpacity });
if (immediate && !mw.is_on_all_workspaces()) {
tweenOpts.time = 0;
}
Utils.animateWindowOpacity(wa, tweenOpts);
}
} }
}); });
}, }
_restorePeekedWindowStack: function() { animateWindowOpacity(metaWindow, windowActor, opacity, immediate) {
windowActor = windowActor || metaWindow.get_compositor_private();
if (windowActor && !metaWindow.minimized) {
let tweenOpts = getTweenOpts({ opacity });
if (immediate && !metaWindow.is_on_all_workspaces()) {
tweenOpts.time = 0;
}
Utils.animateWindowOpacity(windowActor, tweenOpts);
}
}
_restorePeekedWindowStack() {
let windowActor = this._peekedWindow ? this._peekedWindow.get_compositor_private() : null; let windowActor = this._peekedWindow ? this._peekedWindow.get_compositor_private() : null;
if (windowActor) { if (windowActor) {
@@ -698,15 +709,14 @@ var PreviewMenu = Utils.defineClass({
windowActor.hide(); windowActor.hide();
} }
} }
}, }
}); });
var Preview = Utils.defineClass({ export const Preview = GObject.registerClass({
Name: 'ZorinTaskbar-Preview', }, class Preview extends St.Widget {
Extends: St.Widget,
_init: function(previewMenu) { _init(previewMenu) {
this.callParent('_init', { super._init({
style_class: 'preview-container', style_class: 'preview-container',
reactive: true, reactive: true,
track_hover: true, track_hover: true,
@@ -726,9 +736,7 @@ var Preview = Utils.defineClass({
let [previewBinWidth, previewBinHeight] = this._getBinSize(); let [previewBinWidth, previewBinHeight] = this._getBinSize();
let closeButton = new St.Button({ style_class: 'window-close', accessible_name: 'Close window' }); let closeButton = new St.Button({ style_class: 'window-close', accessible_name: 'Close window' });
if (Config.PACKAGE_VERSION >= '3.31.9') { closeButton.add_child(new St.Icon({ icon_name: 'window-close-symbolic' }));
closeButton.add_actor(new St.Icon({ icon_name: 'window-close-symbolic' }));
}
this._closeButtonBin = new St.Widget({ this._closeButtonBin = new St.Widget({
style_class: 'preview-close-btn-container', style_class: 'preview-close-btn-container',
@@ -774,9 +782,9 @@ var Preview = Utils.defineClass({
this.connect('notify::hover', () => this._onHoverChanged()); this.connect('notify::hover', () => this._onHoverChanged());
this.connect('button-release-event', (actor, e) => this._onButtonReleaseEvent(e)); this.connect('button-release-event', (actor, e) => this._onButtonReleaseEvent(e));
this.connect('destroy', () => this._onDestroy()); this.connect('destroy', () => this._onDestroy());
}, }
adjustOnStage: function() { adjustOnStage() {
let closeButton = this._closeButtonBin.get_first_child(); let closeButton = this._closeButtonBin.get_first_child();
let closeButtonHeight = closeButton.height; let closeButtonHeight = closeButton.height;
let maxCloseButtonSize = MAX_CLOSE_BUTTON_SIZE * scaleFactor; let maxCloseButtonSize = MAX_CLOSE_BUTTON_SIZE * scaleFactor;
@@ -802,9 +810,9 @@ var Preview = Utils.defineClass({
'padding: ' + (headerHeight ? Math.round((headerHeight - closeButtonHeight) * .5 / scaleFactor) : 4) + 'px;' + 'padding: ' + (headerHeight ? Math.round((headerHeight - closeButtonHeight) * .5 / scaleFactor) : 4) + 'px;' +
closeButtonBorderRadius closeButtonBorderRadius
); );
}, }
assignWindow: function(window, animateSize) { assignWindow(window, animateSize) {
if (this.window != window) { if (this.window != window) {
let _assignWindowClone = () => { let _assignWindowClone = () => {
if (window.get_compositor_private()) { if (window.get_compositor_private()) {
@@ -814,12 +822,14 @@ var Preview = Utils.defineClass({
this._addClone(cloneBin, animateSize); this._addClone(cloneBin, animateSize);
this._previewMenu.updatePosition(); this._previewMenu.updatePosition();
} else if (!this._waitWindowId) { } else if (!this._waitWindowId) {
this._waitWindowId = Mainloop.idle_add(() => { this._waitWindowId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
this._waitWindowId = 0; this._waitWindowId = 0;
if (this._previewMenu.opened) { if (this._previewMenu.opened) {
_assignWindowClone(); _assignWindowClone();
} }
return GLib.SOURCE_REMOVE;
}); });
} }
}; };
@@ -830,11 +840,11 @@ var Preview = Utils.defineClass({
this._cancelAnimateOut(); this._cancelAnimateOut();
this._removeWindowSignals(); this._removeWindowSignals();
this.window = window; this.window = window;
this._needsCloseButton = window.can_close() && !Utils.checkIfWindowHasTransient(window); this._needsCloseButton = this._previewMenu.allowCloseWindow && window.can_close() && !Utils.checkIfWindowHasTransient(window);
this._updateHeader(); this._updateHeader();
}, }
animateOut: function() { animateOut() {
if (!this.animatingOut) { if (!this.animatingOut) {
let tweenOpts = getTweenOpts({ opacity: 0, width: 0, height: 0, onComplete: () => this.destroy() }); let tweenOpts = getTweenOpts({ opacity: 0, width: 0, height: 0, onComplete: () => this.destroy() });
@@ -843,18 +853,18 @@ var Preview = Utils.defineClass({
Utils.stopAnimations(this); Utils.stopAnimations(this);
Utils.animate(this, tweenOpts); Utils.animate(this, tweenOpts);
} }
}, }
getSize: function() { getSize() {
let [binWidth, binHeight] = this._getBinSize(); let [binWidth, binHeight] = this._getBinSize();
binWidth = Math.max(binWidth, this.cloneWidth + this._padding * 2); binWidth = Math.max(binWidth, this.cloneWidth + this._padding * 2);
binHeight = Math.max(binHeight, this.cloneHeight + this._padding * 2) + headerHeight; binHeight = Math.max(binHeight, this.cloneHeight + this._padding * 2) + headerHeight;
return [binWidth, binHeight]; return [binWidth, binHeight];
}, }
setFocus: function(focused) { setFocus(focused) {
this._hideOrShowCloseButton(!focused); this._hideOrShowCloseButton(!focused);
setStyle(this, this._getBackgroundColor(FOCUSED_COLOR_OFFSET, focused ? '-' : 0)); setStyle(this, this._getBackgroundColor(FOCUSED_COLOR_OFFSET, focused ? '-' : 0));
@@ -862,47 +872,47 @@ var Preview = Utils.defineClass({
this._previewMenu.ensureVisible(this); this._previewMenu.ensureVisible(this);
this._previewMenu.requestPeek(this.window); this._previewMenu.requestPeek(this.window);
} }
}, }
activate: function() { activate() {
this._previewMenu.endPeekHere(); this._previewMenu.endPeekHere();
this._previewMenu.close(); this._previewMenu.close();
Main.activateWindow(this.window); Main.activateWindow(this.window);
}, }
_onDestroy: function() { _onDestroy() {
if (this._waitWindowId) { if (this._waitWindowId) {
GLib.source_remove(this._waitWindowId); GLib.source_remove(this._waitWindowId);
this._waitWindowId = 0; this._waitWindowId = 0;
} }
this._removeWindowSignals(); this._removeWindowSignals();
}, }
_onHoverChanged: function() { _onHoverChanged() {
this.setFocus(this.hover); this.setFocus(this.hover);
}, }
_onCloseBtnClick: function() { _onCloseBtnClick() {
this._hideOrShowCloseButton(true); this._hideOrShowCloseButton(true);
this.reactive = false; this.reactive = false;
if (!Me.settings.get_boolean('group-apps')) { if (!SETTINGS.get_boolean('group-apps')) {
this._previewMenu.close(); this._previewMenu.close();
} else { } else {
this._previewMenu.endPeekHere(); this._previewMenu.endPeekHere();
} }
this.window.delete(global.get_current_time()); this.window.delete(global.get_current_time());
}, }
_onButtonReleaseEvent: function(e) { _onButtonReleaseEvent(e) {
switch (e.get_button()) { switch (e.get_button()) {
case 1: // Left click case 1: // Left click
this.activate(); this.activate();
break; break;
case 2: // Middle click case 2: // Middle click
if (Me.settings.get_boolean('preview-middle-click-close')) { if (SETTINGS.get_boolean('preview-middle-click-close')) {
this._onCloseBtnClick(); this._onCloseBtnClick();
} }
break; break;
@@ -912,18 +922,18 @@ var Preview = Utils.defineClass({
} }
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
}, }
_cancelAnimateOut: function() { _cancelAnimateOut() {
if (this.animatingOut) { if (this.animatingOut) {
this.animatingOut = false; this.animatingOut = false;
Utils.stopAnimations(this); Utils.stopAnimations(this);
Utils.animate(this, getTweenOpts({ opacity: 255, width: this.cloneWidth, height: this.cloneHeight })); Utils.animate(this, getTweenOpts({ opacity: 255, width: this.cloneWidth, height: this.cloneHeight }));
} }
}, }
_showContextMenu: function(e) { _showContextMenu(e) {
let coords = e.get_coords(); let coords = e.get_coords();
let currentWorkspace = this._previewMenu.peekInitialWorkspaceIndex < 0 ? let currentWorkspace = this._previewMenu.peekInitialWorkspaceIndex < 0 ?
Utils.getCurrentWorkspace() : Utils.getCurrentWorkspace() :
@@ -936,52 +946,53 @@ var Preview = Utils.defineClass({
height: 0 height: 0
}); });
let ctxMenuData = Main.wm._windowMenuManager._manager._menus[0]; let menu = Main.wm._windowMenuManager._manager._menus[0];
ctxMenuData.menu.connect('open-state-changed', () => this._previewMenu.menu.sync_hover()); menu.connect('open-state-changed', () => this._previewMenu.menu.sync_hover());
this._previewMenu.menu.sync_hover();
if (this.window.get_workspace() != currentWorkspace) { if (this.window.get_workspace() != currentWorkspace) {
let menuItem = new PopupMenu.PopupMenuItem(_('Move to current Workspace') + ' [' + (currentWorkspace.index() + 1) + ']'); let menuItem = new PopupMenu.PopupMenuItem(_('Move to current Workspace') + ' [' + (currentWorkspace.index() + 1) + ']');
let menuItems = ctxMenuData.menu.box.get_children(); let menuItems = menu.box.get_children();
let insertIndex = Utils.findIndex(menuItems, c => c._delegate instanceof PopupMenu.PopupSeparatorMenuItem); let insertIndex = Utils.findIndex(menuItems, c => c._delegate instanceof PopupMenu.PopupSeparatorMenuItem);
insertIndex = insertIndex >= 0 ? insertIndex : menuItems.length - 1; insertIndex = insertIndex >= 0 ? insertIndex : menuItems.length - 1;
ctxMenuData.menu.addMenuItem(menuItem, insertIndex); menu.addMenuItem(menuItem, insertIndex);
menuItem.connect('activate', () => this.window.change_workspace(currentWorkspace)); menuItem.connect('activate', () => this.window.change_workspace(currentWorkspace));
} }
}, }
_removeWindowSignals: function() { _removeWindowSignals() {
if (this._titleWindowChangeId) { if (this._titleWindowChangeId) {
this.window.disconnect(this._titleWindowChangeId); this.window.disconnect(this._titleWindowChangeId);
this._titleWindowChangeId = 0; this._titleWindowChangeId = 0;
} }
}, }
_updateHeader: function() { _updateHeader() {
if (headerHeight) { if (headerHeight) {
this._titleWindowChangeId = this.window.connect('notify::title', () => this._updateWindowTitle()); this._titleWindowChangeId = this.window.connect('notify::title', () => this._updateWindowTitle());
setStyle(this._windowTitle, 'max-width: 0px; padding-left: 8px; padding-right: 8px; text-align: center;'); setStyle(this._windowTitle, 'max-width: 0px; padding-left: 8px; padding-right: 8px; text-align: center;');
this._updateWindowTitle(); this._updateWindowTitle();
} }
}, }
_updateWindowTitle: function() { _updateWindowTitle() {
this._windowTitle.text = this.window.title; this._windowTitle.text = this.window.title;
}, }
_hideOrShowCloseButton: function(hide) { _hideOrShowCloseButton(hide) {
if (this._needsCloseButton) { if (this._needsCloseButton) {
Utils.animate(this._closeButtonBin, getTweenOpts({ opacity: hide ? 0 : 255 })); Utils.animate(this._closeButtonBin, getTweenOpts({ opacity: hide ? 0 : 255 }));
} }
}, }
_getBackgroundColor: function(offset, alpha) { _getBackgroundColor(offset, alpha) {
return 'background-color: ' + this._getRgbaColor(offset, alpha) + return 'background-color: ' + this._getRgbaColor(offset, alpha) +
'transition-duration:' + this._previewMenu.panel.dynamicTransparency.animationDuration; 'transition-duration:' + this._previewMenu.panel.dynamicTransparency.animationDuration;
}, }
_getRgbaColor: function(offset, alpha) { _getRgbaColor(offset, alpha) {
alpha = Math.abs(alpha); alpha = Math.abs(alpha);
if (isNaN(alpha)) { if (isNaN(alpha)) {
@@ -989,9 +1000,9 @@ var Preview = Utils.defineClass({
} }
return Utils.getrgbaColor(this._previewMenu._getThemeBackground(), alpha, offset); return Utils.getrgbaColor(this._previewMenu._getThemeBackground(), alpha, offset);
}, }
_addClone: function(newCloneBin, animateSize) { _addClone(newCloneBin, animateSize) {
let currentClones = this._previewBin.get_children(); let currentClones = this._previewBin.get_children();
let newCloneOpts = getTweenOpts({ opacity: 255 }); let newCloneOpts = getTweenOpts({ opacity: 255 });
@@ -1025,9 +1036,9 @@ var Preview = Utils.defineClass({
} }
Utils.animate(newCloneBin, newCloneOpts); Utils.animate(newCloneBin, newCloneOpts);
}, }
_getWindowCloneBin: function(window) { _getWindowCloneBin(window) {
let frameRect = window.get_frame_rect(); let frameRect = window.get_frame_rect();
let bufferRect = window.get_buffer_rect(); let bufferRect = window.get_buffer_rect();
let clone = new Clutter.Clone({ source: window.get_compositor_private() }); let clone = new Clutter.Clone({ source: window.get_compositor_private() });
@@ -1042,18 +1053,18 @@ var Preview = Utils.defineClass({
cloneBin.add_child(clone); cloneBin.add_child(clone);
return cloneBin; return cloneBin;
}, }
_getBinSize: function() { _getBinSize() {
let [fixedWidth, fixedHeight] = this._previewDimensions; let [fixedWidth, fixedHeight] = this._previewDimensions;
return [ return [
aspectRatio.x.fixed ? fixedWidth + this._padding * 2 : -1, aspectRatio.x.fixed ? fixedWidth + this._padding * 2 : -1,
aspectRatio.y.fixed ? fixedHeight + this._padding * 2 : -1 aspectRatio.y.fixed ? fixedHeight + this._padding * 2 : -1
]; ];
}, }
_resizeClone: function(cloneBin, window) { _resizeClone(cloneBin, window) {
let frameRect = cloneBin.layout_manager.frameRect || window.get_frame_rect(); let frameRect = cloneBin.layout_manager.frameRect || window.get_frame_rect();
let [fixedWidth, fixedHeight] = this._previewDimensions; let [fixedWidth, fixedHeight] = this._previewDimensions;
let ratio = Math.min(fixedWidth / frameRect.width, fixedHeight / frameRect.height, 1); let ratio = Math.min(fixedWidth / frameRect.width, fixedHeight / frameRect.height, 1);
@@ -1073,10 +1084,10 @@ var Preview = Utils.defineClass({
cloneBin.layout_manager.padding = [clonePaddingLeft * scaleFactor, clonePaddingTop * scaleFactor]; cloneBin.layout_manager.padding = [clonePaddingLeft * scaleFactor, clonePaddingTop * scaleFactor];
cloneBin.get_first_child().set_size(cloneWidth, cloneHeight); cloneBin.get_first_child().set_size(cloneWidth, cloneHeight);
}, }
_getPreviewDimensions: function() { _getPreviewDimensions() {
let size = Me.settings.get_int('window-preview-size') * scaleFactor; let size = SETTINGS.get_int('window-preview-size') * scaleFactor;
let w, h; let w, h;
if (this._previewMenu.isVertical) { if (this._previewMenu.isVertical) {
@@ -1091,19 +1102,18 @@ var Preview = Utils.defineClass({
} }
}); });
var WindowCloneLayout = Utils.defineClass({ export const WindowCloneLayout = GObject.registerClass({
Name: 'ZorinTaskbar-WindowCloneLayout', }, class WindowCloneLayout extends Clutter.BinLayout {
Extends: Clutter.BinLayout,
_init: function(frameRect, bufferRect) { _init(frameRect, bufferRect) {
this.callParent('_init'); super._init();
//the buffer_rect contains the transparent padding that must be removed //the buffer_rect contains the transparent padding that must be removed
this.frameRect = frameRect; this.frameRect = frameRect;
this.bufferRect = bufferRect; this.bufferRect = bufferRect;
}, }
vfunc_allocate: function(actor, box, flags) { vfunc_allocate(actor, box) {
let [width, height] = box.get_size(); let [width, height] = box.get_size();
box.set_origin( box.set_origin(
@@ -1116,15 +1126,15 @@ var WindowCloneLayout = Utils.defineClass({
height + (this.bufferRect.height - this.frameRect.height) * this.ratio height + (this.bufferRect.height - this.frameRect.height) * this.ratio
); );
Utils.allocate(actor.get_first_child(), box, flags); actor.get_first_child().allocate(box);
} }
}); });
function setStyle(actor, style) { export function setStyle(actor, style) {
actor.set_style(style); actor.set_style(style);
} }
function getTweenOpts(opts) { export function getTweenOpts(opts) {
let defaults = { let defaults = {
time: animationTime, time: animationTime,
transition: 'easeInOutQuad' transition: 'easeInOutQuad'