Format code

This commit is contained in:
Charles Gagnon
2025-01-31 11:49:22 -05:00
parent a0d831c25e
commit d04104ff8a
22 changed files with 14374 additions and 10716 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@ dash-to-panel@jderose9.github.com*.zip
*.mo *.mo
po/dash-to-panel.pot po/dash-to-panel.pot
ui/*.ui.h ui/*.ui.h
node_modules/

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"semi": false,
"arrowParens": "always",
"singleQuote": true
}

File diff suppressed because it is too large Load Diff

View File

@@ -55,38 +55,42 @@
* *
*******************************************************************************/ *******************************************************************************/
import GLib from 'gi://GLib'; import GLib from 'gi://GLib'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import * as ExtensionUtils from 'resource:///org/gnome/shell/misc/extensionUtils.js'; import * as ExtensionUtils from 'resource:///org/gnome/shell/misc/extensionUtils.js'
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js'; import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js'
const IDENTIFIER_UUID = "130cbc66-235c-4bd6-8571-98d2d8bba5e2"; const IDENTIFIER_UUID = '130cbc66-235c-4bd6-8571-98d2d8bba5e2'
export class DesktopIconsUsableAreaClass { export class DesktopIconsUsableAreaClass {
_checkIfExtensionIsEnabled(extension) { _checkIfExtensionIsEnabled(extension) {
return (extension?.state === ExtensionUtils.ExtensionState.ENABLED) || return (
(extension?.state === ExtensionUtils.ExtensionState.ACTIVE); extension?.state === ExtensionUtils.ExtensionState.ENABLED ||
extension?.state === ExtensionUtils.ExtensionState.ACTIVE
)
} }
constructor() { constructor() {
const Me = Extension.lookupByURL(import.meta.url); const Me = Extension.lookupByURL(import.meta.url)
this._UUID = Me.uuid; this._UUID = Me.uuid
this._extensionManager = Main.extensionManager; this._extensionManager = Main.extensionManager
this._timedMarginsID = 0; this._timedMarginsID = 0
this._margins = {}; this._margins = {}
this._emID = this._extensionManager.connect('extension-state-changed', (_obj, extension) => { this._emID = this._extensionManager.connect(
if (!extension) 'extension-state-changed',
return; (_obj, extension) => {
if (!extension) return
// If an extension is being enabled and lacks the DesktopIconsUsableArea object, we can avoid launching a refresh // If an extension is being enabled and lacks the DesktopIconsUsableArea object, we can avoid launching a refresh
if (this._checkIfExtensionIsEnabled(extension)) { if (this._checkIfExtensionIsEnabled(extension)) {
this._sendMarginsToExtension(extension); this._sendMarginsToExtension(extension)
return; return
} }
// if the extension is being disabled, we must do a full refresh, because if there were other extensions originally // 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 // loaded after that extension, those extensions will be disabled and enabled again without notification
this._changedMargins(); this._changedMargins()
}); },
)
} }
/** /**
@@ -103,12 +107,12 @@ export class DesktopIconsUsableAreaClass {
*/ */
setMargins(monitor, top, bottom, left, right) { setMargins(monitor, top, bottom, left, right) {
this._margins[monitor] = { this._margins[monitor] = {
'top': top, top: top,
'bottom': bottom, bottom: bottom,
'left': left, left: left,
'right': right right: right,
}; }
this._changedMargins(); this._changedMargins()
} }
/** /**
@@ -116,8 +120,8 @@ export class DesktopIconsUsableAreaClass {
* margins with setMargins(). * margins with setMargins().
*/ */
resetMargins() { resetMargins() {
this._margins = {}; this._margins = {}
this._changedMargins(); this._changedMargins()
} }
/** /**
@@ -125,41 +129,43 @@ export class DesktopIconsUsableAreaClass {
*/ */
destroy() { destroy() {
if (this._emID) { if (this._emID) {
this._extensionManager.disconnect(this._emID); this._extensionManager.disconnect(this._emID)
this._emID = 0; this._emID = 0
} }
if (this._timedMarginsID) { if (this._timedMarginsID) {
GLib.source_remove(this._timedMarginsID); GLib.source_remove(this._timedMarginsID)
this._timedMarginsID = 0; this._timedMarginsID = 0
} }
this._margins = null; this._margins = null
this._changedMargins(); this._changedMargins()
} }
_changedMargins() { _changedMargins() {
if (this._timedMarginsID) { if (this._timedMarginsID) {
GLib.source_remove(this._timedMarginsID); GLib.source_remove(this._timedMarginsID)
} }
this._timedMarginsID = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, ()=> { this._timedMarginsID = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => {
this._sendMarginsToAll(); this._sendMarginsToAll()
this._timedMarginsID = 0; this._timedMarginsID = 0
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE
}); })
} }
_sendMarginsToAll() { _sendMarginsToAll() {
this._extensionManager.getUuids().forEach(uuid => this._extensionManager
this._sendMarginsToExtension(this._extensionManager.lookup(uuid))); .getUuids()
.forEach((uuid) =>
this._sendMarginsToExtension(this._extensionManager.lookup(uuid)),
)
} }
_sendMarginsToExtension(extension) { _sendMarginsToExtension(extension) {
// check that the extension is an extension that has the logic to accept // check that the extension is an extension that has the logic to accept
// working margins // working margins
if (!this._checkIfExtensionIsEnabled(extension)) if (!this._checkIfExtensionIsEnabled(extension)) return
return;
const usableArea = extension?.stateObj?.DesktopIconsUsableArea; const usableArea = extension?.stateObj?.DesktopIconsUsableArea
if (usableArea?.uuid === IDENTIFIER_UUID) if (usableArea?.uuid === IDENTIFIER_UUID)
usableArea.setMarginsForExtension(this._UUID, this._margins); usableArea.setMarginsForExtension(this._UUID, this._margins)
} }
} }

9
eslint.config.js Normal file
View File

@@ -0,0 +1,9 @@
import globals from 'globals'
import pluginJs from '@eslint/js'
import eslintConfigPrettier from 'eslint-config-prettier'
export default [
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
eslintConfigPrettier,
]

View File

