diff --git a/src/appIcons.js b/src/appIcons.js
index 9e5a34d..9009258 100644
--- a/src/appIcons.js
+++ b/src/appIcons.js
@@ -43,7 +43,6 @@ import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js'
import * as Utils from './utils.js'
import * as PanelSettings from './panelSettings.js'
import * as Taskbar from './taskbar.js'
-import * as Progress from './progress.js'
import {
DTP_EXTENSION,
SETTINGS,
@@ -121,6 +120,7 @@ export const TaskbarAppIcon = GObject.registerClass(
_init(appInfo, panel, iconParams, previewMenu, iconAnimator) {
this.dtpPanel = panel
this._nWindows = 0
+ this._notifications = {}
this.window = appInfo.window
this.isLauncher = appInfo.isLauncher
this._previewMenu = previewMenu
@@ -132,6 +132,7 @@ export const TaskbarAppIcon = GObject.registerClass(
super._init(appInfo.app, iconParams)
+ this._signalsHandler = new Utils.GlobalSignalsHandler()
this._timeoutsHandler = new Utils.TimeoutsHandler()
// Fix touchscreen issues before the listener is added by the parent constructor.
@@ -176,6 +177,7 @@ export const TaskbarAppIcon = GObject.registerClass(
})
this.remove_child(this._iconContainer)
+ this.icon._iconBin.set_pivot_point(0.5, 0.5)
this._dtpIconContainer.add_child(this._iconContainer)
@@ -191,11 +193,6 @@ export const TaskbarAppIcon = GObject.registerClass(
this._updateWindowTitle()
this._updateWindowTitleStyle()
- this._scaleFactorChangedId = Utils.getStageTheme().connect(
- 'changed',
- () => this._updateWindowTitleStyle(),
- )
-
box.add_child(this._dtpIconContainer)
box.add_child(this._windowTitle)
@@ -223,35 +220,33 @@ export const TaskbarAppIcon = GObject.registerClass(
this._setAppIconPadding()
this._setAppIconStyle()
this._showDots()
+ this._numberOverlay()
- this._focusWindowChangedId = global.display.connect(
- 'notify::focus-window',
- this._onFocusAppChanged.bind(this),
- )
-
- this._windowEnteredMonitorId = this._windowLeftMonitorId = 0
- this._stateChangedId = this.app.connect(
- 'windows-changed',
- this.onWindowsChanged.bind(this),
+ this._signalsHandler.add(
+ [
+ Utils.getStageTheme(),
+ 'changed',
+ this._updateWindowTitleStyle.bind(this),
+ ],
+ [
+ global.display,
+ 'notify::focus-window',
+ this._onFocusAppChanged.bind(this),
+ ],
+ [this.app, 'windows-changed', this.onWindowsChanged.bind(this)],
)
if (!this.window) {
if (SETTINGS.get_boolean('isolate-monitors')) {
- this._windowEnteredMonitorId =
- Utils.DisplayWrapper.getScreen().connect(
- 'window-entered-monitor',
- this.onWindowEnteredOrLeft.bind(this),
- )
- this._windowLeftMonitorId = Utils.DisplayWrapper.getScreen().connect(
- 'window-left-monitor',
+ this._signalsHandler.add([
+ Utils.DisplayWrapper.getScreen(),
+ ['window-entered-monitor', 'window-left-monitor'],
this.onWindowEnteredOrLeft.bind(this),
- )
+ ])
}
- this._titleWindowChangeId = 0
- this._minimizedWindowChangeId = 0
-
- this._fullscreenId = Utils.DisplayWrapper.getScreen().connect(
+ this._signalsHandler.add([
+ Utils.DisplayWrapper.getScreen(),
'in-fullscreen-changed',
() => {
if (
@@ -263,188 +258,110 @@ export const TaskbarAppIcon = GObject.registerClass(
this._displayProperIndicator()
}
},
- )
+ ])
} else {
- this._titleWindowChangeId = this.window.connect(
- 'notify::title',
- this._updateWindowTitle.bind(this),
- )
-
- this._minimizedWindowChangeId = this.window.connect(
- 'notify::minimized',
- this._updateWindowTitleStyle.bind(this),
+ this._signalsHandler.add(
+ [this.window, 'notify::title', this._updateWindowTitle.bind(this)],
+ [
+ this.window,
+ 'notify::minimized',
+ this._updateWindowTitleStyle.bind(this),
+ ],
)
}
- this._scrollEventId = this.connect(
- 'scroll-event',
- this._onMouseScroll.bind(this),
- )
-
- this._overviewWindowDragEndId = Main.overview.connect(
- 'window-drag-end',
- this._onOverviewWindowDragEnd.bind(this),
- )
-
- this._switchWorkspaceId = global.window_manager.connect(
- 'switch-workspace',
- this._onSwitchWorkspace.bind(this),
- )
-
- this._hoverChangeId = this.connect('notify::hover', () =>
- this._onAppIconHoverChanged(),
- )
-
- this._hoverChangeId2 = this.connect('notify::hover', () =>
- this._onAppIconHoverChanged_GtkWorkaround(),
- )
- this._pressedChangedId = this.connect('notify::pressed', () =>
- this._onAppIconPressedChanged_GtkWorkaround(),
- )
-
- this._dtpSettingsSignalIds = [
- SETTINGS.connect(
- 'changed::animate-appicon-hover',
- this._onAnimateAppiconHoverChanged.bind(this),
- ),
- SETTINGS.connect(
+ this._signalsHandler.add(
+ [this, 'scroll-event', this._onMouseScroll.bind(this)],
+ [
+ Main.overview,
+ 'window-drag-end',
+ this._onOverviewWindowDragEnd.bind(this),
+ ],
+ [
+ global.window_manager,
+ 'switch-workspace',
+ this._onSwitchWorkspace.bind(this),
+ ],
+ [
+ this,
+ 'notify::hover',
+ () => {
+ this._onAppIconHoverChanged()
+ this._onAppIconHoverChanged_GtkWorkaround()
+ },
+ ],
+ [
+ this,
+ 'notify::pressed',
+ this._onAppIconPressedChanged_GtkWorkaround.bind(this),
+ ],
+ [
+ this.dtpPanel.panelManager.notificationsMonitor,
+ `update-${this.app.id}`,
+ this._handleNotifications.bind(this),
+ ],
+ [
+ SETTINGS,
'changed::animate-appicon-hover',
+ () => {
+ this._onAnimateAppiconHoverChanged()
+ this._onAppIconHoverHighlightChanged()
+ },
+ ],
+ [
+ SETTINGS,
+ [
+ 'changed::highlight-appicon-hover',
+ 'changed::highlight-appicon-hover-background-color',
+ 'changed::highlight-appicon-pressed-background-color',
+ 'changed::highlight-appicon-hover-border-radius',
+ ],
this._onAppIconHoverHighlightChanged.bind(this),
- ),
- SETTINGS.connect(
- 'changed::highlight-appicon-hover',
- this._onAppIconHoverHighlightChanged.bind(this),
- ),
- SETTINGS.connect(
- 'changed::highlight-appicon-hover-background-color',
- this._onAppIconHoverHighlightChanged.bind(this),
- ),
- SETTINGS.connect(
- 'changed::highlight-appicon-pressed-background-color',
- this._onAppIconHoverHighlightChanged.bind(this),
- ),
- SETTINGS.connect(
+ ],
+ [
+ SETTINGS,
+ [
+ 'changed::dot-position',
+ 'changed::dot-size',
+ 'changed::dot-style-focused',
+ 'changed::dot-style-unfocused',
+ 'changed::dot-color-dominant',
+ 'changed::dot-color-override',
+ 'changed::dot-color-1',
+ 'changed::dot-color-2',
+ 'changed::dot-color-3',
+ 'changed::dot-color-4',
+ 'changed::dot-color-unfocused-different',
+ 'changed::dot-color-unfocused-1',
+ 'changed::dot-color-unfocused-2',
+ 'changed::dot-color-unfocused-3',
+ 'changed::dot-color-unfocused-4',
+ 'changed::focus-highlight',
+ 'changed::focus-highlight-dominant',
+ 'changed::focus-highlight-color',
+ 'changed::focus-highlight-opacity',
+ 'changed::group-apps-underline-unfocused',
+ ],
+ this._settingsChangeRefresh.bind(this),
+ ],
+ [
+ SETTINGS,
+ [
+ 'changed::group-apps-label-font-size',
+ 'changed::group-apps-label-font-weight',
+ 'changed::group-apps-label-font-color',
+ 'changed::group-apps-label-font-color-minimized',
+ 'changed::group-apps-label-max-width',
+ 'changed::group-apps-use-fixed-width',
+ ],
+ this._updateWindowTitleStyle.bind(this),
+ ],
+ [
+ SETTINGS,
'changed::highlight-appicon-hover-border-radius',
- this._onAppIconHoverHighlightChanged.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-position',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-size',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-style-focused',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-style-unfocused',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-dominant',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-override',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-1',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-2',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-3',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-4',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-unfocused-different',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-unfocused-1',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-unfocused-2',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-unfocused-3',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::dot-color-unfocused-4',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::focus-highlight',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::focus-highlight-dominant',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::focus-highlight-color',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::focus-highlight-opacity',
- this._settingsChangeRefresh.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-label-font-size',
- this._updateWindowTitleStyle.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-label-font-weight',
- this._updateWindowTitleStyle.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-label-font-color',
- this._updateWindowTitleStyle.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-label-font-color-minimized',
- this._updateWindowTitleStyle.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-label-max-width',
- this._updateWindowTitleStyle.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-use-fixed-width',
- this._updateWindowTitleStyle.bind(this),
- ),
- SETTINGS.connect(
- 'changed::group-apps-underline-unfocused',
- this._settingsChangeRefresh.bind(this),
- ),
- ]
-
- this._dtpSettingsSignalIds = this._dtpSettingsSignalIds.concat([
- SETTINGS.connect('changed::highlight-appicon-hover-border-radius', () =>
- this._setIconStyle(this._isFocusedWindow()),
- ),
- ])
-
- this._progressIndicator = new Progress.ProgressIndicator(
- this,
- panel.progressManager,
+ () => this._setIconStyle(this._isFocusedWindow()),
+ ],
)
-
- this._numberOverlay()
}
getDragActor() {
@@ -520,60 +437,9 @@ export const TaskbarAppIcon = GObject.registerClass(
super._onDestroy()
this._timeoutsHandler.destroy()
+ this._signalsHandler.destroy()
this._previewMenu.close(true)
-
- // Disconect global signals
- if (this._stateChangedId > 0) {
- this.app.disconnect(this._stateChangedId)
- this._stateChangedId = 0
- }
-
- if (this._overviewWindowDragEndId)
- Main.overview.disconnect(this._overviewWindowDragEndId)
-
- if (this._focusWindowChangedId)
- global.display.disconnect(this._focusWindowChangedId)
-
- if (this._fullscreenId)
- Utils.DisplayWrapper.getScreen().disconnect(this._fullscreenId)
-
- if (this._titleWindowChangeId)
- this.window.disconnect(this._titleWindowChangeId)
-
- if (this._minimizedWindowChangeId)
- this.window.disconnect(this._minimizedWindowChangeId)
-
- if (this._windowEnteredMonitorId) {
- Utils.DisplayWrapper.getScreen().disconnect(
- this._windowEnteredMonitorId,
- )
- Utils.DisplayWrapper.getScreen().disconnect(this._windowLeftMonitorId)
- }
-
- if (this._switchWorkspaceId)
- global.window_manager.disconnect(this._switchWorkspaceId)
-
- if (this._scaleFactorChangedId)
- Utils.getStageTheme().disconnect(this._scaleFactorChangedId)
-
- if (this._hoverChangeId) {
- this.disconnect(this._hoverChangeId)
- }
- if (this._hoverChangeId2) {
- this.disconnect(this._hoverChangeId2)
- }
- if (this._pressedChangedId) {
- this.disconnect(this._pressedChangedId)
- }
-
- if (this._scrollEventId) {
- this.disconnect(this._scrollEventId)
- }
-
- for (let i = 0; i < this._dtpSettingsSignalIds.length; ++i) {
- SETTINGS.disconnect(this._dtpSettingsSignalIds[i])
- }
}
onWindowsChanged() {
@@ -1009,16 +875,18 @@ export const TaskbarAppIcon = GObject.registerClass(
if (!this._menu) {
this._menu = new TaskbarSecondaryMenu(this, this.dtpPanel.geom.position)
this._menu.setApp(this.app)
- this._menu.connect('open-state-changed', (menu, isPoppedUp) => {
- if (!isPoppedUp) this._onMenuPoppedDown()
- else this._previewMenu.close(true)
- })
- let id = Main.overview.connect('hiding', () => {
- this._menu.close()
- })
- this.connect('destroy', () => {
- Main.overview.disconnect(id)
- })
+
+ this._signalsHandler.add(
+ [
+ this._menu,
+ 'open-state-changed',
+ (menu, isPoppedUp) => {
+ if (!isPoppedUp) this._onMenuPoppedDown()
+ else this._previewMenu.close(true)
+ },
+ ],
+ [Main.overview, 'hiding', () => this._menu.close()],
+ )
// We want to keep the item hovered while the menu is up
this._menu.blockSourceEvents = true
@@ -1731,25 +1599,89 @@ export const TaskbarAppIcon = GObject.registerClass(
cr.$dispose()
}
+ _handleNotifications(notificationsMonitor, state) {
+ if (!this._nWindows && !this.window) {
+ delete this._notifications.total
+ return
+ }
+
+ let urgent =
+ 'urgent' in state ? state.urgent : this._notifications.urgent || false
+ let formatCount = (count) => {
+ if (!count) return 0
+
+ return count > 10 ? '10+' : count
+ }
+
+ if ('count-visible' in state)
+ this._notifications.countVisible = state['count-visible']
+
+ if ('count' in state) this._notifications.count = state.count
+
+ if ('trayCount' in state)
+ this._notifications.trayCount = this._checkIfFocusedApp()
+ ? 0
+ : state.trayCount
+
+ this._notifications.total =
+ SETTINGS.get_boolean('progress-show-count') &&
+ ((this._notifications.countVisible || 0) &&
+ (this._notifications.count || 0)) +
+ (this._notifications.trayCount || 0)
+
+ urgent = urgent && !!this._notifications.total
+
+ if (urgent !== this._notifications.urgent)
+ this.iconAnimator[`${urgent ? 'add' : 'remove'}Animation`](
+ this.icon._iconBin,
+ 'dance',
+ )
+
+ this._notifications.urgent = urgent
+
+ // restore hotkeys number if no more notifications
+ this._maybeToggleNumberOverlay(
+ formatCount(this._notifications.total) ||
+ this._numberHotkeysOverlayLabel,
+ )
+ }
+
+ _maybeToggleNumberOverlay(labelNumber) {
+ let visible = this._numberOverlayBin.visible
+ let shouldBeVisible =
+ this._hotkeysOverlayActive || this._notifications.total
+
+ this._numberOverlayLabel[
+ `${this._notifications.total ? 'add' : 'remove'}_style_class_name`
+ ]('notification-badge')
+
+ if (
+ shouldBeVisible &&
+ labelNumber != this._numberOverlayLabel.get_text()
+ ) {
+ this._numberOverlayLabel.set_text(labelNumber.toString())
+ this._updateNumberOverlay()
+ }
+
+ if (visible && !shouldBeVisible) this._numberOverlayBin.hide()
+ else if (!visible && shouldBeVisible) this._numberOverlayBin.show()
+ }
+
_numberOverlay() {
- // Add label for a Hot-Key visual aid
+ // Add label for a numeric visual aid (hotkeys or notification)
this._numberOverlayLabel = new St.Label({ style_class: 'badge' })
this._numberOverlayBin = new St.Bin({
child: this._numberOverlayLabel,
y: 2,
})
this._numberOverlayLabel.add_style_class_name('number-overlay')
- this._numberOverlayOrder = -1
+ this._numberHotkeysOverlayLabel = -1
this._numberOverlayBin.hide()
this._dtpIconContainer.add_child(this._numberOverlayBin)
}
- updateHotkeyNumberOverlay() {
- this.updateNumberOverlay(this._numberOverlayBin, true)
- }
-
- updateNumberOverlay(bin, fixedSize) {
+ _updateNumberOverlay() {
// We apply an overall scale factor that might come from a HiDPI monitor.
// Clutter dimensions are in physical pixels, but CSS measures are in logical
// pixels, so make sure to consider the scale.
@@ -1760,7 +1692,6 @@ export const TaskbarAppIcon = GObject.registerClass(
Math.max(12, 0.3 * natWidth) / Utils.getScaleFactor(),
)
let size = Math.round(font_size * 1.3)
- let label = bin.child
let style =
'font-size: ' +
font_size +
@@ -1772,25 +1703,25 @@ export const TaskbarAppIcon = GObject.registerClass(
size +
'px;'
- if (fixedSize || label.get_text().length == 1) {
+ if (this._numberOverlayLabel.get_text().length == 1) {
style += 'width: ' + size + 'px;'
} else {
style += 'padding: 0 2px;'
}
- bin.x = 2
- label.set_style(style)
+ this._numberOverlayLabel.set_style(style)
}
- setNumberOverlay(number) {
- this._numberOverlayOrder = number
- this._numberOverlayLabel.set_text(number.toString())
+ setHotkeysNumberOverlayLabel(number) {
+ this._numberHotkeysOverlayLabel = number
}
- toggleNumberOverlay(activate) {
- if (activate && this._numberOverlayOrder > -1)
- this._numberOverlayBin.show()
- else this._numberOverlayBin.hide()
+ toggleHotkeysNumberOverlay(activate) {
+ this._hotkeysOverlayActive =
+ activate && this._numberHotkeysOverlayLabel > -1
+
+ if (!this._notifications.total)
+ this._maybeToggleNumberOverlay(this._numberHotkeysOverlayLabel)
}
handleDragOver(source) {
diff --git a/src/notificationsMonitor.js b/src/notificationsMonitor.js
new file mode 100644
index 0000000..803685b
--- /dev/null
+++ b/src/notificationsMonitor.js
@@ -0,0 +1,159 @@
+/*
+ * This file is part of the Dash-To-Panel extension for Gnome 3
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import Gio from 'gi://Gio'
+import Shell from 'gi://Shell'
+
+import * as Main from 'resource:///org/gnome/shell/ui/main.js'
+import * as MessageTray from 'resource:///org/gnome/shell/ui/messageTray.js'
+import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js'
+
+import * as Utils from './utils.js'
+
+const tracker = Shell.WindowTracker.get_default()
+const knownCorrespondances = {
+ 'org.gnome.Evolution': [/^org\.gnome\.[eE]volution([.-].+)?$/g],
+}
+
+export const NotificationsMonitor = class extends EventEmitter {
+ constructor() {
+ super()
+
+ this._signalsHandler = new Utils.GlobalSignalsHandler()
+
+ // pretty much useless, but might as well keep it for now
+ this._launcherEntryId = Gio.DBus.session.signal_subscribe(
+ null, // sender
+ 'com.canonical.Unity.LauncherEntry', // iface
+ 'Update', // member
+ null, // path
+ null, // arg0
+ Gio.DBusSignalFlags.NONE,
+ (
+ connection,
+ senderName,
+ objectPath,
+ interfaceName,
+ signalName,
+ parameters,
+ ) => this._handleLauncherUpdate(senderName, parameters),
+ )
+
+ this._signalsHandler.add([
+ tracker,
+ 'notify::focus-app',
+ () => {
+ // reset notifications from message tray on app focus
+ if (tracker.focus_app)
+ this.dispatch(tracker.focus_app.id, { trayCount: 0 }, true)
+ },
+ ])
+ this._acquireUnityDBus()
+
+ this._checkNotifications()
+ }
+
+ destroy() {
+ if (this._launcherEntryId)
+ Gio.DBus.session.signal_unsubscribe(this._launcherEntryId)
+
+ this._releaseUnityDBus()
+ this._signalsHandler.destroy()
+ }
+
+ dispatch(appId, state, ignoreMapping) {
+ // depending of the notification source, some app id end
+ // with ".desktop" and some don't ¯\_(ツ)_/¯
+ appId = appId.replace('.desktop', '')
+
+ // some app have different source app id, deamon and such,
+ // but it maps to a desktop app so match those here
+ if (!ignoreMapping && !knownCorrespondances[appId])
+ appId =
+ Object.keys(knownCorrespondances).find((k) =>
+ knownCorrespondances[k].some((regex) => appId.match(regex)),
+ ) || appId
+
+ this.emit(`update-${appId}.desktop`, state)
+ }
+
+ _acquireUnityDBus() {
+ if (!this._unityBusId) {
+ this._unityBusId = Gio.DBus.session.own_name(
+ 'com.canonical.Unity',
+ Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT,
+ null,
+ null,
+ )
+ }
+ }
+
+ _releaseUnityDBus() {
+ if (this._unityBusId) {
+ Gio.DBus.session.unown_name(this._unityBusId)
+ this._unityBusId = 0
+ }
+ }
+
+ _handleLauncherUpdate(senderName, parameters) {
+ if (!senderName || !parameters) return
+
+ let [appUri, properties] = parameters.deep_unpack()
+ let appId = appUri.replace(/(^\w+:|^)\/\//, '')
+ let updates = {}
+
+ // https://wiki.ubuntu.com/Unity/LauncherAPI#Low_level_DBus_API:_com.canonical.Unity.LauncherEntry
+ for (let property in properties)
+ updates[property] = properties[property].unpack()
+
+ this.dispatch(appId, updates)
+ }
+
+ _checkNotifications() {
+ let addSource = (tray, source) => {
+ let appId = source?._appId || source?.app?.id
+
+ if (!appId) return
+
+ this._signalsHandler.addWithLabel(appId, [
+ source,
+ 'notify::count',
+ () =>
+ this.dispatch(appId, {
+ trayCount: source.count, // source.unseenCount might be less annoying
+ urgent: !!source.notifications.find(
+ (n) => n.urgency > MessageTray.Urgency.NORMAL,
+ ),
+ }),
+ ])
+ }
+
+ this._signalsHandler.add(
+ [Main.messageTray, 'source-added', addSource],
+ [
+ Main.messageTray,
+ 'source-removed',
+ (tray, source) => {
+ if (source?._appId)
+ this._signalsHandler.removeWithLabel(source._appId)
+ },
+ ],
+ )
+
+ Main.messageTray.getSources().forEach((s) => addSource(null, s))
+ }
+}
diff --git a/src/overview.js b/src/overview.js
index 026e7cb..ea8706c 100644
--- a/src/overview.js
+++ b/src/overview.js
@@ -373,7 +373,7 @@ export const Overview = class {
this._hotKeysEnabled = true
if (SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS')
- this.taskbar.toggleNumberOverlay(true)
+ this.taskbar.toggleHotkeysNumberOverlay(true)
}
_disableHotKeys() {
@@ -418,7 +418,7 @@ export const Overview = class {
this._hotKeysEnabled = false
- this.taskbar.toggleNumberOverlay(false)
+ this.taskbar.toggleHotkeysNumberOverlay(false)
}
_optionalNumberOverlay() {
@@ -435,8 +435,8 @@ export const Overview = class {
SETTINGS.get_boolean('hot-keys') &&
SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS'
)
- this.taskbar.toggleNumberOverlay(true)
- else this.taskbar.toggleNumberOverlay(false)
+ this.taskbar.toggleHotkeysNumberOverlay(true)
+ else this.taskbar.toggleHotkeysNumberOverlay(false)
},
],
[SETTINGS, 'changed::shortcut-num-keys', () => this._resetHotkeys()],
@@ -468,7 +468,7 @@ export const Overview = class {
if (hotkey_option === 'NEVER') return
if (hotkey_option === 'TEMPORARILY' || overlayFromShortcut)
- this.taskbar.toggleNumberOverlay(true)
+ this.taskbar.toggleHotkeysNumberOverlay(true)
this._panel.intellihide.revealAndHold(Intellihide.Hold.TEMPORARY)
@@ -484,7 +484,7 @@ export const Overview = class {
timeout,
() => {
if (hotkey_option != 'ALWAYS') {
- this.taskbar.toggleNumberOverlay(false)
+ this.taskbar.toggleHotkeysNumberOverlay(false)
}
this._panel.intellihide.release(Intellihide.Hold.TEMPORARY)
diff --git a/src/panel.js b/src/panel.js
index 3aa215b..b0d465f 100644
--- a/src/panel.js
+++ b/src/panel.js
@@ -48,7 +48,6 @@ import Shell from 'gi://Shell'
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'
import * as DateMenu from 'resource:///org/gnome/shell/ui/dateMenu.js'
import * as Volume from 'resource:///org/gnome/shell/ui/status/volume.js'
-import * as Progress from './progress.js'
import * as Intellihide from './intellihide.js'
import * as Transparency from './transparency.js'
@@ -359,8 +358,6 @@ export const Panel = GObject.registerClass(
// most repaint requests don't actually require us to repaint anything.
// This saves significant CPU when repainting the screen.
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS)
-
- this._initProgressManager()
}
disable() {
@@ -377,8 +374,6 @@ export const Panel = GObject.registerClass(
this.dynamicTransparency.destroy()
- this.progressManager.destroy()
-
this.taskbar.destroy()
this.showAppsIconWrapper.destroy()
@@ -610,16 +605,6 @@ export const Panel = GObject.registerClass(
}
},
],
- [
- SETTINGS,
- 'changed::progress-show-bar',
- () => this._initProgressManager(),
- ],
- [
- SETTINGS,
- 'changed::progress-show-count',
- () => this._initProgressManager(),
- ],
)
if (isVertical) {
@@ -1494,19 +1479,6 @@ export const Panel = GObject.registerClass(
ignoredConstr.indexOf(source.constructor.name) >= 0
)
}
-
- _initProgressManager() {
- const progressVisible = SETTINGS.get_boolean('progress-show-bar')
- const countVisible = SETTINGS.get_boolean('progress-show-count')
- const pm = this.progressManager
-
- if (!pm && (progressVisible || countVisible))
- this.progressManager = new Progress.ProgressManager()
- else if (pm)
- Object.keys(pm._entriesByDBusName).forEach((k) =>
- pm._entriesByDBusName[k].setCountVisible(countVisible),
- )
- }
},
)
diff --git a/src/panelManager.js b/src/panelManager.js
index dd14070..9e8c9c5 100755
--- a/src/panelManager.js
+++ b/src/panelManager.js
@@ -45,6 +45,7 @@ import * as BoxPointer from 'resource:///org/gnome/shell/ui/boxpointer.js'
import * as LookingGlass from 'resource:///org/gnome/shell/ui/lookingGlass.js'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'
+import { NotificationsMonitor } from './notificationsMonitor.js'
import * as Layout from 'resource:///org/gnome/shell/ui/layout.js'
import { InjectionManager } from 'resource:///org/gnome/shell/extensions/extension.js'
import { SETTINGS } from './extension.js'
@@ -133,6 +134,8 @@ export const PanelManager = class {
if (reset) return
+ this.notificationsMonitor = new NotificationsMonitor()
+
this._desktopIconsUsableArea =
new DesktopIconsIntegration.DesktopIconsUsableAreaClass()
@@ -337,6 +340,8 @@ export const PanelManager = class {
this._setKeyBindings(false)
+ this.notificationsMonitor.destroy()
+
this._signalsHandler.destroy()
Main.layoutManager._updateHotCorners = this._oldUpdateHotCorners
@@ -716,6 +721,9 @@ export const IconAnimator = class {
if (this._started && this._count === 0) {
this._timeline.stop()
}
+
+ if (name == 'dance') target.rotation_angle_z = 0
+
return
}
}
diff --git a/src/prefs.js b/src/prefs.js
index 7778766..36a2c5e 100644
--- a/src/prefs.js
+++ b/src/prefs.js
@@ -255,18 +255,18 @@ const Preferences = class {
this._setMonitorsInfo()
},
)
-
+
let maybeGoToPage = () => {
let targetPageName = settings.get_string('target-prefs-page')
-
+
if (targetPageName) {
window.set_visible_page_name(targetPageName)
settings.set_string('target-prefs-page', '')
}
}
-
+
settings.connect('changed::target-prefs-page', maybeGoToPage)
-
+
maybeGoToPage()
})
}
diff --git a/src/progress.js b/src/progress.js
deleted file mode 100644
index dc84120..0000000
--- a/src/progress.js
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * This file is part of the Dash-To-Panel extension for Gnome 3
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- *
- * Credits:
- * This file is based on code from the Dash to Dock extension by micheleg
- */
-
-import Cairo from 'cairo'
-import Gio from 'gi://Gio'
-import Clutter from 'gi://Clutter'
-import Pango from 'gi://Pango'
-import St from 'gi://St'
-import * as Utils from './utils.js'
-import { SETTINGS } from './extension.js'
-
-import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js'
-
-export const ProgressManager = class extends EventEmitter {
- constructor() {
- super()
-
- this._entriesByDBusName = {}
-
- this._launcher_entry_dbus_signal_id = Gio.DBus.session.signal_subscribe(
- null, // sender
- 'com.canonical.Unity.LauncherEntry', // iface
- null, // member
- null, // path
- null, // arg0
- Gio.DBusSignalFlags.NONE,
- this._onEntrySignalReceived.bind(this),
- )
-
- this._dbus_name_owner_changed_signal_id = Gio.DBus.session.signal_subscribe(
- 'org.freedesktop.DBus', // sender
- 'org.freedesktop.DBus', // interface
- 'NameOwnerChanged', // member
- '/org/freedesktop/DBus', // path
- null, // arg0
- Gio.DBusSignalFlags.NONE,
- this._onDBusNameOwnerChanged.bind(this),
- )
-
- this._acquireUnityDBus()
- }
-
- destroy() {
- if (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) {
- Gio.DBus.session.signal_unsubscribe(
- this._dbus_name_owner_changed_signal_id,
- )
- }
-
- this._releaseUnityDBus()
- }
-
- size() {
- return Object.keys(this._entriesByDBusName).length
- }
-
- lookupByDBusName(dbusName) {
- return Object.hasOwn(this._entriesByDBusName, dbusName)
- ? this._entriesByDBusName[dbusName]
- : null
- }
-
- lookupById(appId) {
- let ret = []
- for (let dbusName in this._entriesByDBusName) {
- let entry = this._entriesByDBusName[dbusName]
- if (entry && entry.appId() == appId) {
- ret.push(entry)
- }
- }
-
- return ret
- }
-
- addEntry(entry) {
- let existingEntry = this.lookupByDBusName(entry.dbusName())
- if (existingEntry) {
- existingEntry.update(entry)
- } else {
- this._entriesByDBusName[entry.dbusName()] = entry
- this.emit('progress-entry-added', entry)
- }
- }
-
- removeEntry(entry) {
- delete this._entriesByDBusName[entry.dbusName()]
- this.emit('progress-entry-removed', entry)
- }
-
- _acquireUnityDBus() {
- if (!this._unity_bus_id) {
- Gio.DBus.session.own_name(
- 'com.canonical.Unity',
- Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT,
- null,
- null,
- )
- }
- }
-
- _releaseUnityDBus() {
- if (this._unity_bus_id) {
- Gio.DBus.session.unown_name(this._unity_bus_id)
- this._unity_bus_id = 0
- }
- }
-
- _onEntrySignalReceived(
- connection,
- sender_name,
- object_path,
- interface_name,
- signal_name,
- parameters,
- ) {
- if (!parameters || !signal_name) return
-
- if (signal_name == 'Update') {
- if (!sender_name) {
- return
- }
-
- this._handleUpdateRequest(sender_name, parameters)
- }
- }
-
- _onDBusNameOwnerChanged(
- connection,
- sender_name,
- object_path,
- interface_name,
- signal_name,
- parameters,
- ) {
- if (!parameters || !this.size()) return
-
- let [, before, after] = parameters.deep_unpack()
-
- if (!after) {
- if (Object.hasOwn(this._entriesByDBusName, before)) {
- this.removeEntry(this._entriesByDBusName[before])
- }
- }
- }
-
- _handleUpdateRequest(senderName, parameters) {
- if (!senderName || !parameters) {
- return
- }
-
- let [appUri, properties] = parameters.deep_unpack()
- let appId = appUri.replace(/(^\w+:|^)\/\//, '')
- let entry = this.lookupByDBusName(senderName)
-
- if (entry) {
- entry.setDBusName(senderName)
- entry.update(properties)
- } else {
- let entry = new AppProgress(senderName, appId, properties)
- this.addEntry(entry)
- }
- }
-}
-
-export class AppProgress extends EventEmitter {
- constructor(dbusName, appId, properties) {
- super()
-
- this._dbusName = dbusName
- this._appId = appId
- this._count = 0
- this._countVisible = false
- this._progress = 0.0
- this._progressVisible = false
- this._urgent = false
- this.update(properties)
- }
-
- appId() {
- return this._appId
- }
-
- dbusName() {
- return this._dbusName
- }
-
- count() {
- return this._count
- }
-
- setCount(count) {
- if (this._count != count) {
- this._count = count
- this.emit('count-changed', this._count)
- }
- }
-
- countVisible() {
- return this._countVisible
- }
-
- setCountVisible(countVisible) {
- if (this._countVisible != countVisible) {
- this._countVisible = countVisible
- this.emit('count-visible-changed', this._countVisible)
- }
- }
-
- progress() {
- return this._progress
- }
-
- setProgress(progress) {
- if (this._progress != progress) {
- this._progress = progress
- this.emit('progress-changed', this._progress)
- }
- }
-
- progressVisible() {
- return this._progressVisible
- }
-
- setProgressVisible(progressVisible) {
- if (this._progressVisible != progressVisible) {
- this._progressVisible = progressVisible
- this.emit('progress-visible-changed', this._progressVisible)
- }
- }
-
- urgent() {
- return this._urgent
- }
-
- setUrgent(urgent) {
- if (this._urgent != urgent) {
- this._urgent = urgent
- this.emit('urgent-changed', this._urgent)
- }
- }
-
- setDBusName(dbusName) {
- if (this._dbusName != dbusName) {
- let oldName = this._dbusName
- this._dbusName = dbusName
- this.emit('dbus-name-changed', oldName)
- }
- }
-
- update(other) {
- if (other instanceof AppProgress) {
- this.setDBusName(other.dbusName())
- this.setCount(other.count())
- this.setCountVisible(other.countVisible())
- this.setProgress(other.progress())
- this.setProgressVisible(other.progressVisible())
- this.setUrgent(other.urgent())
- } else {
- for (let property in other) {
- if (Object.hasOwn(other, property)) {
- if (property == 'count') {
- this.setCount(other[property].get_int64())
- } else if (property == 'count-visible') {
- this.setCountVisible(
- SETTINGS.get_boolean('progress-show-count') &&
- other[property].get_boolean(),
- )
- } else if (property == 'progress') {
- this.setProgress(other[property].get_double())
- } else if (property == 'progress-visible') {
- this.setProgressVisible(
- SETTINGS.get_boolean('progress-show-bar') &&
- other[property].get_boolean(),
- )
- } else if (property == 'urgent') {
- this.setUrgent(other[property].get_boolean())
- } else {
- // Not implemented yet
- }
- }
- }
- }
- }
-}
-
-export const ProgressIndicator = class {
- constructor(source, progressManager) {
- this._source = source
- this._progressManager = progressManager
- this._signalsHandler = new Utils.GlobalSignalsHandler()
-
- this._sourceDestroyId = this._source.connect('destroy', () => {
- this._signalsHandler.destroy()
- })
-
- this._notificationBadgeLabel = new St.Label({ style_class: 'badge' })
- this._notificationBadgeBin = new St.Bin({
- child: this._notificationBadgeLabel,
- y: 2,
- x: 2,
- })
- this._notificationBadgeLabel.add_style_class_name('notification-badge')
- this._notificationBadgeCount = 0
- this._notificationBadgeBin.hide()
-
- this._source._dtpIconContainer.add_child(this._notificationBadgeBin)
- this._source._dtpIconContainer.connect(
- 'notify::allocation',
- this.updateNotificationBadge.bind(this),
- )
-
- this._progressManagerEntries = []
- this._progressManager.lookupById(this._source.app.id).forEach((entry) => {
- this.insertEntry(entry)
- })
-
- this._signalsHandler.add(
- [
- this._progressManager,
- 'progress-entry-added',
- this._onEntryAdded.bind(this),
- ],
- [
- this._progressManager,
- 'progress-entry-removed',
- this._onEntryRemoved.bind(this),
- ],
- )
- }
-
- destroy() {
- this._source.disconnect(this._sourceDestroyId)
- this._signalsHandler.destroy()
- }
-
- _onEntryAdded(appProgress, entry) {
- if (!entry || !entry.appId()) return
- if (
- this._source &&
- this._source.app &&
- this._source.app.id == entry.appId()
- ) {
- this.insertEntry(entry)
- }
- }
-
- _onEntryRemoved(appProgress, entry) {
- if (!entry || !entry.appId()) return
-
- if (
- this._source &&
- this._source.app &&
- this._source.app.id == entry.appId()
- ) {
- this.removeEntry(entry)
- }
- }
-
- updateNotificationBadge() {
- this._source.updateNumberOverlay(this._notificationBadgeBin)
- this._notificationBadgeLabel.clutter_text.ellipsize =
- Pango.EllipsizeMode.MIDDLE
- }
-
- _notificationBadgeCountToText(count) {
- if (count <= 9999) {
- return count.toString()
- } else if (count < 1e5) {
- let thousands = count / 1e3
- return thousands.toFixed(1).toString() + 'k'
- } else if (count < 1e6) {
- let thousands = count / 1e3
- return thousands.toFixed(0).toString() + 'k'
- } else if (count < 1e8) {
- let millions = count / 1e6
- return millions.toFixed(1).toString() + 'M'
- } else if (count < 1e9) {
- let millions = count / 1e6
- return millions.toFixed(0).toString() + 'M'
- } else {
- let billions = count / 1e9
- return billions.toFixed(1).toString() + 'B'
- }
- }
-
- setNotificationBadge(count) {
- this._notificationBadgeCount = count
- let text = this._notificationBadgeCountToText(count)
- this._notificationBadgeLabel.set_text(text)
- }
-
- toggleNotificationBadge(activate) {
- if (activate && this._notificationBadgeCount > 0) {
- this.updateNotificationBadge()
- this._notificationBadgeBin.show()
- } else this._notificationBadgeBin.hide()
- }
-
- _showProgressOverlay() {
- if (this._progressOverlayArea) {
- this._updateProgressOverlay()
- return
- }
-
- this._progressOverlayArea = new St.DrawingArea({
- x_expand: true,
- y_expand: true,
- })
- this._progressOverlayArea.add_style_class_name('progress-bar')
- this._progressOverlayArea.connect('repaint', () => {
- this._drawProgressOverlay(this._progressOverlayArea)
- })
-
- this._source._iconContainer.add_child(this._progressOverlayArea)
- let node = this._progressOverlayArea.get_theme_node()
-
- let [hasColor, color] = node.lookup_color('-progress-bar-background', false)
- if (hasColor) this._progressbar_background = color
- else
- this._progressbar_background = new Utils.ColorUtils.Color({
- red: 204,
- green: 204,
- blue: 204,
- alpha: 255,
- })
- ;[hasColor, color] = node.lookup_color('-progress-bar-border', false)
- if (hasColor) this._progressbar_border = color
- else
- this._progressbar_border = new Utils.ColorUtils.Color({
- red: 230,
- green: 230,
- blue: 230,
- alpha: 255,
- })
-
- this._updateProgressOverlay()
- }
-
- _hideProgressOverlay() {
- if (this._progressOverlayArea) this._progressOverlayArea.destroy()
-
- this._progressOverlayArea = null
- this._progressbar_background = null
- this._progressbar_border = null
- }
-
- _updateProgressOverlay() {
- if (this._progressOverlayArea) {
- this._progressOverlayArea.queue_repaint()
- }
- }
-
- _drawProgressOverlay(area) {
- let scaleFactor = Utils.getScaleFactor()
- let [surfaceWidth, surfaceHeight] = area.get_surface_size()
- let cr = area.get_context()
-
- let iconSize = this._source.icon.iconSize * scaleFactor
-
- let x = Math.floor((surfaceWidth - iconSize) / 2)
- let y = Math.floor((surfaceHeight - iconSize) / 2)
-
- let lineWidth = Math.floor(1.0 * scaleFactor)
- let padding = Math.floor(iconSize * 0.05)
- let width = iconSize - 2.0 * padding
- let height = Math.floor(Math.min(18.0 * scaleFactor, 0.2 * iconSize))
- x += padding
- y += iconSize - height - padding
-
- cr.setLineWidth(lineWidth)
-
- // Draw the outer stroke
- let stroke = new Cairo.LinearGradient(0, y, 0, y + height)
- let fill = null
- stroke.addColorStopRGBA(0.5, 0.5, 0.5, 0.5, 0.1)
- 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,
- )
-
- // Draw the background
- x += lineWidth
- y += lineWidth
- width -= 2.0 * lineWidth
- height -= 2.0 * lineWidth
-
- stroke = Cairo.SolidPattern.createRGBA(0.2, 0.2, 0.2, 0.9)
- fill = new Cairo.LinearGradient(0, y, 0, y + height)
- fill.addColorStopRGBA(0.4, 0.25, 0.25, 0.25, 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,
- )
-
- // Draw the finished bar
- x += lineWidth
- y += lineWidth
- width -= 2.0 * lineWidth
- height -= 2.0 * lineWidth
-
- let finishedWidth = Math.ceil(this._progress * width)
-
- let bg = this._progressbar_background
- let bd = this._progressbar_border
-
- stroke = Cairo.SolidPattern.createRGBA(
- 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)
- Utils.drawRoundedLine(
- cr,
- x + lineWidth / 2.0 + width - finishedWidth,
- y + lineWidth / 2.0,
- finishedWidth,
- height,
- true,
- true,
- stroke,
- fill,
- )
- else
- Utils.drawRoundedLine(
- cr,
- x + lineWidth / 2.0,
- y + lineWidth / 2.0,
- finishedWidth,
- height,
- true,
- true,
- stroke,
- fill,
- )
-
- cr.$dispose()
- }
-
- setProgress(progress) {
- this._progress = Math.min(Math.max(progress, 0.0), 1.0)
- this._updateProgressOverlay()
- }
-
- toggleProgressOverlay(activate) {
- if (activate) {
- this._showProgressOverlay()
- } else {
- this._hideProgressOverlay()
- }
- }
-
- insertEntry(appProgress) {
- if (
- !appProgress ||
- this._progressManagerEntries.indexOf(appProgress) !== -1
- )
- return
-
- this._progressManagerEntries.push(appProgress)
- this._selectEntry(appProgress)
- }
-
- removeEntry(appProgress) {
- if (!appProgress || this._progressManagerEntries.indexOf(appProgress) == -1)
- return
-
- this._progressManagerEntries.splice(
- this._progressManagerEntries.indexOf(appProgress),
- 1,
- )
-
- if (this._progressManagerEntries.length > 0) {
- this._selectEntry(
- this._progressManagerEntries[this._progressManagerEntries.length - 1],
- )
- } else {
- this.setNotificationBadge(0)
- this.toggleNotificationBadge(false)
- this.setProgress(0)
- this.toggleProgressOverlay(false)
- this.setUrgent(false)
- }
- }
-
- _selectEntry(appProgress) {
- if (!appProgress) return
-
- this._signalsHandler.removeWithLabel('progress-entry')
-
- this._signalsHandler.addWithLabel(
- 'progress-entry',
- [
- appProgress,
- 'count-changed',
- (appProgress, value) => {
- this.setNotificationBadge(value)
- },
- ],
- [
- appProgress,
- 'count-visible-changed',
- (appProgress, value) => {
- this.toggleNotificationBadge(value)
- },
- ],
- [
- appProgress,
- 'progress-changed',
- (appProgress, value) => {
- this.setProgress(value)
- },
- ],
- [
- appProgress,
- 'progress-visible-changed',
- (appProgress, value) => {
- this.toggleProgressOverlay(value)
- },
- ],
- [
- appProgress,
- 'urgent-changed',
- (appProgress, value) => {
- this.setUrgent(value)
- },
- ],
- )
-
- this.setNotificationBadge(appProgress.count())
- this.toggleNotificationBadge(appProgress.countVisible())
- this.setProgress(appProgress.progress())
- this.toggleProgressOverlay(appProgress.progressVisible())
-
- this._isUrgent = false
- }
-
- setUrgent(urgent) {
- const icon = this._source.icon._iconBin
- if (urgent) {
- if (!this._isUrgent) {
- icon.set_pivot_point(0.5, 0.5)
- this._source.iconAnimator.addAnimation(icon, 'dance')
- this._isUrgent = true
- }
- } else {
- if (this._isUrgent) {
- this._source.iconAnimator.removeAnimation(icon, 'dance')
- this._isUrgent = false
- }
- icon.rotation_angle_z = 0
- }
- }
-}
diff --git a/src/stylesheet.css b/src/stylesheet.css
index 8b951bf..96fb7c9 100644
--- a/src/stylesheet.css
+++ b/src/stylesheet.css
@@ -153,7 +153,7 @@
}
#dashtopanelScrollview .notification-badge {
- background-color: rgba(255,0,0,0.8);
+ background-color: rgba(214, 0, 0, 0.8);
}
#dashtopanelScrollview .progress-bar {
diff --git a/src/taskbar.js b/src/taskbar.js
index 30ee3d0..d66a993 100644
--- a/src/taskbar.js
+++ b/src/taskbar.js
@@ -64,6 +64,7 @@ let donateDummyApp = {
action == 'opts' ? _('Donation options') : '',
},
connect: () => [],
+ disconnect: () => false,
connectObject: () => [],
get_id: () => 'dtp_donate',
get_windows: () => [],
@@ -1197,10 +1198,8 @@ export const Taskbar = class extends EventEmitter {
// This is required for icon reordering when the scrollview is used.
this._updateAppIcons()
- // This will update the size, and the corresponding number for each icon on the primary panel
- if (this.dtpPanel.isPrimary) {
- this._updateNumberOverlay()
- }
+ // This will update the size, and the corresponding number for each icon
+ this._updateHotkeysNumberOverlay()
this._shownInitially = true
}
@@ -1276,7 +1275,7 @@ export const Taskbar = class extends EventEmitter {
}
}
- _updateNumberOverlay() {
+ _updateHotkeysNumberOverlay() {
let seenApps = {}
let counter = 0
@@ -1287,26 +1286,24 @@ export const Taskbar = class extends EventEmitter {
}
if (counter <= 10) {
- icon.setNumberOverlay(counter == 10 ? 0 : counter)
+ icon.setHotkeysNumberOverlayLabel(counter == 10 ? 0 : counter)
} else {
// No overlay after 10
- icon.setNumberOverlay(-1)
+ icon.setHotkeysNumberOverlayLabel(-1)
}
-
- icon.updateHotkeyNumberOverlay()
})
if (
SETTINGS.get_boolean('hot-keys') &&
SETTINGS.get_string('hotkeys-overlay-combo') === 'ALWAYS'
)
- this.toggleNumberOverlay(true)
+ this.toggleHotkeysNumberOverlay(true)
}
- toggleNumberOverlay(activate) {
+ toggleHotkeysNumberOverlay(activate) {
let appIcons = this._getAppIcons()
appIcons.forEach(function (icon) {
- icon.toggleNumberOverlay(activate)
+ icon.toggleHotkeysNumberOverlay(activate)
})
}