@@ -17,105 +17,120 @@
* *
*/ */
import Gio from 'gi://Gio'
import Gio from 'gi://Gio'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js'
import {
Extension,
gettext as _,
} from 'resource:///org/gnome/shell/extensions/extension.js'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as PanelManager from './panelManager.js'
import {EventEmitter} from 'resource:///org/gnome/shell/misc/signals.js'; import * as AppIcons from './appIcons.js'
import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
import * as PanelManager from './panelManager.js'; const UBUNTU_DOCK_UUID = 'ubuntu-dock@ubuntu.com'
import * as AppIcons from './appIcons.js';
let panelManager
let extensionChangedHandler
let startupCompleteHandler
let extensionSystem = Main.extensionManager
const UBUNTU_DOCK_UUID = 'ubuntu-dock@ubuntu.com'; export let DTP_EXTENSION = null
export let SETTINGS = null
let panelManager; export let DESKTOPSETTINGS = null
let extensionChangedHandler; export let TERMINALSETTINGS = null
let startupCompleteHandler; export let PERSISTENTSTORAGE = null
let extensionSystem = Main.extensionManager; export let EXTENSION_UUID = null
export let EXTENSION_PATH = null
export let DTP_EXTENSION = null;
export let SETTINGS = null;
export let DESKTOPSETTINGS = null;
export let TERMINALSETTINGS = null;
export let PERSISTENTSTORAGE = null;
export let EXTENSION_UUID = null;
export let EXTENSION_PATH = null;
export default class DashToPanelExtension extends Extension { export default class DashToPanelExtension extends Extension {
constructor(metadata) { constructor(metadata) {
super(metadata); super(metadata)
this._realHasOverview = Main.sessionMode.hasOverview; this._realHasOverview = Main.sessionMode.hasOverview
//create an object that persists until gnome-shell is restarted, even if the extension is disabled //create an object that persists until gnome-shell is restarted, even if the extension is disabled
PERSISTENTSTORAGE = {}; PERSISTENTSTORAGE = {}
} }
enable() { enable() {
DTP_EXTENSION = this; DTP_EXTENSION = this
// The Ubuntu Dock extension might get enabled after this extension // The Ubuntu Dock extension might get enabled after this extension
extensionChangedHandler = extensionSystem.connect('extension-state-changed', (data, extension) => { extensionChangedHandler = extensionSystem.connect(
'extension-state-changed',
(data, extension) => {
if (extension.uuid === UBUNTU_DOCK_UUID && extension.state === 1) { if (extension.uuid === UBUNTU_DOCK_UUID && extension.state === 1) {
_enable(this); _enable(this)
} }
}); },
)
//create a global object that can emit signals and conveniently expose functionalities to other extensions //create a global object that can emit signals and conveniently expose functionalities to other extensions
global.dashToPanel = new EventEmitter(); global.dashToPanel = new EventEmitter()
_enable(this); _enable(this)
} }
disable(reset = false) { disable(reset = false) {
panelManager.disable(); panelManager.disable()
DTP_EXTENSION = null; DTP_EXTENSION = null
SETTINGS = null; SETTINGS = null
DESKTOPSETTINGS = null; DESKTOPSETTINGS = null
TERMINALSETTINGS = null; TERMINALSETTINGS = null
panelManager = null; panelManager = null
if (!reset) { if (!reset) {
extensionSystem.disconnect(extensionChangedHandler); extensionSystem.disconnect(extensionChangedHandler)
delete global.dashToPanel; delete global.dashToPanel
AppIcons.resetRecentlyClickedApp(); AppIcons.resetRecentlyClickedApp()
} }
if (startupCompleteHandler) { if (startupCompleteHandler) {
Main.layoutManager.disconnect(startupCompleteHandler); Main.layoutManager.disconnect(startupCompleteHandler)
startupCompleteHandler = null; startupCompleteHandler = null
} }
Main.sessionMode.hasOverview = this._realHasOverview; Main.sessionMode.hasOverview = this._realHasOverview
} }
} }
function _enable(extension) { function _enable(extension) {
let enabled = global.settings.get_strv('enabled-extensions'); let enabled = global.settings.get_strv('enabled-extensions')
if (enabled?.indexOf(UBUNTU_DOCK_UUID) >= 0) if (enabled?.indexOf(UBUNTU_DOCK_UUID) >= 0)
extensionSystem.disableExtension(UBUNTU_DOCK_UUID); extensionSystem.disableExtension(UBUNTU_DOCK_UUID)
if (panelManager) if (panelManager) return
return
SETTINGS = extension.getSettings('org.gnome.shell.extensions.dash-to-panel'); SETTINGS = extension.getSettings('org.gnome.shell.extensions.dash-to-panel')
DESKTOPSETTINGS = new Gio.Settings({schema_id: 'org.gnome.desktop.interface'}); DESKTOPSETTINGS = new Gio.Settings({
TERMINALSETTINGS = new Gio.Settings({schema_id: 'org.gnome.desktop.default-applications.terminal'}) schema_id: 'org.gnome.desktop.interface',
})
TERMINALSETTINGS = new Gio.Settings({
schema_id: 'org.gnome.desktop.default-applications.terminal',
})
EXTENSION_UUID = extension.uuid EXTENSION_UUID = extension.uuid
EXTENSION_PATH = extension.path EXTENSION_PATH = extension.path
Main.layoutManager.startInOverview = !SETTINGS.get_boolean('hide-overview-on-startup'); Main.layoutManager.startInOverview = !SETTINGS.get_boolean(
'hide-overview-on-startup',
)
if (SETTINGS.get_boolean('hide-overview-on-startup') && Main.layoutManager._startingUp) { if (
Main.sessionMode.hasOverview = false; SETTINGS.get_boolean('hide-overview-on-startup') &&
startupCompleteHandler = Main.layoutManager.connect('startup-complete', () => { Main.layoutManager._startingUp
) {
Main.sessionMode.hasOverview = false
startupCompleteHandler = Main.layoutManager.connect(
'startup-complete',
() => {
Main.sessionMode.hasOverview = extension._realHasOverview Main.sessionMode.hasOverview = extension._realHasOverview
}); },
)
} }
// show the donate icon every 120 days (10368000000 milliseconds) // show the donate icon every 120 days (10368000000 milliseconds)
@@ -124,7 +139,7 @@ function _enable(extension) {
if (donateIconUnixtime && donateIconUnixtime < Date.now() - 10368000000) if (donateIconUnixtime && donateIconUnixtime < Date.now() - 10368000000)
SETTINGS.set_string('hide-donate-icon-unixtime', '') SETTINGS.set_string('hide-donate-icon-unixtime', '')
panelManager = new PanelManager.PanelManager(); panelManager = new PanelManager.PanelManager()
panelManager.enable(); panelManager.enable()
} }

View File

@@ -15,149 +15,159 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import Clutter from 'gi://Clutter'; import Clutter from 'gi://Clutter'
import Meta from 'gi://Meta'; import Meta from 'gi://Meta'
import Shell from 'gi://Shell'; import Shell from 'gi://Shell'
import St from 'gi://St'; import St from 'gi://St'
import * as GrabHelper from 'resource:///org/gnome/shell/ui/grabHelper.js'; import * as GrabHelper from 'resource:///org/gnome/shell/ui/grabHelper.js'
import * as Layout from 'resource:///org/gnome/shell/ui/layout.js'; import * as Layout from 'resource:///org/gnome/shell/ui/layout.js'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import * as OverviewControls from 'resource:///org/gnome/shell/ui/overviewControls.js'; import * as OverviewControls from 'resource:///org/gnome/shell/ui/overviewControls.js'
import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.js'; import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.js'
import * as Proximity from './proximity.js'; import * as Proximity from './proximity.js'
import * as Utils from './utils.js'; import * as Utils from './utils.js'
import {SETTINGS} from './extension.js'; import { SETTINGS } from './extension.js'
//timeout intervals //timeout intervals
const CHECK_POINTER_MS = 200; const CHECK_POINTER_MS = 200
const CHECK_GRAB_MS = 400; const CHECK_GRAB_MS = 400
const POST_ANIMATE_MS = 50; const POST_ANIMATE_MS = 50
const MIN_UPDATE_MS = 250; const MIN_UPDATE_MS = 250
//timeout names //timeout names
const T1 = 'checkGrabTimeout'; const T1 = 'checkGrabTimeout'
const T2 = 'limitUpdateTimeout'; const T2 = 'limitUpdateTimeout'
const T3 = 'postAnimateTimeout'; const T3 = 'postAnimateTimeout'
const 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)
export const Hold = { export const Hold = {
NONE: 0, NONE: 0,
TEMPORARY: 1, TEMPORARY: 1,
PERMANENT: 2 PERMANENT: 2,
}; }
export const Intellihide = class { export const Intellihide = class {
constructor(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
this._proximityManager = this._panelManager.proximityManager; this._proximityManager = this._panelManager.proximityManager
this._holdStatus = Hold.NONE; this._holdStatus = Hold.NONE
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler()
this._timeoutsHandler = new Utils.TimeoutsHandler(); this._timeoutsHandler = new Utils.TimeoutsHandler()
this._intellihideChangedId = SETTINGS.connect('changed::intellihide', () => this._changeEnabledStatus()); this._intellihideChangedId = SETTINGS.connect('changed::intellihide', () =>
this._intellihideOnlySecondaryChangedId = SETTINGS.connect('changed::intellihide-only-secondary', () => this._changeEnabledStatus()); this._changeEnabledStatus(),
)
this._intellihideOnlySecondaryChangedId = SETTINGS.connect(
'changed::intellihide-only-secondary',
() => this._changeEnabledStatus(),
)
this.enabled = false; this.enabled = false
this._changeEnabledStatus(); this._changeEnabledStatus()
} }
enable() { enable() {
this.enabled = true; this.enabled = true
this._monitor = this._dtpPanel.monitor; this._monitor = this._dtpPanel.monitor
this._animationDestination = -1; this._animationDestination = -1
this._pendingUpdate = false; this._pendingUpdate = false
this._hoveredOut = false; this._hoveredOut = false
this._windowOverlap = false; this._windowOverlap = false
this._translationProp = 'translation_' + (this._dtpPanel.checkIfVertical() ? 'x' : 'y'); this._translationProp =
'translation_' + (this._dtpPanel.checkIfVertical() ? 'x' : 'y')
this._panelBox.translation_y = 0; this._panelBox.translation_y = 0
this._panelBox.translation_x = 0; this._panelBox.translation_x = 0
this._setTrackPanel(true); this._setTrackPanel(true)
this._bindGeneralSignals(); this._bindGeneralSignals()
if (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(),
this._dtpPanel.monitor.index, this._dtpPanel.monitor.index,
Proximity.Mode[SETTINGS.get_string('intellihide-behaviour')], Proximity.Mode[SETTINGS.get_string('intellihide-behaviour')],
0, 0, 0,
overlap => { 0,
this._windowOverlap = overlap; (overlap) => {
this._queueUpdatePanelPosition(); this._windowOverlap = overlap
} this._queueUpdatePanelPosition()
); },
)
} }
this._setRevealMechanism(); this._setRevealMechanism()
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition()
} }
disable(reset) { disable(reset) {
if (this._proximityWatchId) { if (this._proximityWatchId) {
this._proximityManager.removeWatch(this._proximityWatchId); this._proximityManager.removeWatch(this._proximityWatchId)
} }
this._setTrackPanel(false); this._setTrackPanel(false)
this._signalsHandler.destroy(); this._signalsHandler.destroy()
this._timeoutsHandler.destroy(); this._timeoutsHandler.destroy()
this._removeRevealMechanism(); this._removeRevealMechanism()
this._revealPanel(!reset); this._revealPanel(!reset)
this.enabled = false; this.enabled = false
} }
destroy() { destroy() {
SETTINGS.disconnect(this._intellihideChangedId); SETTINGS.disconnect(this._intellihideChangedId)
SETTINGS.disconnect(this._intellihideOnlySecondaryChangedId); SETTINGS.disconnect(this._intellihideOnlySecondaryChangedId)
if (this.enabled) { if (this.enabled) {
this.disable(); this.disable()
} }
} }
toggle() { toggle() {
this[this._holdStatus & Hold.PERMANENT ? 'release' : 'revealAndHold'](Hold.PERMANENT); this[this._holdStatus & Hold.PERMANENT ? 'release' : 'revealAndHold'](
Hold.PERMANENT,
)
} }
revealAndHold(holdStatus) { revealAndHold(holdStatus) {
if (this.enabled && !this._holdStatus) { if (this.enabled && !this._holdStatus) {
this._revealPanel(); this._revealPanel()
} }
this._holdStatus |= holdStatus; this._holdStatus |= holdStatus
} }
release(holdStatus) { release(holdStatus) {
this._holdStatus -= holdStatus; this._holdStatus -= holdStatus
if (this.enabled && !this._holdStatus) { if (this.enabled && !this._holdStatus) {
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition()
} }
} }
reset() { reset() {
this.disable(true); this.disable(true)
this.enable(); this.enable()
} }
_changeEnabledStatus() { _changeEnabledStatus() {
let intellihide = SETTINGS.get_boolean('intellihide'); let intellihide = SETTINGS.get_boolean('intellihide')
let onlySecondary = 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']()
} }
} }
@@ -167,9 +177,9 @@ export const Intellihide = class {
this._dtpPanel.taskbar, this._dtpPanel.taskbar,
['menu-closed', 'end-drag'], ['menu-closed', 'end-drag'],
() => { () => {
this._panelBox.sync_hover(); this._panelBox.sync_hover()
this._onHoverChanged(); this._onHoverChanged()
} },
], ],
[ [
SETTINGS, SETTINGS,
@@ -178,171 +188,196 @@ export const Intellihide = class {
'changed::intellihide-hide-from-windows', 'changed::intellihide-hide-from-windows',
'changed::intellihide-behaviour', 'changed::intellihide-behaviour',
'changed::intellihide-pressure-threshold', 'changed::intellihide-pressure-threshold',
'changed::intellihide-pressure-time' 'changed::intellihide-pressure-time',
], ],
() => this.reset() () => this.reset(),
],
[
this._panelBox,
'notify::hover',
() => this._onHoverChanged()
], ],
[this._panelBox, 'notify::hover', () => this._onHoverChanged()],
[ [
this._dtpPanel.taskbar.previewMenu, this._dtpPanel.taskbar.previewMenu,
'open-state-changed', 'open-state-changed',
() => this._queueUpdatePanelPosition() () => this._queueUpdatePanelPosition(),
], ],
[ [
Main.overview, Main.overview,
[ ['showing', 'hiding'],
'showing', () => this._queueUpdatePanelPosition(),
'hiding'
], ],
() => this._queueUpdatePanelPosition() )
]
);
if (Meta.is_wayland_compositor()) { if (Meta.is_wayland_compositor()) {
this._signalsHandler.add([ this._signalsHandler.add([
this._panelBox, this._panelBox,
'notify::visible', 'notify::visible',
() => Utils.setDisplayUnredirect(!this._panelBox.visible) () => Utils.setDisplayUnredirect(!this._panelBox.visible),
]); ])
} }
} }
_onHoverChanged() { _onHoverChanged() {
this._hoveredOut = !this._panelBox.hover; this._hoveredOut = !this._panelBox.hover
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition()
} }
_setTrackPanel(enable) { _setTrackPanel(enable) {
let actorData = Utils.getTrackedActorData(this._panelBox) let actorData = Utils.getTrackedActorData(this._panelBox)
actorData.affectsStruts = !enable; actorData.affectsStruts = !enable
actorData.trackFullscreen = !enable; actorData.trackFullscreen = !enable
this._panelBox.track_hover = enable; this._panelBox.track_hover = enable
this._panelBox.reactive = enable; this._panelBox.reactive = enable
this._panelBox.visible = enable ? enable : this._panelBox.visible; this._panelBox.visible = enable ? enable : this._panelBox.visible
Main.layoutManager._queueUpdateRegions(); Main.layoutManager._queueUpdateRegions()
} }
_setRevealMechanism() { _setRevealMechanism() {
let barriers = Meta.BackendCapabilities.BARRIERS let barriers = Meta.BackendCapabilities.BARRIERS
if ((global.backend.capabilities & barriers) === barriers && SETTINGS.get_boolean('intellihide-use-pressure')) { if (
this._edgeBarrier = this._createBarrier(); (global.backend.capabilities & barriers) === barriers &&
SETTINGS.get_boolean('intellihide-use-pressure')
) {
this._edgeBarrier = this._createBarrier()
this._pressureBarrier = new Layout.PressureBarrier( this._pressureBarrier = new Layout.PressureBarrier(
SETTINGS.get_int('intellihide-pressure-threshold'), SETTINGS.get_int('intellihide-pressure-threshold'),
SETTINGS.get_int('intellihide-pressure-time'), SETTINGS.get_int('intellihide-pressure-time'),
Shell.ActionMode.NORMAL Shell.ActionMode.NORMAL,
); )
this._pressureBarrier.addBarrier(this._edgeBarrier); this._pressureBarrier.addBarrier(this._edgeBarrier)
this._signalsHandler.add([this._pressureBarrier, 'trigger', () => this._queueUpdatePanelPosition(true)]); this._signalsHandler.add([
this._pressureBarrier,
'trigger',
() => this._queueUpdatePanelPosition(true),
])
} else { } else {
this._pointerWatch = PointerWatcher.getPointerWatcher() this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(
.addWatch(CHECK_POINTER_MS, (x, y) => this._checkMousePointer(x, y)); CHECK_POINTER_MS,
(x, y) => this._checkMousePointer(x, y),
)
} }
} }
_removeRevealMechanism() { _removeRevealMechanism() {
if (this._pointerWatch) { if (this._pointerWatch) {
PointerWatcher.getPointerWatcher()._removeWatch(this._pointerWatch); PointerWatcher.getPointerWatcher()._removeWatch(this._pointerWatch)
} }
if (this._pressureBarrier) { if (this._pressureBarrier) {
this._pressureBarrier.destroy(); this._pressureBarrier.destroy()
this._edgeBarrier.destroy(); this._edgeBarrier.destroy()
this._pressureBarrier = 0; this._pressureBarrier = 0
} }
} }
_createBarrier() { _createBarrier() {
let position = this._dtpPanel.geom.position; let position = this._dtpPanel.geom.position
let opts = { backend: global.backend }; let opts = { backend: global.backend }
if (this._dtpPanel.checkIfVertical()) { if (this._dtpPanel.checkIfVertical()) {
opts.y1 = this._monitor.y; opts.y1 = this._monitor.y
opts.y2 = this._monitor.y + this._monitor.height; opts.y2 = this._monitor.y + this._monitor.height
opts.x1 = opts.x2 = this._monitor.x; opts.x1 = opts.x2 = this._monitor.x
} else { } else {
opts.x1 = this._monitor.x; opts.x1 = this._monitor.x
opts.x2 = this._monitor.x + this._monitor.width; opts.x2 = this._monitor.x + this._monitor.width
opts.y1 = opts.y2 = this._monitor.y; opts.y1 = opts.y2 = this._monitor.y
} }
if (position == St.Side.TOP) { if (position == St.Side.TOP) {
opts.directions = Meta.BarrierDirection.POSITIVE_Y; opts.directions = Meta.BarrierDirection.POSITIVE_Y
} else if (position == St.Side.BOTTOM) { } else if (position == St.Side.BOTTOM) {
opts.y1 = opts.y2 = opts.y1 + this._monitor.height; opts.y1 = opts.y2 = opts.y1 + this._monitor.height
opts.directions = Meta.BarrierDirection.NEGATIVE_Y; opts.directions = Meta.BarrierDirection.NEGATIVE_Y
} else if (position == St.Side.LEFT) { } else if (position == St.Side.LEFT) {
opts.directions = Meta.BarrierDirection.POSITIVE_X; opts.directions = Meta.BarrierDirection.POSITIVE_X
} else { } else {
opts.x1 = opts.x2 = opts.x1 + this._monitor.width; opts.x1 = opts.x2 = opts.x1 + this._monitor.width
opts.directions = Meta.BarrierDirection.NEGATIVE_X; opts.directions = Meta.BarrierDirection.NEGATIVE_X
} }
return new Meta.Barrier(opts); return new Meta.Barrier(opts)
} }
_checkMousePointer(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 &&
((position == St.Side.TOP && y <= this._monitor.y + 1) || ((position == St.Side.TOP && y <= this._monitor.y + 1) ||
(position == St.Side.BOTTOM && y >= this._monitor.y + this._monitor.height - 1) || (position == St.Side.BOTTOM &&
y >= this._monitor.y + this._monitor.height - 1) ||
(position == St.Side.LEFT && x <= this._monitor.x + 1) || (position == St.Side.LEFT && x <= this._monitor.x + 1) ||
(position == St.Side.RIGHT && x >= this._monitor.x + this._monitor.width - 1)) && (position == St.Side.RIGHT &&
((x >= this._monitor.x && x < this._monitor.x + this._monitor.width) && x >= this._monitor.x + this._monitor.width - 1)) &&
(y >= this._monitor.y && y < this._monitor.y + this._monitor.height))) { x >= this._monitor.x &&
this._queueUpdatePanelPosition(true); x < this._monitor.x + this._monitor.width &&
y >= this._monitor.y &&
y < this._monitor.y + this._monitor.height
) {
this._queueUpdatePanelPosition(true)
} }
} }
_queueUpdatePanelPosition(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
this._pendingUpdate = true; this._pendingUpdate = true
} else if (!this._holdStatus) { } else if (!this._holdStatus) {
this._checkIfShouldBeVisible(fromRevealMechanism) ? this._revealPanel() : this._hidePanel(); this._checkIfShouldBeVisible(fromRevealMechanism)
this._timeoutsHandler.add([T2, MIN_UPDATE_MS, () => this._endLimitUpdate()]); ? this._revealPanel()
: this._hidePanel()
this._timeoutsHandler.add([
T2,
MIN_UPDATE_MS,
() => this._endLimitUpdate(),
])
} }
} }
_endLimitUpdate() { _endLimitUpdate() {
if (this._pendingUpdate) { if (this._pendingUpdate) {
this._pendingUpdate = false; this._pendingUpdate = false
this._queueUpdatePanelPosition(); this._queueUpdatePanelPosition()
} }
} }
_checkIfShouldBeVisible(fromRevealMechanism) { _checkIfShouldBeVisible(fromRevealMechanism) {
if (Main.overview.visibleTarget || this._dtpPanel.taskbar.previewMenu.opened || if (
this._dtpPanel.taskbar._dragMonitor || this._panelBox.get_hover() || this._checkIfGrab()) { Main.overview.visibleTarget ||
return true; this._dtpPanel.taskbar.previewMenu.opened ||
this._dtpPanel.taskbar._dragMonitor ||
this._panelBox.get_hover() ||
this._checkIfGrab()
) {
return true
} }
if (fromRevealMechanism) { if (fromRevealMechanism) {
let mouseBtnIsPressed = global.get_pointer()[2] & Clutter.ModifierType.BUTTON1_MASK; let mouseBtnIsPressed =
global.get_pointer()[2] & Clutter.ModifierType.BUTTON1_MASK
//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 SETTINGS.get_boolean('intellihide-show-in-fullscreen'); return SETTINGS.get_boolean('intellihide-show-in-fullscreen')
} }
return !mouseBtnIsPressed; return !mouseBtnIsPressed
} }
if (!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() { _checkIfGrab() {
@@ -350,78 +385,104 @@ export const Intellihide = class {
if (GrabHelper._grabHelperStack) if (GrabHelper._grabHelperStack)
// gnome-shell < 42 // gnome-shell < 42
isGrab = GrabHelper._grabHelperStack.some(gh => gh._owner == this._dtpPanel.panel) isGrab = GrabHelper._grabHelperStack.some(
(gh) => gh._owner == this._dtpPanel.panel,
)
else if (global.stage.get_grab_actor) { else if (global.stage.get_grab_actor) {
// gnome-shell >= 42 // gnome-shell >= 42
let grabActor = global.stage.get_grab_actor() let grabActor = global.stage.get_grab_actor()
let sourceActor = grabActor?._sourceActor || grabActor let sourceActor = grabActor?._sourceActor || grabActor
isGrab = sourceActor && isGrab =
sourceActor &&
(sourceActor == Main.layoutManager.dummyCursor || (sourceActor == Main.layoutManager.dummyCursor ||
this._dtpPanel.statusArea.quickSettings?.menu.actor.contains(sourceActor) || this._dtpPanel.statusArea.quickSettings?.menu.actor.contains(
sourceActor,
) ||
this._dtpPanel.panel.contains(sourceActor)) this._dtpPanel.panel.contains(sourceActor))
} }
if (isGrab) 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 isGrab; return isGrab
} }
_revealPanel(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(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 =
let coefficient = position == St.Side.TOP || position == St.Side.LEFT ? -1 : 1; this._panelBox[
position == St.Side.LEFT || position == St.Side.RIGHT
? 'width'
: 'height'
]
let coefficient =
position == St.Side.TOP || position == St.Side.LEFT ? -1 : 1
this._animatePanel(size * coefficient, immediate); this._animatePanel(size * coefficient, immediate)
} }
_animatePanel(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._panelBox[this._translationProp]))) { !(
(animating && destination === this._animationDestination) ||
(!animating && destination === this._panelBox[this._translationProp])
)
) {
//the panel isn't already at, or animating to the asked destination //the panel isn't already at, or animating to the asked destination
if (animating) { if (animating) {
Utils.stopAnimations(this._panelBox); Utils.stopAnimations(this._panelBox)
} }
this._animationDestination = destination; this._animationDestination = destination
if (immediate) { if (immediate) {
this._panelBox[this._translationProp] = destination; this._panelBox[this._translationProp] = destination
this._panelBox.visible = !destination; this._panelBox.visible = !destination
} else { } else {
let tweenOpts = { let tweenOpts = {
//when entering/leaving the overview, use its animation time instead of the one from the settings //when entering/leaving the overview, use its animation time instead of the one from the settings
time: Main.overview.visible ? time: Main.overview.visible
SIDE_CONTROLS_ANIMATION_TIME : ? SIDE_CONTROLS_ANIMATION_TIME
SETTINGS.get_int('intellihide-animation-time') * 0.001, : SETTINGS.get_int('intellihide-animation-time') * 0.001,
//only delay the animation when hiding the panel after the user hovered out //only delay the animation when hiding the panel after the user hovered out
delay: destination != 0 && this._hoveredOut ? SETTINGS.get_int('intellihide-close-delay') * 0.001 : 0, delay:
destination != 0 && this._hoveredOut
? SETTINGS.get_int('intellihide-close-delay') * 0.001
: 0,
transition: 'easeOutQuad', transition: 'easeOutQuad',
onComplete: () => { onComplete: () => {
this._panelBox.visible = !destination; this._panelBox.visible = !destination
Main.layoutManager._queueUpdateRegions(); Main.layoutManager._queueUpdateRegions()
this._timeoutsHandler.add([T3, POST_ANIMATE_MS, () => this._queueUpdatePanelPosition()]); this._timeoutsHandler.add([
T3,
POST_ANIMATE_MS,
() => this._queueUpdatePanelPosition(),
])
},
} }
};
tweenOpts[this._translationProp] = destination; tweenOpts[this._translationProp] = destination
Utils.animate(this._panelBox, tweenOpts); Utils.animate(this._panelBox, tweenOpts)
} }
} }
this._hoveredOut = false; this._hoveredOut = false
} }
} }

View File

@@ -20,96 +20,93 @@
* Some code was also adapted from the upstream Gnome Shell source code. * Some code was also adapted from the upstream Gnome Shell source code.
*/ */
import * as Intellihide from './intellihide.js'; import * as Intellihide from './intellihide.js'
import * as Utils from './utils.js'; import * as Utils from './utils.js'
import Clutter from 'gi://Clutter'; import Clutter from 'gi://Clutter'
import Gio from 'gi://Gio'; import Gio from 'gi://Gio'
import Shell from 'gi://Shell'; import Shell from 'gi://Shell'
import St from 'gi://St'; import St from 'gi://St'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import * as WindowManager from 'resource:///org/gnome/shell/ui/windowManager.js'; import * as WindowManager from 'resource:///org/gnome/shell/ui/windowManager.js'
import {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js'; import { WindowPreview } from 'resource:///org/gnome/shell/ui/windowPreview.js'
import {InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js'; import { InjectionManager } from 'resource:///org/gnome/shell/extensions/extension.js'
import {SETTINGS} from './extension.js'; import { SETTINGS } from './extension.js'
const GS_HOTKEYS_KEY = 'switch-to-application-'; const GS_HOTKEYS_KEY = 'switch-to-application-'
// When the dash is shown, workspace window preview bottom labels go over it (default // 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 // gnome-shell behavior), but when the extension hides the dash, leave some space
// so those labels don't go over a bottom panel // so those labels don't go over a bottom panel
const LABEL_MARGIN = 60; const LABEL_MARGIN = 60
//timeout names //timeout names
const T1 = 'swipeEndTimeout'; const T1 = 'swipeEndTimeout'
const T2 = 'numberOverlayTimeout'; const T2 = 'numberOverlayTimeout'
export const Overview = class { export const Overview = class {
constructor() { constructor() {
this._injectionManager = new InjectionManager(); this._injectionManager = new InjectionManager()
this._numHotkeys = 10; this._numHotkeys = 10
} }
enable (primaryPanel) { enable(primaryPanel) {
this._panel = primaryPanel; this._panel = primaryPanel
this.taskbar = primaryPanel.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._timeoutsHandler = new Utils.TimeoutsHandler()
this._optionalWorkspaceIsolation(); this._optionalWorkspaceIsolation()
this._optionalHotKeys(); this._optionalHotKeys()
this._optionalNumberOverlay(); this._optionalNumberOverlay()
this._optionalClickToExit(); this._optionalClickToExit()
this.toggleDash(); this.toggleDash()
this._adaptAlloc(); this._adaptAlloc()
this._signalsHandler.add([ this._signalsHandler.add([
SETTINGS, SETTINGS,
[ ['changed::stockgs-keep-dash', 'changed::panel-sizes'],
'changed::stockgs-keep-dash', () => this.toggleDash(),
'changed::panel-sizes' ])
],
() => this.toggleDash()
]);
} }
disable() { disable() {
this._signalsHandler.destroy(); this._signalsHandler.destroy()
this._injectionsHandler.destroy(); this._injectionsHandler.destroy()
this._timeoutsHandler.destroy(); this._timeoutsHandler.destroy()
this._injectionManager.clear(); this._injectionManager.clear()
this.toggleDash(true); this.toggleDash(true)
// Remove key bindings // Remove key bindings
this._disableHotKeys(); this._disableHotKeys()
this._disableExtraShortcut(); this._disableExtraShortcut()
this._disableClickToExit(); this._disableClickToExit()
} }
toggleDash(visible) { toggleDash(visible) {
if (visible === undefined) { if (visible === undefined) {
visible = SETTINGS.get_boolean('stockgs-keep-dash'); visible = SETTINGS.get_boolean('stockgs-keep-dash')
} }
let visibilityFunc = visible ? 'show' : 'hide'; let visibilityFunc = visible ? 'show' : 'hide'
let height = visible ? -1 : LABEL_MARGIN * Utils.getScaleFactor(); let height = visible ? -1 : LABEL_MARGIN * Utils.getScaleFactor()
let overviewControls = Main.overview._overview._controls; let overviewControls = Main.overview._overview._controls
overviewControls.dash[visibilityFunc](); overviewControls.dash[visibilityFunc]()
overviewControls.dash.set_height(height); overviewControls.dash.set_height(height)
} }
_adaptAlloc() { _adaptAlloc() {
let overviewControls = Main.overview._overview._controls let overviewControls = Main.overview._overview._controls
this._injectionManager.overrideMethod(Object.getPrototypeOf(overviewControls), 'vfunc_allocate', this._injectionManager.overrideMethod(
(originalAllocate) => Object.getPrototypeOf(overviewControls),
(box) => { 'vfunc_allocate',
(originalAllocate) => (box) => {
let focusedPanel = this._panel.panelManager.focusedMonitorPanel let focusedPanel = this._panel.panelManager.focusedMonitorPanel
if (focusedPanel) { if (focusedPanel) {
@@ -119,14 +116,17 @@ export const Overview = class {
if (focusedPanel.intellihide?.enabled) { if (focusedPanel.intellihide?.enabled) {
// Panel intellihide is enabled (struts aren't taken into account on overview allocation), // Panel intellihide is enabled (struts aren't taken into account on overview allocation),
// dynamically modify the overview box to follow the reveal/hide animation // dynamically modify the overview box to follow the reveal/hide animation
let { transitioning, finalState, progress } = overviewControls._stateAdjustment.getStateTransitionParams() let { transitioning, finalState, progress } =
let size = focusedPanel.geom[focusedPanel.checkIfVertical() ? 'w' : 'h'] * overviewControls._stateAdjustment.getStateTransitionParams()
(transitioning ? Math.abs((finalState != 0 ? 0 : 1) - progress) : 1) let size =
focusedPanel.geom[focusedPanel.checkIfVertical() ? 'w' : 'h'] *
(transitioning
? Math.abs((finalState != 0 ? 0 : 1) - progress)
: 1)
if (isBottom || position == St.Side.RIGHT) if (isBottom || position == St.Side.RIGHT)
box[focusedPanel.fixedCoord.c2] -= size box[focusedPanel.fixedCoord.c2] -= size
else else box[focusedPanel.fixedCoord.c1] += size
box[focusedPanel.fixedCoord.c1] += size
} else if (isBottom) } else if (isBottom)
// The default overview allocation takes into account external // The default overview allocation takes into account external
// struts, everywhere but the bottom where the dash is usually fixed anyway. // struts, everywhere but the bottom where the dash is usually fixed anyway.
@@ -135,384 +135,418 @@ export const Overview = class {
} }
originalAllocate.call(overviewControls, box) originalAllocate.call(overviewControls, box)
} },
); )
} }
/** /**
* Isolate overview to open new windows for inactive apps * Isolate overview to open new windows for inactive apps
*/ */
_optionalWorkspaceIsolation() { _optionalWorkspaceIsolation() {
let label = 'optionalWorkspaceIsolation'; let label = 'optionalWorkspaceIsolation'
let enable = () => { let enable = () => {
this._injectionsHandler.removeWithLabel(label); this._injectionsHandler.removeWithLabel(label)
this._injectionsHandler.addWithLabel(label, [ this._injectionsHandler.addWithLabel(label, [
Shell.App.prototype, Shell.App.prototype,
'activate', 'activate',
IsolatedOverview IsolatedOverview,
]); ])
this._signalsHandler.removeWithLabel(label); this._signalsHandler.removeWithLabel(label)
this._signalsHandler.addWithLabel(label, [ this._signalsHandler.addWithLabel(label, [
global.window_manager, global.window_manager,
'switch-workspace', 'switch-workspace',
() => this._panel.panelManager.allPanels.forEach(p => p.taskbar.handleIsolatedWorkspaceSwitch()) () =>
]); this._panel.panelManager.allPanels.forEach((p) =>
p.taskbar.handleIsolatedWorkspaceSwitch(),
),
])
} }
let disable = () => { let disable = () => {
this._signalsHandler.removeWithLabel(label); this._signalsHandler.removeWithLabel(label)
this._injectionsHandler.removeWithLabel(label); this._injectionsHandler.removeWithLabel(label)
} }
function IsolatedOverview() { function IsolatedOverview() {
// These lines take care of Nautilus for icons on Desktop // These lines take care of Nautilus for icons on Desktop
let activeWorkspace = Utils.DisplayWrapper.getWorkspaceManager().get_active_workspace(); let activeWorkspace =
let windows = this.get_windows().filter(w => w.get_workspace().index() == activeWorkspace.index()); Utils.DisplayWrapper.getWorkspaceManager().get_active_workspace()
let windows = this.get_windows().filter(
(w) => w.get_workspace().index() == activeWorkspace.index(),
)
if (windows.length > 0 && if (
windows.length > 0 &&
(!(windows.length == 1 && windows[0].skip_taskbar) || (!(windows.length == 1 && windows[0].skip_taskbar) ||
this.is_on_workspace(activeWorkspace))) this.is_on_workspace(activeWorkspace))
return Main.activateWindow(windows[0]); )
return Main.activateWindow(windows[0])
return this.open_new_window(-1); return this.open_new_window(-1)
} }
this._signalsHandler.add([ this._signalsHandler.add([
SETTINGS, SETTINGS,
'changed::isolate-workspaces', 'changed::isolate-workspaces',
() => { () => {
this._panel.panelManager.allPanels.forEach(p => p.taskbar.resetAppIcons()); this._panel.panelManager.allPanels.forEach((p) =>
p.taskbar.resetAppIcons(),
)
if (SETTINGS.get_boolean('isolate-workspaces')) if (SETTINGS.get_boolean('isolate-workspaces')) enable()
enable(); else disable()
else },
disable(); ])
}
]);
if (SETTINGS.get_boolean('isolate-workspaces')) if (SETTINGS.get_boolean('isolate-workspaces')) enable()
enable();
} }
// Hotkeys // Hotkeys
_activateApp(appIndex, modifiers) { _activateApp(appIndex, modifiers) {
let seenApps = {}; let seenApps = {}
let apps = []; let apps = []
this.taskbar._getAppIcons().forEach(appIcon => { this.taskbar._getAppIcons().forEach((appIcon) => {
if (!seenApps[appIcon.app] || this.taskbar.allowSplitApps) { if (!seenApps[appIcon.app] || this.taskbar.allowSplitApps) {
apps.push(appIcon); apps.push(appIcon)
} }
seenApps[appIcon.app] = (seenApps[appIcon.app] || 0) + 1; seenApps[appIcon.app] = (seenApps[appIcon.app] || 0) + 1
}); })
this._showOverlay(); this._showOverlay()
if (appIndex < apps.length) { if (appIndex < apps.length) {
let appIcon = apps[appIndex]; let appIcon = apps[appIndex]
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 (SETTINGS.get_boolean('shortcut-previews') && windowCount > 1 && if (
!(modifiers & ~(Clutter.ModifierType.MOD1_MASK | Clutter.ModifierType.SUPER_MASK))) { //ignore the alt (MOD1_MASK) and super key (SUPER_MASK) SETTINGS.get_boolean('shortcut-previews') &&
if (this._hotkeyPreviewCycleInfo && this._hotkeyPreviewCycleInfo.appIcon != appIcon) { windowCount > 1 &&
this._endHotkeyPreviewCycle(); !(
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
) {
this._endHotkeyPreviewCycle()
} }
if (!this._hotkeyPreviewCycleInfo) { if (!this._hotkeyPreviewCycleInfo) {
this._hotkeyPreviewCycleInfo = { this._hotkeyPreviewCycleInfo = {
appIcon: appIcon, appIcon: appIcon,
currentWindow: appIcon.window, currentWindow: appIcon.window,
keyFocusOutId: appIcon.connect('key-focus-out', () => appIcon.grab_key_focus()), keyFocusOutId: appIcon.connect('key-focus-out', () =>
capturedEventId: global.stage.connect('captured-event', (actor, e) => { appIcon.grab_key_focus(),
if (e.type() == Clutter.EventType.KEY_RELEASE && e.get_key_symbol() == (Clutter.KEY_Super_L || Clutter.Super_L)) { ),
this._endHotkeyPreviewCycle(true); 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)
) {
this._endHotkeyPreviewCycle(true)
} }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE
}) },
}; ),
appIcon._hotkeysCycle = appIcon.window;
appIcon.window = null;
appIcon._previewMenu.open(appIcon, true);
appIcon.grab_key_focus();
} }
appIcon._previewMenu.focusNext(); appIcon._hotkeysCycle = appIcon.window
appIcon.window = null
appIcon._previewMenu.open(appIcon, true)
appIcon.grab_key_focus()
}
appIcon._previewMenu.focusNext()
} else { } else {
// 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, modifiers, !this.taskbar.allowSplitApps); appIcon.activate(button, modifiers, !this.taskbar.allowSplitApps)
} }
} }
} }
_endHotkeyPreviewCycle(focusWindow) { _endHotkeyPreviewCycle(focusWindow) {
if (this._hotkeyPreviewCycleInfo) { if (this._hotkeyPreviewCycleInfo) {
global.stage.disconnect(this._hotkeyPreviewCycleInfo.capturedEventId); global.stage.disconnect(this._hotkeyPreviewCycleInfo.capturedEventId)
this._hotkeyPreviewCycleInfo.appIcon.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 } else this._hotkeyPreviewCycleInfo.appIcon._previewMenu.close()
this._hotkeyPreviewCycleInfo.appIcon._previewMenu.close()
this._hotkeyPreviewCycleInfo.appIcon.window = this._hotkeyPreviewCycleInfo.currentWindow; this._hotkeyPreviewCycleInfo.appIcon.window =
delete this._hotkeyPreviewCycleInfo.appIcon._hotkeysCycle; this._hotkeyPreviewCycleInfo.currentWindow
this._hotkeyPreviewCycleInfo = 0; delete this._hotkeyPreviewCycleInfo.appIcon._hotkeysCycle
this._hotkeyPreviewCycleInfo = 0
} }
} }
_optionalHotKeys() { _optionalHotKeys() {
this._hotKeysEnabled = false; this._hotKeysEnabled = false
if (SETTINGS.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys')) this._enableHotKeys()
this._enableHotKeys();
this._signalsHandler.add([ this._signalsHandler.add([
SETTINGS, SETTINGS,
'changed::hot-keys', 'changed::hot-keys',
() => { () => {
if (SETTINGS.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys')) this._enableHotKeys()
this._enableHotKeys(); else this._disableHotKeys()
else },
this._disableHotKeys(); ])
}
]);
} }
_resetHotkeys() { _resetHotkeys() {
this._disableHotKeys(); this._disableHotKeys()
this._enableHotKeys(); this._enableHotKeys()
} }
_enableHotKeys() { _enableHotKeys() {
if (this._hotKeysEnabled) if (this._hotKeysEnabled) return
return;
//3.32 introduced app hotkeys, disable them to prevent conflicts //3.32 introduced app hotkeys, disable them to prevent conflicts
if (Main.wm._switchToApplication) { if (Main.wm._switchToApplication) {
for (let i = 1; i < 10; ++i) { for (let i = 1; i < 10; ++i) {
Utils.removeKeybinding(GS_HOTKEYS_KEY + i); Utils.removeKeybinding(GS_HOTKEYS_KEY + i)
} }
} }
// Setup keyboard bindings for taskbar elements // Setup keyboard bindings for taskbar elements
let shortcutNumKeys = 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 let prefixModifiers = Clutter.ModifierType.SUPER_MASK
if (SETTINGS.get_string('hotkey-prefix-text') == 'SuperAlt') if (SETTINGS.get_string('hotkey-prefix-text') == 'SuperAlt')
prefixModifiers |= Clutter.ModifierType.MOD1_MASK 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
} }
if (bothNumKeys || shortcutNumKeys == 'NUM_KEYPAD') { if (bothNumKeys || shortcutNumKeys == 'NUM_KEYPAD') {
keys.push('app-hotkey-kp-', 'app-shift-hotkey-kp-', 'app-ctrl-hotkey-kp-'); // Key-pad numbers keys.push('app-hotkey-kp-', 'app-shift-hotkey-kp-', 'app-ctrl-hotkey-kp-') // Key-pad numbers
} }
keys.forEach( function(key) { keys.forEach(function (key) {
let modifiers = prefixModifiers let modifiers = prefixModifiers
// for some reason, in gnome-shell >= 40 Clutter.get_current_event() is now empty // 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 // for keyboard events. Create here the modifiers that are needed in appicon.activate
modifiers |= (key.indexOf('-shift-') >= 0 ? Clutter.ModifierType.SHIFT_MASK : 0) modifiers |=
modifiers |= (key.indexOf('-ctrl-') >= 0 ? Clutter.ModifierType.CONTROL_MASK : 0) 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), SETTINGS, () => this._activateApp(appNum, modifiers)); Utils.addKeybinding(key + (i + 1), SETTINGS, () =>
this._activateApp(appNum, modifiers),
)
} }
}, this); }, this)
this._hotKeysEnabled = true; this._hotKeysEnabled = true
if (SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS') if (SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS')
this.taskbar.toggleNumberOverlay(true); this.taskbar.toggleNumberOverlay(true)
} }
_disableHotKeys() { _disableHotKeys() {
if (!this._hotKeysEnabled) if (!this._hotKeysEnabled) return
return;
let keys = ['app-hotkey-', 'app-shift-hotkey-', 'app-ctrl-hotkey-', // Regular numbers let keys = [
'app-hotkey-kp-', 'app-shift-hotkey-kp-', 'app-ctrl-hotkey-kp-']; // Key-pad numbers 'app-hotkey-',
keys.forEach( function(key) { 'app-shift-hotkey-',
'app-ctrl-hotkey-', // Regular numbers
'app-hotkey-kp-',
'app-shift-hotkey-kp-',
'app-ctrl-hotkey-kp-',
] // Key-pad numbers
keys.forEach(function (key) {
for (let i = 0; i < this._numHotkeys; i++) { for (let i = 0; i < this._numHotkeys; i++) {
Utils.removeKeybinding(key + (i + 1)); Utils.removeKeybinding(key + (i + 1))
} }
}, this); }, this)
if (Main.wm._switchToApplication) { if (Main.wm._switchToApplication) {
let gsSettings = new Gio.Settings({ schema_id: 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),
)
} }
} }
this._hotKeysEnabled = false; this._hotKeysEnabled = false
this.taskbar.toggleNumberOverlay(false); this.taskbar.toggleNumberOverlay(false)
} }
_optionalNumberOverlay() { _optionalNumberOverlay() {
// Enable extra shortcut // Enable extra shortcut
if (SETTINGS.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys')) this._enableExtraShortcut()
this._enableExtraShortcut();
this._signalsHandler.add([ this._signalsHandler.add(
SETTINGS, [SETTINGS, 'changed::hot-keys', this._checkHotkeysOptions.bind(this)],
'changed::hot-keys', [
this._checkHotkeysOptions.bind(this)
], [
SETTINGS, SETTINGS,
'changed::hotkeys-overlay-combo', 'changed::hotkeys-overlay-combo',
() => { () => {
if (SETTINGS.get_boolean('hot-keys') && SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS') if (
this.taskbar.toggleNumberOverlay(true); SETTINGS.get_boolean('hot-keys') &&
else SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS'
this.taskbar.toggleNumberOverlay(false); )
} this.taskbar.toggleNumberOverlay(true)
], [ else this.taskbar.toggleNumberOverlay(false)
SETTINGS, },
'changed::shortcut-num-keys', ],
() => this._resetHotkeys() [SETTINGS, 'changed::shortcut-num-keys', () => this._resetHotkeys()],
]); )
} }
_checkHotkeysOptions() { _checkHotkeysOptions() {
if (SETTINGS.get_boolean('hot-keys')) if (SETTINGS.get_boolean('hot-keys')) this._enableExtraShortcut()
this._enableExtraShortcut(); else this._disableExtraShortcut()
else
this._disableExtraShortcut();
} }
_enableExtraShortcut() { _enableExtraShortcut() {
Utils.addKeybinding('shortcut', SETTINGS, () => this._showOverlay(true)); Utils.addKeybinding('shortcut', SETTINGS, () => this._showOverlay(true))
} }
_disableExtraShortcut() { _disableExtraShortcut() {
Utils.removeKeybinding('shortcut'); Utils.removeKeybinding('shortcut')
} }
_showOverlay(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
let hotkey_option = SETTINGS.get_string('hotkeys-overlay-combo'); let hotkey_option = SETTINGS.get_string('hotkeys-overlay-combo')
if (hotkey_option === 'NEVER') if (hotkey_option === 'NEVER') return
return;
if (hotkey_option === 'TEMPORARILY' || overlayFromShortcut) if (hotkey_option === 'TEMPORARILY' || overlayFromShortcut)
this.taskbar.toggleNumberOverlay(true); this.taskbar.toggleNumberOverlay(true)
this._panel.intellihide.revealAndHold(Intellihide.Hold.TEMPORARY); this._panel.intellihide.revealAndHold(Intellihide.Hold.TEMPORARY)
let timeout = SETTINGS.get_int('overlay-timeout'); let timeout = SETTINGS.get_int('overlay-timeout')
if (overlayFromShortcut) { if (overlayFromShortcut) {
timeout = SETTINGS.get_int('shortcut-timeout'); timeout = SETTINGS.get_int('shortcut-timeout')
} }
// Hide the overlay/dock after the timeout // Hide the overlay/dock after the timeout
this._timeoutsHandler.add([T2, timeout, () => { this._timeoutsHandler.add([
T2,
timeout,
() => {
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)
}]); },
])
} }
_optionalClickToExit() { _optionalClickToExit() {
this._clickToExitEnabled = false; this._clickToExitEnabled = false
if (SETTINGS.get_boolean('overview-click-to-exit')) if (SETTINGS.get_boolean('overview-click-to-exit'))
this._enableClickToExit(); this._enableClickToExit()
this._signalsHandler.add([ this._signalsHandler.add([
SETTINGS, SETTINGS,
'changed::overview-click-to-exit', 'changed::overview-click-to-exit',
() => { () => {
if (SETTINGS.get_boolean('overview-click-to-exit')) if (SETTINGS.get_boolean('overview-click-to-exit'))
this._enableClickToExit(); this._enableClickToExit()
else else this._disableClickToExit()
this._disableClickToExit(); },
} ])
]);
} }
_enableClickToExit() { _enableClickToExit() {
if (this._clickToExitEnabled) if (this._clickToExitEnabled) return
return;
this._signalsHandler.addWithLabel('click-to-exit', [ this._signalsHandler.addWithLabel('click-to-exit', [
Main.layoutManager.overviewGroup, Main.layoutManager.overviewGroup,
'button-release-event', 'button-release-event',
() => { () => {
let [x, y] = global.get_pointer(); let [x, y] = global.get_pointer()
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y); let pickedActor = global.stage.get_actor_at_pos(
Clutter.PickMode.REACTIVE,
x,
y,
)
if (pickedActor) { if (pickedActor) {
let parent = pickedActor.get_parent(); let parent = pickedActor.get_parent()
if ( if (
( (pickedActor.has_style_class_name &&
pickedActor.has_style_class_name &&
pickedActor.has_style_class_name('apps-scroll-view') && pickedActor.has_style_class_name('apps-scroll-view') &&
!pickedActor.has_style_pseudo_class('first-child') !pickedActor.has_style_pseudo_class('first-child')) ||
) || ( (parent?.has_style_class_name &&
parent?.has_style_class_name && parent.has_style_class_name('window-picker')) ||
parent.has_style_class_name('window-picker') Main.overview._overview._controls._searchEntryBin.contains(
pickedActor,
) || ) ||
Main.overview._overview._controls._searchEntryBin.contains(pickedActor) ||
pickedActor instanceof WindowPreview pickedActor instanceof WindowPreview
) )
return Clutter.EVENT_PROPAGATE return Clutter.EVENT_PROPAGATE
} }
Main.overview.toggle() Main.overview.toggle()
} },
]); ])
this._clickToExitEnabled = true; this._clickToExitEnabled = true
} }
_disableClickToExit() { _disableClickToExit() {
if (!this._clickToExitEnabled) if (!this._clickToExitEnabled) return
return;
this._signalsHandler.removeWithLabel('click-to-exit') this._signalsHandler.removeWithLabel('click-to-exit')
this._clickToExitEnabled = false; this._clickToExitEnabled = false
} }
_onSwipeBegin() { _onSwipeBegin() {
this._swiping = true; this._swiping = true
return true; return true
} }
_onSwipeEnd() { _onSwipeEnd() {
this._timeoutsHandler.add([ this._timeoutsHandler.add([T1, 0, () => (this._swiping = false)])
T1, return true
0,
() => this._swiping = false
]);
return true;
} }
} }

13
package.json Normal file
View File

@@ -0,0 +1,13 @@
{
"type": "module",
"scripts": {
"lint": "prettier 'src/**/*.js' --write && eslint 'src/**/*.js' --fix"
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"eslint": "^9.19.0",
"eslint-config-prettier": "^10.0.1",
"globals": "^15.14.0",
"prettier": "^3.4.2"
}
}

1479
panel.js

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -15,29 +15,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
export const SHOW_APPS_BTN = 'showAppsButton'; export const SHOW_APPS_BTN = 'showAppsButton'
export const ACTIVITIES_BTN = 'activitiesButton'; export const ACTIVITIES_BTN = 'activitiesButton'
export const TASKBAR = 'taskbar'; export const TASKBAR = 'taskbar'
export const DATE_MENU = 'dateMenu'; export const DATE_MENU = 'dateMenu'
export const SYSTEM_MENU = 'systemMenu'; export const SYSTEM_MENU = 'systemMenu'
export const LEFT_BOX = 'leftBox'; export const LEFT_BOX = 'leftBox'
export const CENTER_BOX = 'centerBox'; export const CENTER_BOX = 'centerBox'
export const RIGHT_BOX = 'rightBox'; export const RIGHT_BOX = 'rightBox'
export const DESKTOP_BTN = 'desktopButton'; export const DESKTOP_BTN = 'desktopButton'
export const STACKED_TL = 'stackedTL'; export const STACKED_TL = 'stackedTL'
export const STACKED_BR = 'stackedBR'; export const STACKED_BR = 'stackedBR'
export const CENTERED = 'centered'; export const CENTERED = 'centered'
export const CENTERED_MONITOR = 'centerMonitor'; export const CENTERED_MONITOR = 'centerMonitor'
export const TOP = 'TOP'; export const TOP = 'TOP'
export const BOTTOM = 'BOTTOM'; export const BOTTOM = 'BOTTOM'
export const LEFT = 'LEFT'; export const LEFT = 'LEFT'
export const RIGHT = 'RIGHT'; export const RIGHT = 'RIGHT'
export const START = 'START'; export const START = 'START'
export const MIDDLE = 'MIDDLE'; export const MIDDLE = 'MIDDLE'
export const END = 'END'; export const END = 'END'
export const defaults = [ export const defaults = [
{ element: SHOW_APPS_BTN, visible: true, position: STACKED_TL }, { element: SHOW_APPS_BTN, visible: true, position: STACKED_TL },
@@ -49,13 +49,13 @@ export const defaults = [
{ element: DATE_MENU, visible: true, position: STACKED_BR }, { element: DATE_MENU, visible: true, position: STACKED_BR },
{ element: SYSTEM_MENU, visible: true, position: STACKED_BR }, { element: SYSTEM_MENU, visible: true, position: STACKED_BR },
{ element: DESKTOP_BTN, visible: true, position: STACKED_BR }, { element: DESKTOP_BTN, visible: true, position: STACKED_BR },
]; ]
export const optionDialogFunctions = {}; export const optionDialogFunctions = {}
optionDialogFunctions[SHOW_APPS_BTN] = '_showShowAppsButtonOptions'; optionDialogFunctions[SHOW_APPS_BTN] = '_showShowAppsButtonOptions'
optionDialogFunctions[DESKTOP_BTN] = '_showDesktopButtonOptions'; optionDialogFunctions[DESKTOP_BTN] = '_showDesktopButtonOptions'
export function checkIfCentered(position) { export function checkIfCentered(position) {
return position == CENTERED || position == CENTERED_MONITOR; return position == CENTERED || position == CENTERED_MONITOR
} }

View File

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

View File

@@ -21,294 +21,323 @@
* mathematical.coffee@gmail.com * mathematical.coffee@gmail.com
*/ */
import * as Utils from './utils.js'; import * as Utils from './utils.js'
import {SETTINGS} from './extension.js'; import { SETTINGS } from './extension.js'
export const PanelStyle = class { export const PanelStyle = class {
enable(panel) { enable(panel) {
this.panel = panel; this.panel = panel
this._applyStyles(); this._applyStyles()
this._bindSettingsChanges(); this._bindSettingsChanges()
} }
disable() { disable() {
for (let i = 0; i < this._dtpSettingsSignalIds.length; ++i) { for (let i = 0; i < this._dtpSettingsSignalIds.length; ++i) {
SETTINGS.disconnect(this._dtpSettingsSignalIds[i]); SETTINGS.disconnect(this._dtpSettingsSignalIds[i])
} }
this._removeStyles(); this._removeStyles()
} }
_bindSettingsChanges() { _bindSettingsChanges() {
let configKeys = [ let configKeys = [
"tray-size", 'tray-size',
"leftbox-size", 'leftbox-size',
"tray-padding", 'tray-padding',
"leftbox-padding", 'leftbox-padding',
"status-icon-padding", 'status-icon-padding',
]; ]
this._dtpSettingsSignalIds = []; this._dtpSettingsSignalIds = []
for(let i in configKeys) { for (let i in configKeys) {
this._dtpSettingsSignalIds.push(SETTINGS.connect('changed::' + configKeys[i], () => { this._dtpSettingsSignalIds.push(
this._removeStyles(); SETTINGS.connect('changed::' + configKeys[i], () => {
this._applyStyles(); this._removeStyles()
})); this._applyStyles()
}),
)
} }
} }
_applyStyles() { _applyStyles() {
this._rightBoxOperations = []; this._rightBoxOperations = []
let trayPadding = SETTINGS.get_int('tray-padding'); let trayPadding = SETTINGS.get_int('tray-padding')
let isVertical = this.panel.checkIfVertical(); let isVertical = this.panel.checkIfVertical()
let paddingStyle = 'padding: ' + (isVertical ? '%dpx 0' : '0 %dpx'); let paddingStyle = 'padding: ' + (isVertical ? '%dpx 0' : '0 %dpx')
if(trayPadding >= 0) { if (trayPadding >= 0) {
let operation = {}; let operation = {}
let trayPaddingStyleLine; let trayPaddingStyleLine
if (isVertical) { if (isVertical) {
trayPaddingStyleLine = paddingStyle.format(trayPadding); trayPaddingStyleLine = paddingStyle.format(trayPadding)
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
let parent = actor.get_parent(); let parent = actor.get_parent()
return ((parent && parent.has_style_class_name && (parent.has_style_class_name('panel-button') && !parent.has_style_class_name('clock-display'))) || return (
(actor.has_style_class_name && actor.has_style_class_name('clock'))); (parent &&
}; parent.has_style_class_name &&
parent.has_style_class_name('panel-button') &&
!parent.has_style_class_name('clock-display')) ||
(actor.has_style_class_name && actor.has_style_class_name('clock'))
)
}
} else { } else {
trayPaddingStyleLine = '-natural-hpadding: %dpx'.format(trayPadding); trayPaddingStyleLine = '-natural-hpadding: %dpx'.format(trayPadding)
if (trayPadding < 6) { if (trayPadding < 6) {
trayPaddingStyleLine += '; -minimum-hpadding: %dpx'.format(trayPadding); trayPaddingStyleLine += '; -minimum-hpadding: %dpx'.format(
trayPadding,
)
} }
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
return (actor.has_style_class_name && actor.has_style_class_name('panel-button')); return (
}; actor.has_style_class_name &&
actor.has_style_class_name('panel-button')
)
}
} }
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, trayPaddingStyleLine, operationIdx); this._overrideStyle(actor, trayPaddingStyleLine, operationIdx)
this._refreshPanelButton(actor); this._refreshPanelButton(actor)
}; }
this._rightBoxOperations.push(operation); this._rightBoxOperations.push(operation)
} }
let statusIconPadding = SETTINGS.get_int('status-icon-padding'); let statusIconPadding = SETTINGS.get_int('status-icon-padding')
if(statusIconPadding >= 0) { if (statusIconPadding >= 0) {
let statusIconPaddingStyleLine = paddingStyle.format(statusIconPadding) let statusIconPaddingStyleLine = paddingStyle.format(statusIconPadding)
let operation = {}; let operation = {}
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
return (actor.has_style_class_name && actor.has_style_class_name('system-status-icon')); return (
}; actor.has_style_class_name &&
actor.has_style_class_name('system-status-icon')
)
}
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, statusIconPaddingStyleLine, operationIdx); this._overrideStyle(actor, statusIconPaddingStyleLine, operationIdx)
}; }
this._rightBoxOperations.push(operation); this._rightBoxOperations.push(operation)
} }
let trayContentSize = SETTINGS.get_int('tray-size'); let trayContentSize = SETTINGS.get_int('tray-size')
if(trayContentSize > 0) { if (trayContentSize > 0) {
let trayIconSizeStyleLine = 'icon-size: %dpx'.format(trayContentSize) let trayIconSizeStyleLine = 'icon-size: %dpx'.format(trayContentSize)
let operation = {}; let operation = {}
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
return (actor.constructor && actor.constructor.name == 'St_Icon'); return actor.constructor && actor.constructor.name == 'St_Icon'
}; }
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, trayIconSizeStyleLine, operationIdx); this._overrideStyle(actor, trayIconSizeStyleLine, operationIdx)
}; }
this._rightBoxOperations.push(operation); this._rightBoxOperations.push(operation)
let trayContentSizeStyleLine = 'font-size: %dpx'.format(trayContentSize) let trayContentSizeStyleLine = 'font-size: %dpx'.format(trayContentSize)
operation = {}; operation = {}
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
return (actor.constructor && actor.constructor.name == 'St_Label'); return actor.constructor && actor.constructor.name == 'St_Label'
}; }
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, trayContentSizeStyleLine, operationIdx); this._overrideStyle(actor, trayContentSizeStyleLine, operationIdx)
}; }
this._rightBoxOperations.push(operation); this._rightBoxOperations.push(operation)
this._overrideStyle(this.panel._rightBox, trayContentSizeStyleLine, 0); this._overrideStyle(this.panel._rightBox, trayContentSizeStyleLine, 0)
this._overrideStyle(this.panel._centerBox, trayContentSizeStyleLine, 0); this._overrideStyle(this.panel._centerBox, trayContentSizeStyleLine, 0)
} }
// 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
this._leftBoxOperations = []; this._leftBoxOperations = []
let leftboxPadding = SETTINGS.get_int('leftbox-padding'); let leftboxPadding = SETTINGS.get_int('leftbox-padding')
if(leftboxPadding >= 0) { if (leftboxPadding >= 0) {
let leftboxPaddingStyleLine = paddingStyle.format(leftboxPadding); let leftboxPaddingStyleLine = paddingStyle.format(leftboxPadding)
let operation = {}; let operation = {}
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
let parent = actor.get_parent(); let parent = actor.get_parent()
return (parent && parent.has_style_class_name && parent.has_style_class_name('panel-button')); return (
}; parent &&
parent.has_style_class_name &&
parent.has_style_class_name('panel-button')
)
}
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, leftboxPaddingStyleLine, operationIdx); this._overrideStyle(actor, leftboxPaddingStyleLine, operationIdx)
}; }
this._leftBoxOperations.push(operation); this._leftBoxOperations.push(operation)
} }
let leftboxContentSize = SETTINGS.get_int('leftbox-size'); let leftboxContentSize = SETTINGS.get_int('leftbox-size')
if(leftboxContentSize > 0) { if (leftboxContentSize > 0) {
let leftboxIconSizeStyleLine = 'icon-size: %dpx'.format(leftboxContentSize) let leftboxIconSizeStyleLine = 'icon-size: %dpx'.format(
let operation = {}; leftboxContentSize,
)
let operation = {}
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
return (actor.constructor && actor.constructor.name == 'St_Icon'); return actor.constructor && actor.constructor.name == 'St_Icon'
}; }
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, leftboxIconSizeStyleLine, operationIdx); this._overrideStyle(actor, leftboxIconSizeStyleLine, operationIdx)
}; }
this._leftBoxOperations.push(operation); this._leftBoxOperations.push(operation)
let leftboxContentSizeStyleLine = 'font-size: %dpx'.format(leftboxContentSize) let leftboxContentSizeStyleLine = 'font-size: %dpx'.format(
operation = {}; leftboxContentSize,
)
operation = {}
operation.compareFn = function (actor) { operation.compareFn = function (actor) {
return (actor.constructor && actor.constructor.name == 'St_Label'); return actor.constructor && actor.constructor.name == 'St_Label'
}; }
operation.applyFn = (actor, operationIdx) => { operation.applyFn = (actor, operationIdx) => {
this._overrideStyle(actor, leftboxContentSizeStyleLine, operationIdx); this._overrideStyle(actor, leftboxContentSizeStyleLine, operationIdx)
}; }
this._leftBoxOperations.push(operation); this._leftBoxOperations.push(operation)
this._overrideStyle(this.panel._leftBox, leftboxContentSizeStyleLine, 0); this._overrideStyle(this.panel._leftBox, leftboxContentSizeStyleLine, 0)
} }
this._applyStylesRecursively(); this._applyStylesRecursively()
/* connect signal */ /* connect signal */
this._rightBoxActorAddedID = this.panel._rightBox.connect('child-added', this._rightBoxActorAddedID = this.panel._rightBox.connect(
'child-added',
(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('child-added', this._centerBoxActorAddedID = this.panel._centerBox.connect(
'child-added',
(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('child-added', this._leftBoxActorAddedID = this.panel._leftBox.connect(
'child-added',
(container, actor) => { (container, actor) => {
if(this._leftBoxOperations.length) if (this._leftBoxOperations.length)
this._recursiveApply(actor, this._leftBoxOperations); this._recursiveApply(actor, this._leftBoxOperations)
} },
); )
} }
_removeStyles() { _removeStyles() {
/* disconnect signal */ /* disconnect signal */
if (this._rightBoxActorAddedID) if (this._rightBoxActorAddedID)
this.panel._rightBox.disconnect(this._rightBoxActorAddedID); this.panel._rightBox.disconnect(this._rightBoxActorAddedID)
if (this._centerBoxActorAddedID) if (this._centerBoxActorAddedID)
this.panel._centerBox.disconnect(this._centerBoxActorAddedID); this.panel._centerBox.disconnect(this._centerBoxActorAddedID)
if (this._leftBoxActorAddedID) if (this._leftBoxActorAddedID)
this.panel._leftBox.disconnect(this._leftBoxActorAddedID); this.panel._leftBox.disconnect(this._leftBoxActorAddedID)
this._restoreOriginalStyle(this.panel._rightBox); this._restoreOriginalStyle(this.panel._rightBox)
this._restoreOriginalStyle(this.panel._centerBox); this._restoreOriginalStyle(this.panel._centerBox)
this._restoreOriginalStyle(this.panel._leftBox); this._restoreOriginalStyle(this.panel._leftBox)
this._applyStylesRecursively(true); this._applyStylesRecursively(true)
} }
_applyStylesRecursively(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[Utils.getSystemMenuInfo().name].container]); let children = this.panel._rightBox
for(let i in children) .get_children()
this._recursiveApply(children[i], this._rightBoxOperations, restore); .concat([
this.panel.statusArea[Utils.getSystemMenuInfo().name].container,
])
for (let i in children)
this._recursiveApply(children[i], this._rightBoxOperations, restore)
} }
if(this._centerBoxOperations.length) { if (this._centerBoxOperations.length) {
// add the date menu as we move it from the centerbox to the panel to position it independently // add the date menu as we move it from the centerbox to the panel to position it independently
let children = this.panel._centerBox.get_children().concat([this.panel.statusArea.dateMenu.container]); let children = this.panel._centerBox
for(let i in children) .get_children()
this._recursiveApply(children[i], this._centerBoxOperations, restore); .concat([this.panel.statusArea.dateMenu.container])
for (let i in children)
this._recursiveApply(children[i], this._centerBoxOperations, restore)
} }
if(this._leftBoxOperations.length) { if (this._leftBoxOperations.length) {
let children = this.panel._leftBox.get_children(); let children = this.panel._leftBox.get_children()
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(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))
if(restore) if (restore)
o.restoreFn ? o.restoreFn(actor) : this._restoreOriginalStyle(actor); o.restoreFn ? o.restoreFn(actor) : this._restoreOriginalStyle(actor)
else else o.applyFn(actor, i)
o.applyFn(actor, i);
} }
if(actor.get_children) { if (actor.get_children) {
let children = actor.get_children(); let children = actor.get_children()
for(let i in children) { for (let i in children) {
this._recursiveApply(children[i], operations, restore); this._recursiveApply(children[i], operations, restore)
} }
} }
} }
_overrideStyle(actor, styleLine, operationIdx) { _overrideStyle(actor, styleLine, operationIdx) {
if (actor._dtp_original_inline_style === undefined) { if (actor._dtp_original_inline_style === undefined) {
actor._dtp_original_inline_style = actor.get_style(); actor._dtp_original_inline_style = actor.get_style()
} }
if(actor._dtp_style_overrides === undefined) { if (actor._dtp_style_overrides === undefined) {
actor._dtp_style_overrides = {}; actor._dtp_style_overrides = {}
} }
actor._dtp_style_overrides[operationIdx] = styleLine; actor._dtp_style_overrides[operationIdx] = styleLine
let newStyleLine = ''; let newStyleLine = ''
for(let i in actor._dtp_style_overrides) for (let i in actor._dtp_style_overrides)
newStyleLine += actor._dtp_style_overrides[i] + '; '; newStyleLine += actor._dtp_style_overrides[i] + '; '
actor.set_style(newStyleLine + (actor._dtp_original_inline_style || '')); actor.set_style(newStyleLine + (actor._dtp_original_inline_style || ''))
} }
_restoreOriginalStyle(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
delete actor._dtp_style_overrides; delete actor._dtp_style_overrides
} }
if (actor.has_style_class_name('panel-button')) { if (actor.has_style_class_name('panel-button')) {
this._refreshPanelButton(actor); this._refreshPanelButton(actor)
} }
} }
_refreshPanelButton(actor) { _refreshPanelButton(actor) {
if (actor.visible) { 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()
let actorIndex = 0; let actorIndex = 0
if (children.length > 1) { if (children.length > 1) {
actorIndex = children.indexOf(actor); actorIndex = children.indexOf(actor)
} }
this._ignoreAddedChild = [this.panel._centerBox, this.panel._rightBox].indexOf(parent) >= 0; this._ignoreAddedChild =
[this.panel._centerBox, this.panel._rightBox].indexOf(parent) >= 0
parent.remove_child(actor); parent.remove_child(actor)
parent.insert_child_at_index(actor, actorIndex); parent.insert_child_at_index(actor, actorIndex)
} }
} }
} }

4269
prefs.js

File diff suppressed because it is too large Load Diff

View File

@@ -19,260 +19,285 @@
* This file is based on code from the Dash to Dock extension by micheleg * This file is based on code from the Dash to Dock extension by micheleg
*/ */
import Cairo from 'cairo'; import Cairo from 'cairo'
import Gio from 'gi://Gio'; import Gio from 'gi://Gio'
import Clutter from 'gi://Clutter'; import Clutter from 'gi://Clutter'
import Pango from 'gi://Pango'; import Pango from 'gi://Pango'
import St from 'gi://St'; import St from 'gi://St'
import * as Utils from './utils.js'; import * as Utils from './utils.js'
import {SETTINGS} from './extension.js'; import { SETTINGS } from './extension.js'
import {EventEmitter} from 'resource:///org/gnome/shell/misc/signals.js';
import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js'
export const ProgressManager = class extends EventEmitter { export const ProgressManager = class extends EventEmitter {
constructor() { constructor() {
super(); super()
this._entriesByDBusName = {}; this._entriesByDBusName = {}
this._launcher_entry_dbus_signal_id = this._launcher_entry_dbus_signal_id = Gio.DBus.session.signal_subscribe(
Gio.DBus.session.signal_subscribe(null, // sender null, // sender
'com.canonical.Unity.LauncherEntry', // iface 'com.canonical.Unity.LauncherEntry', // iface
null, // member null, // member
null, // path null, // path
null, // arg0 null, // arg0
Gio.DBusSignalFlags.NONE, Gio.DBusSignalFlags.NONE,
this._onEntrySignalReceived.bind(this)); this._onEntrySignalReceived.bind(this),
)
this._dbus_name_owner_changed_signal_id = this._dbus_name_owner_changed_signal_id = Gio.DBus.session.signal_subscribe(
Gio.DBus.session.signal_subscribe('org.freedesktop.DBus', // sender 'org.freedesktop.DBus', // sender
'org.freedesktop.DBus', // interface 'org.freedesktop.DBus', // interface
'NameOwnerChanged', // member 'NameOwnerChanged', // member
'/org/freedesktop/DBus', // path '/org/freedesktop/DBus', // path
null, // arg0 null, // arg0
Gio.DBusSignalFlags.NONE, Gio.DBusSignalFlags.NONE,
this._onDBusNameOwnerChanged.bind(this)); this._onDBusNameOwnerChanged.bind(this),
)
this._acquireUnityDBus(); this._acquireUnityDBus()
} }
destroy() { 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)
} }
if (this._dbus_name_owner_changed_signal_id) { if (this._dbus_name_owner_changed_signal_id) {
Gio.DBus.session.signal_unsubscribe(this._dbus_name_owner_changed_signal_id); Gio.DBus.session.signal_unsubscribe(
this._dbus_name_owner_changed_signal_id,
)
} }
this._releaseUnityDBus(); this._releaseUnityDBus()
} }
size() { size() {
return Object.keys(this._entriesByDBusName).length; return Object.keys(this._entriesByDBusName).length
} }
lookupByDBusName(dbusName) { lookupByDBusName(dbusName) {
return this._entriesByDBusName.hasOwnProperty(dbusName) ? this._entriesByDBusName[dbusName] : null; return this._entriesByDBusName.hasOwnProperty(dbusName)
? this._entriesByDBusName[dbusName]
: null
} }
lookupById(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]
if (entry && entry.appId() == appId) { if (entry && entry.appId() == appId) {
ret.push(entry); ret.push(entry)
} }
} }
return ret; return ret
} }
addEntry(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)
} else { } else {
this._entriesByDBusName[entry.dbusName()] = entry; this._entriesByDBusName[entry.dbusName()] = entry
this.emit('progress-entry-added', entry); this.emit('progress-entry-added', entry)
} }
} }
removeEntry(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() { _acquireUnityDBus() {
if (!this._unity_bus_id) { if (!this._unity_bus_id) {
Gio.DBus.session.own_name('com.canonical.Unity', Gio.DBus.session.own_name(
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null); 'com.canonical.Unity',
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT,
null,
null,
)
} }
} }
_releaseUnityDBus() { _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(connection, sender_name, object_path, _onEntrySignalReceived(
interface_name, signal_name, parameters, user_data) { connection,
if (!parameters || !signal_name) sender_name,
return; object_path,
interface_name,
signal_name,
parameters,
user_data,
) {
if (!parameters || !signal_name) return
if (signal_name == 'Update') { if (signal_name == 'Update') {
if (!sender_name) { if (!sender_name) {
return; return
} }
this._handleUpdateRequest(sender_name, parameters); this._handleUpdateRequest(sender_name, parameters)
} }
} }
_onDBusNameOwnerChanged(connection, sender_name, object_path, _onDBusNameOwnerChanged(
interface_name, signal_name, parameters, user_data) { connection,
if (!parameters || !this.size()) sender_name,
return; object_path,
interface_name,
signal_name,
parameters,
user_data,
) {
if (!parameters || !this.size()) return
let [name, before, after] = parameters.deep_unpack(); let [name, before, after] = parameters.deep_unpack()
if (!after) { if (!after) {
if (this._entriesByDBusName.hasOwnProperty(before)) { if (this._entriesByDBusName.hasOwnProperty(before)) {
this.removeEntry(this._entriesByDBusName[before]); this.removeEntry(this._entriesByDBusName[before])
} }
} }
} }
_handleUpdateRequest(senderName, parameters) { _handleUpdateRequest(senderName, parameters) {
if (!senderName || !parameters) { if (!senderName || !parameters) {
return; return
} }
let [appUri, properties] = parameters.deep_unpack(); let [appUri, properties] = parameters.deep_unpack()
let appId = appUri.replace(/(^\w+:|^)\/\//, ''); let appId = appUri.replace(/(^\w+:|^)\/\//, '')
let entry = this.lookupByDBusName(senderName); let entry = this.lookupByDBusName(senderName)
if (entry) { if (entry) {
entry.setDBusName(senderName); entry.setDBusName(senderName)
entry.update(properties); entry.update(properties)
} else { } else {
let entry = new AppProgress(senderName, appId, properties); let entry = new AppProgress(senderName, appId, properties)
this.addEntry(entry); this.addEntry(entry)
} }
} }
}; }
export class AppProgress extends EventEmitter { export class AppProgress extends EventEmitter {
constructor(dbusName, appId, properties) { constructor(dbusName, appId, properties) {
super(); super()
this._dbusName = dbusName; this._dbusName = dbusName
this._appId = appId; this._appId = appId
this._count = 0; this._count = 0
this._countVisible = false; this._countVisible = false
this._progress = 0.0; this._progress = 0.0
this._progressVisible = false; this._progressVisible = false
this._urgent = false; this._urgent = false
this.update(properties); this.update(properties)
} }
appId() { appId() {
return this._appId; return this._appId
} }
dbusName() { dbusName() {
return this._dbusName; return this._dbusName
} }
count() { count() {
return this._count; return this._count
} }
setCount(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() { countVisible() {
return this._countVisible; return this._countVisible
} }
setCountVisible(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() { progress() {
return this._progress; return this._progress
} }
setProgress(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() { progressVisible() {
return this._progressVisible; return this._progressVisible
} }
setProgressVisible(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() { urgent() {
return this._urgent; return this._urgent
} }
setUrgent(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(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(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())
this.setCountVisible(other.countVisible()); this.setCountVisible(other.countVisible())
this.setProgress(other.progress()); this.setProgress(other.progress())
this.setProgressVisible(other.progressVisible()) this.setProgressVisible(other.progressVisible())
this.setUrgent(other.urgent()); this.setUrgent(other.urgent())
} else { } else {
for (let property in other) { for (let property in other) {
if (other.hasOwnProperty(property)) { if (other.hasOwnProperty(property)) {
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(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(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 {
// Not implemented yet // Not implemented yet
} }
@@ -282,316 +307,395 @@ export class AppProgress extends EventEmitter {
} }
} }
export const ProgressIndicator = class { export const ProgressIndicator = class {
constructor(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.connect('destroy', () => { this._sourceDestroyId = this._source.connect('destroy', () => {
this._signalsHandler.destroy(); this._signalsHandler.destroy()
}); })
this._notificationBadgeLabel = new St.Label({ style_class: 'badge' }); this._notificationBadgeLabel = new St.Label({ style_class: 'badge' })
this._notificationBadgeBin = new St.Bin({ this._notificationBadgeBin = new St.Bin({
child: this._notificationBadgeLabel, y: 2, x: 2 child: this._notificationBadgeLabel,
}); y: 2,
this._notificationBadgeLabel.add_style_class_name('notification-badge'); x: 2,
this._notificationBadgeCount = 0; })
this._notificationBadgeBin.hide(); this._notificationBadgeLabel.add_style_class_name('notification-badge')
this._notificationBadgeCount = 0
this._notificationBadgeBin.hide()
this._source._dtpIconContainer.add_child(this._notificationBadgeBin); this._source._dtpIconContainer.add_child(this._notificationBadgeBin)
this._source._dtpIconContainer.connect('notify::allocation', this.updateNotificationBadge.bind(this)); this._source._dtpIconContainer.connect(
'notify::allocation',
this.updateNotificationBadge.bind(this),
)
this._progressManagerEntries = []; this._progressManagerEntries = []
this._progressManager.lookupById(this._source.app.id).forEach( this._progressManager.lookupById(this._source.app.id).forEach((entry) => {
(entry) => { this.insertEntry(entry)
this.insertEntry(entry); })
}
);
this._signalsHandler.add([ this._signalsHandler.add(
[
this._progressManager, this._progressManager,
'progress-entry-added', 'progress-entry-added',
this._onEntryAdded.bind(this) this._onEntryAdded.bind(this),
], [ ],
[
this._progressManager, this._progressManager,
'progress-entry-removed', 'progress-entry-removed',
this._onEntryRemoved.bind(this) this._onEntryRemoved.bind(this),
]); ],
)
} }
destroy() { destroy() {
this._source.disconnect(this._sourceDestroyId); this._source.disconnect(this._sourceDestroyId)
this._signalsHandler.destroy(); this._signalsHandler.destroy()
} }
_onEntryAdded(appProgress, entry) { _onEntryAdded(appProgress, entry) {
if (!entry || !entry.appId()) if (!entry || !entry.appId()) return
return; if (
if (this._source && this._source.app && this._source.app.id == entry.appId()) { this._source &&
this.insertEntry(entry); this._source.app &&
this._source.app.id == entry.appId()
) {
this.insertEntry(entry)
} }
} }
_onEntryRemoved(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.removeEntry(entry); this._source &&
this._source.app &&
this._source.app.id == entry.appId()
) {
this.removeEntry(entry)
} }
} }
updateNotificationBadge() { 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(count) { _notificationBadgeCountToText(count) {
if (count <= 9999) { if (count <= 9999) {
return count.toString(); return count.toString()
} else if (count < 1e5) { } else if (count < 1e5) {
let thousands = count / 1e3; let thousands = count / 1e3
return thousands.toFixed(1).toString() + "k"; return thousands.toFixed(1).toString() + 'k'
} else if (count < 1e6) { } else if (count < 1e6) {
let thousands = count / 1e3; let thousands = count / 1e3
return thousands.toFixed(0).toString() + "k"; return thousands.toFixed(0).toString() + 'k'
} else if (count < 1e8) { } else if (count < 1e8) {
let millions = count / 1e6; let millions = count / 1e6
return millions.toFixed(1).toString() + "M"; return millions.toFixed(1).toString() + 'M'
} else if (count < 1e9) { } else if (count < 1e9) {
let millions = count / 1e6; let millions = count / 1e6
return millions.toFixed(0).toString() + "M"; return millions.toFixed(0).toString() + 'M'
} else { } else {
let billions = count / 1e9; let billions = count / 1e9
return billions.toFixed(1).toString() + "B"; return billions.toFixed(1).toString() + 'B'
} }
} }
setNotificationBadge(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(activate) { toggleNotificationBadge(activate) {
if (activate && this._notificationBadgeCount > 0) { if (activate && this._notificationBadgeCount > 0) {
this.updateNotificationBadge(); this.updateNotificationBadge()
this._notificationBadgeBin.show(); this._notificationBadgeBin.show()
} } else this._notificationBadgeBin.hide()
else
this._notificationBadgeBin.hide();
} }
_showProgressOverlay() { _showProgressOverlay() {
if (this._progressOverlayArea) { if (this._progressOverlayArea) {
this._updateProgressOverlay(); this._updateProgressOverlay()
return; return
} }
this._progressOverlayArea = new St.DrawingArea({x_expand: true, y_expand: true}); this._progressOverlayArea = new St.DrawingArea({
this._progressOverlayArea.add_style_class_name('progress-bar'); x_expand: true,
y_expand: true,
})
this._progressOverlayArea.add_style_class_name('progress-bar')
this._progressOverlayArea.connect('repaint', () => { this._progressOverlayArea.connect('repaint', () => {
this._drawProgressOverlay(this._progressOverlayArea); this._drawProgressOverlay(this._progressOverlayArea)
}); })
this._source._iconContainer.add_child(this._progressOverlayArea); this._source._iconContainer.add_child(this._progressOverlayArea)
let node = this._progressOverlayArea.get_theme_node(); let node = this._progressOverlayArea.get_theme_node()
let [hasColor, color] = node.lookup_color('-progress-bar-background', false); let [hasColor, color] = node.lookup_color('-progress-bar-background', false)
if (hasColor) if (hasColor) this._progressbar_background = color
this._progressbar_background = color
else else
this._progressbar_background = new Utils.ColorUtils.Color({red: 204, green: 204, blue: 204, alpha: 255}); this._progressbar_background = new Utils.ColorUtils.Color({
red: 204,
[hasColor, color] = node.lookup_color('-progress-bar-border', false); green: 204,
if (hasColor) blue: 204,
this._progressbar_border = color; alpha: 255,
})
;[hasColor, color] = node.lookup_color('-progress-bar-border', false)
if (hasColor) this._progressbar_border = color
else else
this._progressbar_border = new Utils.ColorUtils.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() { _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() { _updateProgressOverlay() {
if (this._progressOverlayArea) { if (this._progressOverlayArea) {
this._progressOverlayArea.queue_repaint(); this._progressOverlayArea.queue_repaint()
} }
} }
_drawProgressOverlay(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()
let iconSize = this._source.icon.iconSize * scaleFactor; let iconSize = this._source.icon.iconSize * scaleFactor
let x = Math.floor((surfaceWidth - iconSize) / 2); let x = Math.floor((surfaceWidth - iconSize) / 2)
let y = Math.floor((surfaceHeight - iconSize) / 2); let y = Math.floor((surfaceHeight - iconSize) / 2)
let lineWidth = Math.floor(1.0 * scaleFactor); let lineWidth = Math.floor(1.0 * scaleFactor)
let padding = Math.floor(iconSize * 0.05); let padding = Math.floor(iconSize * 0.05)
let width = iconSize - 2.0*padding; let width = iconSize - 2.0 * padding
let height = Math.floor(Math.min(18.0*scaleFactor, 0.20*iconSize)); let height = Math.floor(Math.min(18.0 * scaleFactor, 0.2 * iconSize))
x += padding; x += padding
y += iconSize - height - padding; y += iconSize - height - padding
cr.setLineWidth(lineWidth); cr.setLineWidth(lineWidth)
// Draw the outer stroke // Draw the outer stroke
let stroke = new Cairo.LinearGradient(0, y, 0, y + height); let stroke = new Cairo.LinearGradient(0, y, 0, y + height)
let fill = null; let fill = null
stroke.addColorStopRGBA(0.5, 0.5, 0.5, 0.5, 0.1); stroke.addColorStopRGBA(0.5, 0.5, 0.5, 0.5, 0.1)
stroke.addColorStopRGBA(0.9, 0.8, 0.8, 0.8, 0.4); stroke.addColorStopRGBA(0.9, 0.8, 0.8, 0.8, 0.4)
Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, width, height, true, true, stroke, fill); Utils.drawRoundedLine(
cr,
x + lineWidth / 2.0,
y + lineWidth / 2.0,
width,
height,
true,
true,
stroke,
fill,
)
// Draw the background // Draw the background
x += lineWidth; x += lineWidth
y += lineWidth; y += lineWidth
width -= 2.0*lineWidth; width -= 2.0 * lineWidth
height -= 2.0*lineWidth; height -= 2.0 * lineWidth
stroke = Cairo.SolidPattern.createRGBA(0.20, 0.20, 0.20, 0.9); stroke = Cairo.SolidPattern.createRGBA(0.2, 0.2, 0.2, 0.9)
fill = new Cairo.LinearGradient(0, y, 0, y + height); fill = new Cairo.LinearGradient(0, y, 0, y + height)
fill.addColorStopRGBA(0.4, 0.25, 0.25, 0.25, 1.0); fill.addColorStopRGBA(0.4, 0.25, 0.25, 0.25, 1.0)
fill.addColorStopRGBA(0.9, 0.35, 0.35, 0.35, 1.0); fill.addColorStopRGBA(0.9, 0.35, 0.35, 0.35, 1.0)
Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, width, height, true, true, stroke, fill); Utils.drawRoundedLine(
cr,
x + lineWidth / 2.0,
y + lineWidth / 2.0,
width,
height,
true,
true,
stroke,
fill,
)
// Draw the finished bar // Draw the finished bar
x += lineWidth; x += lineWidth
y += lineWidth; y += lineWidth
width -= 2.0*lineWidth; width -= 2.0 * lineWidth
height -= 2.0*lineWidth; height -= 2.0 * lineWidth
let finishedWidth = Math.ceil(this._progress * width); let finishedWidth = Math.ceil(this._progress * width)
let bg = this._progressbar_background; let bg = this._progressbar_background
let bd = this._progressbar_border; let bd = this._progressbar_border
stroke = Cairo.SolidPattern.createRGBA(bd.red/255, bd.green/255, bd.blue/255, bd.alpha/255); stroke = Cairo.SolidPattern.createRGBA(
fill = Cairo.SolidPattern.createRGBA(bg.red/255, bg.green/255, bg.blue/255, bg.alpha/255); bd.red / 255,
bd.green / 255,
bd.blue / 255,
bd.alpha / 255,
)
fill = Cairo.SolidPattern.createRGBA(
bg.red / 255,
bg.green / 255,
bg.blue / 255,
bg.alpha / 255,
)
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
Utils.drawRoundedLine(cr, x + lineWidth/2.0 + width - finishedWidth, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill); Utils.drawRoundedLine(
cr,
x + lineWidth / 2.0 + width - finishedWidth,
y + lineWidth / 2.0,
finishedWidth,
height,
true,
true,
stroke,
fill,
)
else else
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(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(activate) { toggleProgressOverlay(activate) {
if (activate) { if (activate) {
this._showProgressOverlay(); this._showProgressOverlay()
} } else {
else { this._hideProgressOverlay()
this._hideProgressOverlay();
} }
} }
insertEntry(appProgress) { insertEntry(appProgress) {
if (!appProgress || this._progressManagerEntries.indexOf(appProgress) !== -1) if (
return; !appProgress ||
this._progressManagerEntries.indexOf(appProgress) !== -1
)
return
this._progressManagerEntries.push(appProgress); this._progressManagerEntries.push(appProgress)
this._selectEntry(appProgress); this._selectEntry(appProgress)
} }
removeEntry(appProgress) { removeEntry(appProgress) {
if (!appProgress || this._progressManagerEntries.indexOf(appProgress) == -1) if (!appProgress || this._progressManagerEntries.indexOf(appProgress) == -1)
return; return
this._progressManagerEntries.splice(this._progressManagerEntries.indexOf(appProgress), 1); this._progressManagerEntries.splice(
this._progressManagerEntries.indexOf(appProgress),
1,
)
if (this._progressManagerEntries.length > 0) { if (this._progressManagerEntries.length > 0) {
this._selectEntry(this._progressManagerEntries[this._progressManagerEntries.length-1]); this._selectEntry(
this._progressManagerEntries[this._progressManagerEntries.length - 1],
)
} else { } else {
this.setNotificationBadge(0); this.setNotificationBadge(0)
this.toggleNotificationBadge(false); this.toggleNotificationBadge(false)
this.setProgress(0); this.setProgress(0)
this.toggleProgressOverlay(false); this.toggleProgressOverlay(false)
this.setUrgent(false); this.setUrgent(false)
} }
} }
_selectEntry(appProgress) { _selectEntry(appProgress) {
if (!appProgress) if (!appProgress) return
return;
this._signalsHandler.removeWithLabel('progress-entry'); this._signalsHandler.removeWithLabel('progress-entry')
this._signalsHandler.addWithLabel('progress-entry', this._signalsHandler.addWithLabel(
'progress-entry',
[ [
appProgress, appProgress,
'count-changed', 'count-changed',
(appProgress, value) => { (appProgress, value) => {
this.setNotificationBadge(value); this.setNotificationBadge(value)
} },
], [ ],
[
appProgress, appProgress,
'count-visible-changed', 'count-visible-changed',
(appProgress, value) => { (appProgress, value) => {
this.toggleNotificationBadge(value); this.toggleNotificationBadge(value)
} },
], [ ],
[
appProgress, appProgress,
'progress-changed', 'progress-changed',
(appProgress, value) => { (appProgress, value) => {
this.setProgress(value); this.setProgress(value)
} },
], [ ],
[
appProgress, appProgress,
'progress-visible-changed', 'progress-visible-changed',
(appProgress, value) => { (appProgress, value) => {
this.toggleProgressOverlay(value); this.toggleProgressOverlay(value)
} },
], [ ],
[
appProgress, appProgress,
'urgent-changed', 'urgent-changed',
(appProgress, value) => { (appProgress, value) => {
this.setUrgent(value) this.setUrgent(value)
} },
]); ],
)
this.setNotificationBadge(appProgress.count()); this.setNotificationBadge(appProgress.count())
this.toggleNotificationBadge(appProgress.countVisible()); this.toggleNotificationBadge(appProgress.countVisible())
this.setProgress(appProgress.progress()); this.setProgress(appProgress.progress())
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) {
if (!this._isUrgent) { if (!this._isUrgent) {
icon.set_pivot_point(0.5, 0.5); icon.set_pivot_point(0.5, 0.5)
this._source.iconAnimator.addAnimation(icon, 'dance'); this._source.iconAnimator.addAnimation(icon, 'dance')
this._isUrgent = true; this._isUrgent = true
} }
} else { } else {
if (this._isUrgent) { if (this._isUrgent) {
this._source.iconAnimator.removeAnimation(icon, 'dance'); this._source.iconAnimator.removeAnimation(icon, 'dance')
this._isUrgent = false; this._isUrgent = false
} }
icon.rotation_angle_z = 0; icon.rotation_angle_z = 0
} }
} }
}; }

View File

@@ -15,242 +15,267 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import Meta from 'gi://Meta'; import Meta from 'gi://Meta'
import Mtk from 'gi://Mtk'; import Mtk from 'gi://Mtk'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import * as Utils from './utils.js'; import * as Utils from './utils.js'
//timeout intervals //timeout intervals
const MIN_UPDATE_MS = 200; const MIN_UPDATE_MS = 200
//timeout names //timeout names
const T1 = 'limitUpdateTimeout'; const T1 = 'limitUpdateTimeout'
export const Mode = { export const Mode = {
ALL_WINDOWS: 0, ALL_WINDOWS: 0,
FOCUSED_WINDOWS: 1, FOCUSED_WINDOWS: 1,
MAXIMIZED_WINDOWS: 2 MAXIMIZED_WINDOWS: 2,
}; }
export class ProximityWatch { export class ProximityWatch {
constructor(actor, monitorIndex, mode, xThreshold, yThreshold, handler) { constructor(actor, monitorIndex, mode, xThreshold, yThreshold, handler) {
this.actor = actor; this.actor = actor
this.monitorIndex = monitorIndex this.monitorIndex = monitorIndex
this.overlap = false; 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._updateWatchRect()); this._allocationChangedId = actor.connect('notify::allocation', () =>
this._updateWatchRect(),
)
this._updateWatchRect(); this._updateWatchRect()
} }
destroy() { destroy() {
this.actor.disconnect(this._allocationChangedId); this.actor.disconnect(this._allocationChangedId)
} }
_updateWatchRect() { _updateWatchRect() {
let [actorX, actorY] = this.actor.get_position(); let [actorX, actorY] = this.actor.get_position()
this.rect = new Mtk.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,
}); })
} }
}; }
export const ProximityManager = class { export const ProximityManager = class {
constructor() { constructor() {
this._counter = 1; this._counter = 1
this._watches = {}; this._watches = {}
this._focusedWindowInfo = null; this._focusedWindowInfo = null
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler()
this._timeoutsHandler = new Utils.TimeoutsHandler(); this._timeoutsHandler = new Utils.TimeoutsHandler()
this._bindSignals(); this._bindSignals()
this._setFocusedWindow(); this._setFocusedWindow()
} }
createWatch(actor, monitorIndex, mode, xThreshold, yThreshold, handler) { createWatch(actor, monitorIndex, mode, xThreshold, yThreshold, handler) {
let watch = new ProximityWatch(actor, monitorIndex, 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(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() { update() {
this._queueUpdate(true); this._queueUpdate(true)
} }
destroy() { 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() { _bindSignals() {
this._signalsHandler.add( this._signalsHandler.add(
[ [global.window_manager, 'switch-workspace', () => this._queueUpdate()],
global.window_manager, [Main.overview, 'hidden', () => this._queueUpdate()],
'switch-workspace',
() => this._queueUpdate()
],
[
Main.overview,
'hidden',
() => this._queueUpdate()
],
[ [
global.display, global.display,
'notify::focus-window', 'notify::focus-window',
() => { () => {
this._setFocusedWindow(); this._setFocusedWindow()
this._queueUpdate(); this._queueUpdate()
} },
], ],
[ [global.display, 'restacked', () => this._queueUpdate()],
global.display, )
'restacked',
() => this._queueUpdate()
]
);
} }
_setFocusedWindow() { _setFocusedWindow() {
this._disconnectFocusedWindow(); this._disconnectFocusedWindow()
let focusedWindow = global.display.focus_window; let focusedWindow = global.display.focus_window
if (focusedWindow) { if (focusedWindow) {
let focusedWindowInfo = this._getFocusedWindowInfo(focusedWindow); let focusedWindowInfo = this._getFocusedWindowInfo(focusedWindow)
if (focusedWindowInfo && this._checkIfHandledWindowType(focusedWindowInfo.metaWindow)) { if (
focusedWindowInfo.allocationId = focusedWindowInfo.window.connect('notify::allocation', () => this._queueUpdate()); focusedWindowInfo &&
focusedWindowInfo.destroyId = focusedWindowInfo.window.connect('destroy', () => this._disconnectFocusedWindow(true)); this._checkIfHandledWindowType(focusedWindowInfo.metaWindow)
) {
focusedWindowInfo.allocationId = focusedWindowInfo.window.connect(
'notify::allocation',
() => this._queueUpdate(),
)
focusedWindowInfo.destroyId = focusedWindowInfo.window.connect(
'destroy',
() => this._disconnectFocusedWindow(true),
)
this._focusedWindowInfo = focusedWindowInfo; this._focusedWindowInfo = focusedWindowInfo
} }
} }
} }
_getFocusedWindowInfo(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 = focusedWindow; 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()
if (focusedWindowInfo.metaWindow.get_frame_rect().height < mainMetaWindow.get_frame_rect().height) { if (
focusedWindowInfo.window = mainMetaWindow.get_compositor_private(); focusedWindowInfo.metaWindow.get_frame_rect().height <
focusedWindowInfo.metaWindow = mainMetaWindow; mainMetaWindow.get_frame_rect().height
) {
focusedWindowInfo.window = mainMetaWindow.get_compositor_private()
focusedWindowInfo.metaWindow = mainMetaWindow
} }
} }
} }
return focusedWindowInfo; return focusedWindowInfo
} }
_disconnectFocusedWindow(destroy) { _disconnectFocusedWindow(destroy) {
if (this._focusedWindowInfo && !destroy) { if (this._focusedWindowInfo && !destroy) {
this._focusedWindowInfo.window.disconnect(this._focusedWindowInfo.allocationId); this._focusedWindowInfo.window.disconnect(
this._focusedWindowInfo.window.disconnect(this._focusedWindowInfo.destroyId); this._focusedWindowInfo.allocationId,
)
this._focusedWindowInfo.window.disconnect(
this._focusedWindowInfo.destroyId,
)
} }
this._focusedWindowInfo = null; this._focusedWindowInfo = null
} }
_getHandledWindows() { _getHandledWindows() {
return Utils.getCurrentWorkspace() return Utils.getCurrentWorkspace()
.list_windows() .list_windows()
.filter(mw => this._checkIfHandledWindow(mw)); .filter((mw) => this._checkIfHandledWindow(mw))
} }
_checkIfHandledWindow(metaWindow) { _checkIfHandledWindow(metaWindow) {
return metaWindow && return (
metaWindow &&
!metaWindow.minimized && !metaWindow.minimized &&
!metaWindow.customJS_ding && !metaWindow.customJS_ding &&
this._checkIfHandledWindowType(metaWindow); this._checkIfHandledWindowType(metaWindow)
)
} }
_checkIfHandledWindowType(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.DESKTOP; metaWindowType <= Meta.WindowType.SPLASHSCREEN &&
metaWindowType != Meta.WindowType.DESKTOP
)
} }
_queueUpdate(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
return; return
} }
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() { _endLimitUpdate() {
if (this._pendingUpdate) { if (this._pendingUpdate) {
this._pendingUpdate = false; this._pendingUpdate = false
this._queueUpdate(); this._queueUpdate()
} }
} }
_update(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)
)
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.get_monitor() == watch.monitorIndex); (mw) =>
mw.maximized_vertically &&
mw.maximized_horizontally &&
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(metaWindow, watch) { _checkProximity(metaWindow, watch) {
let windowRect = metaWindow.get_frame_rect(); let windowRect = metaWindow.get_frame_rect()
return windowRect.overlap(watch.rect) && return (
windowRect.overlap(watch.rect) &&
((!watch.threshold[0] && !watch.threshold[1]) || ((!watch.threshold[0] && !watch.threshold[1]) ||
metaWindow.get_monitor() == watch.monitorIndex || metaWindow.get_monitor() == watch.monitorIndex ||
windowRect.overlap(global.display.get_monitor_geometry(watch.monitorIndex))); windowRect.overlap(
global.display.get_monitor_geometry(watch.monitorIndex),
))
)
} }
}; }

1706
taskbar.js

File diff suppressed because it is too large Load Diff

View File

@@ -15,66 +15,51 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import GdkPixbuf from 'gi://GdkPixbuf'; import GdkPixbuf from 'gi://GdkPixbuf'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import St from 'gi://St'; import St from 'gi://St'
import * as Proximity from './proximity.js'; import * as Proximity from './proximity.js'
import * as Utils from './utils.js'; import * as Utils from './utils.js'
import {SETTINGS} from './extension.js'; import { SETTINGS } from './extension.js'
export const DynamicTransparency = class { export const DynamicTransparency = class {
constructor(dtpPanel) { constructor(dtpPanel) {
this._dtpPanel = dtpPanel; this._dtpPanel = dtpPanel
this._proximityManager = dtpPanel.panelManager.proximityManager; this._proximityManager = dtpPanel.panelManager.proximityManager
this._proximityWatchId = 0; this._proximityWatchId = 0
this.currentBackgroundColor = 0; this.currentBackgroundColor = 0
this._initialPanelStyle = dtpPanel.panel.get_style(); this._initialPanelStyle = dtpPanel.panel.get_style()
this._signalsHandler = new Utils.GlobalSignalsHandler(); this._signalsHandler = new Utils.GlobalSignalsHandler()
this._bindSignals(); this._bindSignals()
this._updateAnimationDuration(); this._updateAnimationDuration()
this._updateAllAndSet(); this._updateAllAndSet()
this._updateProximityWatch(); this._updateProximityWatch()
} }
destroy() { destroy() {
this._signalsHandler.destroy(); this._signalsHandler.destroy()
this._proximityManager.removeWatch(this._proximityWatchId); this._proximityManager.removeWatch(this._proximityWatchId)
this._dtpPanel.panel.set_style(this._initialPanelStyle); this._dtpPanel.panel.set_style(this._initialPanelStyle)
} }
updateExternalStyle() { updateExternalStyle() {
this._updateComplementaryStyles(); this._updateComplementaryStyles()
this._setBackground(); this._setBackground()
} }
_bindSignals() { _bindSignals() {
this._signalsHandler.add( this._signalsHandler.add(
[ [Utils.getStageTheme(), 'changed', () => this._updateAllAndSet()],
Utils.getStageTheme(), [Main.overview, ['showing', 'hiding'], () => this._updateAlphaAndSet()],
'changed',
() => this._updateAllAndSet()
],
[
Main.overview,
[
'showing',
'hiding'
],
() => this._updateAlphaAndSet()
],
[ [
SETTINGS, SETTINGS,
[ ['changed::trans-use-custom-bg', 'changed::trans-bg-color'],
'changed::trans-use-custom-bg', () => this._updateColorAndSet(),
'changed::trans-bg-color'
],
() => this._updateColorAndSet()
], ],
[ [
SETTINGS, SETTINGS,
@@ -83,9 +68,9 @@ export const DynamicTransparency = class {
'changed::trans-panel-opacity', 'changed::trans-panel-opacity',
'changed::trans-bg-color', 'changed::trans-bg-color',
'changed::trans-dynamic-anim-target', 'changed::trans-dynamic-anim-target',
'changed::trans-use-dynamic-opacity' 'changed::trans-use-dynamic-opacity',
], ],
() => this._updateAlphaAndSet() () => this._updateAlphaAndSet(),
], ],
[ [
SETTINGS, SETTINGS,
@@ -94,35 +79,35 @@ export const DynamicTransparency = class {
'changed::trans-gradient-top-color', 'changed::trans-gradient-top-color',
'changed::trans-gradient-bottom-color', 'changed::trans-gradient-bottom-color',
'changed::trans-gradient-top-opacity', 'changed::trans-gradient-top-opacity',
'changed::trans-gradient-bottom-opacity' 'changed::trans-gradient-bottom-opacity',
], ],
() => this._updateGradientAndSet() () => this._updateGradientAndSet(),
], ],
[ [
SETTINGS, SETTINGS,
[ [
'changed::trans-dynamic-behavior', 'changed::trans-dynamic-behavior',
'changed::trans-use-dynamic-opacity', 'changed::trans-use-dynamic-opacity',
'changed::trans-dynamic-distance' 'changed::trans-dynamic-distance',
], ],
() => this._updateProximityWatch() () => this._updateProximityWatch(),
], ],
[ [
SETTINGS, SETTINGS,
'changed::trans-dynamic-anim-time', 'changed::trans-dynamic-anim-time',
() => this._updateAnimationDuration() () => this._updateAnimationDuration(),
] ],
); )
} }
_updateProximityWatch() { _updateProximityWatch() {
this._proximityManager.removeWatch(this._proximityWatchId); this._proximityManager.removeWatch(this._proximityWatchId)
if (SETTINGS.get_boolean('trans-use-dynamic-opacity')) { if (SETTINGS.get_boolean('trans-use-dynamic-opacity')) {
let isVertical = this._dtpPanel.checkIfVertical(); let isVertical = this._dtpPanel.checkIfVertical()
let threshold = SETTINGS.get_int('trans-dynamic-distance'); let threshold = SETTINGS.get_int('trans-dynamic-distance')
this._windowOverlap = false; this._windowOverlap = false
this._updateAlphaAndSet() this._updateAlphaAndSet()
this._proximityWatchId = this._proximityManager.createWatch( this._proximityWatchId = this._proximityManager.createWatch(
@@ -131,84 +116,106 @@ export const DynamicTransparency = class {
Proximity.Mode[SETTINGS.get_string('trans-dynamic-behavior')], Proximity.Mode[SETTINGS.get_string('trans-dynamic-behavior')],
isVertical ? threshold : 0, isVertical ? threshold : 0,
isVertical ? 0 : threshold, isVertical ? 0 : threshold,
overlap => { (overlap) => {
this._windowOverlap = overlap; this._windowOverlap = overlap
this._updateAlphaAndSet(); this._updateAlphaAndSet()
} },
); )
} }
} }
_updateAnimationDuration() { _updateAnimationDuration() {
this.animationDuration = (SETTINGS.get_int('trans-dynamic-anim-time') * 0.001) + 's;'; this.animationDuration =
SETTINGS.get_int('trans-dynamic-anim-time') * 0.001 + 's;'
} }
_updateAllAndSet() { _updateAllAndSet() {
let themeBackground = this._getThemeBackground(true); let themeBackground = this._getThemeBackground(true)
this._updateColor(themeBackground); this._updateColor(themeBackground)
this._updateAlpha(themeBackground); this._updateAlpha(themeBackground)
this._updateComplementaryStyles(); this._updateComplementaryStyles()
this._updateGradient(); this._updateGradient()
this._setBackground(); this._setBackground()
this._setGradient(); this._setGradient()
} }
_updateColorAndSet() { _updateColorAndSet() {
this._updateColor(); this._updateColor()
this._setBackground(); this._setBackground()
} }
_updateAlphaAndSet() { _updateAlphaAndSet() {
this._updateAlpha(); this._updateAlpha()
this._setBackground(); this._setBackground()
} }
_updateGradientAndSet() { _updateGradientAndSet() {
this._updateGradient(); this._updateGradient()
this._setGradient(); this._setGradient()
} }
_updateComplementaryStyles() { _updateComplementaryStyles() {
let panelThemeNode = this._dtpPanel.panel.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(themeBackground) { _updateColor(themeBackground) {
this.backgroundColorRgb = SETTINGS.get_boolean('trans-use-custom-bg') ? this.backgroundColorRgb = SETTINGS.get_boolean('trans-use-custom-bg')
SETTINGS.get_string('trans-bg-color') : ? SETTINGS.get_string('trans-bg-color')
(themeBackground || this._getThemeBackground()); : themeBackground || this._getThemeBackground()
} }
_updateAlpha(themeBackground) { _updateAlpha(themeBackground) {
if (this._windowOverlap && !Main.overview.visibleTarget && SETTINGS.get_boolean('trans-use-dynamic-opacity')) { if (
this.alpha = SETTINGS.get_double('trans-dynamic-anim-target'); this._windowOverlap &&
!Main.overview.visibleTarget &&
SETTINGS.get_boolean('trans-use-dynamic-opacity')
) {
this.alpha = SETTINGS.get_double('trans-dynamic-anim-target')
} else { } else {
this.alpha = SETTINGS.get_boolean('trans-use-custom-opacity') ? this.alpha = SETTINGS.get_boolean('trans-use-custom-opacity')
SETTINGS.get_double('trans-panel-opacity') : ? SETTINGS.get_double('trans-panel-opacity')
(themeBackground || this._getThemeBackground()).alpha * 0.003921569; // 1 / 255 = 0.003921569 : (themeBackground || this._getThemeBackground()).alpha * 0.003921569 // 1 / 255 = 0.003921569
} }
} }
_updateGradient() { _updateGradient() {
this._gradientStyle = ''; this._gradientStyle = ''
if (SETTINGS.get_boolean('trans-use-custom-gradient')) { if (SETTINGS.get_boolean('trans-use-custom-gradient')) {
this._gradientStyle += 'background-gradient-direction: ' + (this._dtpPanel.checkIfVertical() ? 'horizontal;' : 'vertical;') + this._gradientStyle +=
'background-gradient-start: ' + Utils.getrgbaColor(SETTINGS.get_string('trans-gradient-top-color'), 'background-gradient-direction: ' +
SETTINGS.get_double('trans-gradient-top-opacity')) + (this._dtpPanel.checkIfVertical() ? 'horizontal;' : 'vertical;') +
'background-gradient-end: ' + Utils.getrgbaColor(SETTINGS.get_string('trans-gradient-bottom-color'), 'background-gradient-start: ' +
SETTINGS.get_double('trans-gradient-bottom-opacity')); Utils.getrgbaColor(
SETTINGS.get_string('trans-gradient-top-color'),
SETTINGS.get_double('trans-gradient-top-opacity'),
) +
'background-gradient-end: ' +
Utils.getrgbaColor(
SETTINGS.get_string('trans-gradient-bottom-color'),
SETTINGS.get_double('trans-gradient-bottom-opacity'),
)
} }
} }
_setBackground() { _setBackground() {
this.currentBackgroundColor = Utils.getrgbaColor(this.backgroundColorRgb, this.alpha); this.currentBackgroundColor = Utils.getrgbaColor(
this.backgroundColorRgb,
this.alpha,
)
let transition = 'transition-duration:' + this.animationDuration; let transition = 'transition-duration:' + this.animationDuration
this._dtpPanel.set_style('background-color: ' + this.currentBackgroundColor + transition + this._complementaryStyles); this._dtpPanel.set_style(
'background-color: ' +
this.currentBackgroundColor +
transition +
this._complementaryStyles,
)
} }
_setGradient() { _setGradient() {
@@ -217,36 +224,45 @@ export const DynamicTransparency = class {
'border-image: none; ' + 'border-image: none; ' +
'background-image: none; ' + 'background-image: none; ' +
this._gradientStyle + this._gradientStyle +
'transition-duration:' + this.animationDuration 'transition-duration:' +
); this.animationDuration,
)
} }
_getThemeBackground(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 =
Main.uiGroup.remove_child(fakePanel); this._getBackgroundImageColor(fakeTheme) ||
fakeTheme.get_background_color()
Main.uiGroup.remove_child(fakePanel)
} }
return this._themeBackground; return this._themeBackground
} }
_getBackgroundImageColor(theme) { _getBackgroundImageColor(theme) {
let bg = null; let bg = null
try { try {
let imageFile = theme.get_background_image() || theme.get_border_image().get_file(); let imageFile =
theme.get_background_image() || theme.get_border_image().get_file()
if (imageFile) { if (imageFile) {
let imageBuf = GdkPixbuf.Pixbuf.new_from_file(imageFile.get_path()); let imageBuf = GdkPixbuf.Pixbuf.new_from_file(imageFile.get_path())
let pixels = imageBuf.get_pixels(); let pixels = imageBuf.get_pixels()
bg = { red: pixels[0], green: pixels[1], blue: pixels[2], alpha: pixels[3] }; bg = {
red: pixels[0],
green: pixels[1],
blue: pixels[2],
alpha: pixels[3],
}
} }
} catch (error) {} } catch (error) {}
return bg; return bg
} }
} }

875
utils.js

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

583
yarn.lock Normal file
View File

@@ -0,0 +1,583 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.1"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56"
integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==
dependencies:
eslint-visitor-keys "^3.4.3"
"@eslint-community/regexpp@^4.12.1":
version "4.12.1"
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
"@eslint/config-array@^0.19.0":
version "0.19.1"
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984"
integrity sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==
dependencies:
"@eslint/object-schema" "^2.1.5"
debug "^4.3.1"
minimatch "^3.1.2"
"@eslint/core@^0.10.0":
version "0.10.0"
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.10.0.tgz#23727063c21b335f752dbb3a16450f6f9cbc9091"
integrity sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==
dependencies:
"@types/json-schema" "^7.0.15"
"@eslint/eslintrc@^3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c"
integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^10.0.1"
globals "^14.0.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@9.19.0", "@eslint/js@^9.19.0":
version "9.19.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.19.0.tgz#51dbb140ed6b49d05adc0b171c41e1a8713b7789"
integrity sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==
"@eslint/object-schema@^2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.5.tgz#8670a8f6258a2be5b2c620ff314a1d984c23eb2e"
integrity sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==
"@eslint/plugin-kit@^0.2.5":
version "0.2.5"
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz#ee07372035539e7847ef834e3f5e7b79f09e3a81"
integrity sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==
dependencies:
"@eslint/core" "^0.10.0"
levn "^0.4.1"
"@humanfs/core@^0.19.1":
version "0.19.1"
resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"
integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==
"@humanfs/node@^0.16.6":
version "0.16.6"
resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e"
integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==
dependencies:
"@humanfs/core" "^0.19.1"
"@humanwhocodes/retry" "^0.3.0"
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/retry@^0.3.0":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
"@humanwhocodes/retry@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b"
integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==
"@types/estree@^1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
"@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^8.14.0:
version "8.14.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
debug@^4.3.1, debug@^4.3.2:
version "4.4.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
ms "^2.1.3"
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-config-prettier@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz#fbb03bfc8db0651df9ce4e8b7150d11c5fe3addf"
integrity sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==
eslint-scope@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442"
integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-visitor-keys@^3.4.3:
version "3.4.3"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint-visitor-keys@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint@^9.19.0:
version "9.19.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.19.0.tgz#ffa1d265fc4205e0f8464330d35f09e1d548b1bf"
integrity sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.12.1"
"@eslint/config-array" "^0.19.0"
"@eslint/core" "^0.10.0"
"@eslint/eslintrc" "^3.2.0"
"@eslint/js" "9.19.0"
"@eslint/plugin-kit" "^0.2.5"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
"@humanwhocodes/retry" "^0.4.1"
"@types/estree" "^1.0.6"
"@types/json-schema" "^7.0.15"
ajv "^6.12.4"
chalk "^4.0.0"
cross-spawn "^7.0.6"
debug "^4.3.2"
escape-string-regexp "^4.0.0"
eslint-scope "^8.2.0"
eslint-visitor-keys "^4.2.0"
espree "^10.3.0"
esquery "^1.5.0"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
file-entry-cache "^8.0.0"
find-up "^5.0.0"
glob-parent "^6.0.2"
ignore "^5.2.0"
imurmurhash "^0.1.4"
is-glob "^4.0.0"
json-stable-stringify-without-jsonify "^1.0.1"
lodash.merge "^4.6.2"
minimatch "^3.1.2"
natural-compare "^1.4.0"
optionator "^0.9.3"
espree@^10.0.1, espree@^10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a"
integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==
dependencies:
acorn "^8.14.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^4.2.0"
esquery@^1.5.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7"
integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==
dependencies:
estraverse "^5.1.0"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^5.1.0, estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fast-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
file-entry-cache@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f"
integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
dependencies:
flat-cache "^4.0.0"
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
dependencies:
locate-path "^6.0.0"
path-exists "^4.0.0"
flat-cache@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==
dependencies:
flatted "^3.2.9"
keyv "^4.5.4"
flatted@^3.2.9:
version "3.3.2"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27"
integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==
glob-parent@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies:
is-glob "^4.0.3"
globals@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
globals@^15.14.0:
version "15.14.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-15.14.0.tgz#b8fd3a8941ff3b4d38f3319d433b61bbb482e73f"
integrity sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
ignore@^5.2.0:
version "5.3.2"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-glob@^4.0.0, is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
json-buffer@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
keyv@^4.5.4:
version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
dependencies:
json-buffer "3.0.1"
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
dependencies:
prelude-ls "^1.2.1"
type-check "~0.4.0"
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
dependencies:
p-locate "^5.0.0"
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
optionator@^0.9.3:
version "0.9.4"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734"
integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==
dependencies:
deep-is "^0.1.3"
fast-levenshtein "^2.0.6"
levn "^0.4.1"
prelude-ls "^1.2.1"
type-check "^0.4.0"
word-wrap "^1.2.5"
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
dependencies:
yocto-queue "^0.1.0"
p-locate@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
dependencies:
p-limit "^3.0.2"
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
dependencies:
callsites "^3.0.0"
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
prettier@^3.4.2:
version "3.4.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.2.tgz#a5ce1fb522a588bf2b78ca44c6e6fe5aa5a2b13f"
integrity sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==
punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
dependencies:
prelude-ls "^1.2.1"
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
which@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
word-wrap@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==