Centralize notifications state

This commit is contained in:
Charles Gagnon
2025-02-10 15:01:52 -05:00
parent b5cdd6e240
commit f162ac0624
4 changed files with 95 additions and 84 deletions

View File

@@ -120,7 +120,6 @@ 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
@@ -223,6 +222,11 @@ export const TaskbarAppIcon = GObject.registerClass(
this._numberOverlay()
this._signalsHandler.add(
[
this,
'notify::mapped',
() => (this.mapped ? this._handleNotifications() : null),
],
[
Utils.getStageTheme(),
'changed',
@@ -300,6 +304,11 @@ export const TaskbarAppIcon = GObject.registerClass(
`update-${this.app.id}`,
this._handleNotifications.bind(this),
],
[
SETTINGS,
'changed::progress-show-count',
this._handleNotifications.bind(this),
],
[
SETTINGS,
'changed::animate-appicon-hover',
@@ -1599,67 +1608,49 @@ export const TaskbarAppIcon = GObject.registerClass(
cr.$dispose()
}
_handleNotifications(notificationsMonitor, state) {
if (!this._nWindows && !this.window) {
delete this._notifications.total
return
}
_handleNotifications() {
if (!this._nWindows && !this.window) return
let urgent =
'urgent' in state ? state.urgent : this._notifications.urgent || false
let formatCount = (count) => {
if (!count) return 0
let monitor = this.dtpPanel.panelManager.notificationsMonitor
let state = monitor.getState(this.app)
let count = 0
return count > 10 ? '10+' : count
}
if (!state) return
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`](
if (SETTINGS.get_boolean('progress-show-count')) {
this.iconAnimator[`${state.urgent ? 'add' : 'remove'}Animation`](
this.icon._iconBin,
'dance',
)
this._notifications.urgent = urgent
if (state.total) count = state.total > 9 ? '9+' : state.total
}
// restore hotkeys number if no more notifications
this._maybeToggleNumberOverlay(
formatCount(this._notifications.total) ||
this._numberHotkeysOverlayLabel,
)
this._notificationsCount = count
this._maybeUpdateNumberOverlay()
}
_maybeToggleNumberOverlay(labelNumber) {
_maybeUpdateNumberOverlay() {
let visible = this._numberOverlayBin.visible
let shouldBeVisible =
this._hotkeysOverlayActive || this._notifications.total
(this._hotkeysOverlayActiveMode &&
this._numberHotkeysOverlayLabel > -1) ||
this._notificationsCount
let showNotifications =
this._notificationsCount &&
this._hotkeysOverlayActiveMode !== 'TEMPORARILY'
let label = showNotifications
? this._notificationsCount
: this._numberHotkeysOverlayLabel
this._numberOverlayLabel[
`${this._notifications.total ? 'add' : 'remove'}_style_class_name`
`${showNotifications ? 'add' : 'remove'}_style_class_name`
]('notification-badge')
if (
shouldBeVisible &&
labelNumber != this._numberOverlayLabel.get_text()
) {
this._numberOverlayLabel.set_text(labelNumber.toString())
if (shouldBeVisible && label !== this._numberOverlayLabel.get_text()) {
this._numberOverlayLabel.set_text(label.toString())
this._updateNumberOverlay()
}
@@ -1687,28 +1678,16 @@ export const TaskbarAppIcon = GObject.registerClass(
// pixels, so make sure to consider the scale.
// Set the font size to something smaller than the whole icon so it is
// still visible. The border radius is large to make the shape circular
let [, natWidth] = this._dtpIconContainer.get_preferred_width(-1)
let font_size = Math.round(
Math.max(12, 0.3 * natWidth) / Utils.getScaleFactor(),
let panelSize =
this.dtpPanel.geom[this.dtpPanel.checkIfVertical() ? 'w' : 'h']
let fontSize = Math.round(
Math.max(10, 0.3 * panelSize) / Utils.getScaleFactor(),
)
let size = Math.round(font_size * 1.3)
let style =
'font-size: ' +
font_size +
'px;' +
'border-radius: ' +
this.icon.iconSize +
'px;' +
'height: ' +
size +
'px;'
if (this._numberOverlayLabel.get_text().length == 1) {
style += 'width: ' + size + 'px;'
} else {
style += 'padding: 0 2px;'
}
let size = Math.round(fontSize * 1.3)
let style = `
font-size: ${fontSize}px;
height: ${size}px;
`
this._numberOverlayLabel.set_style(style)
}
@@ -1716,12 +1695,11 @@ export const TaskbarAppIcon = GObject.registerClass(
this._numberHotkeysOverlayLabel = number
}
toggleHotkeysNumberOverlay(activate) {
this._hotkeysOverlayActive =
activate && this._numberHotkeysOverlayLabel > -1
toggleHotkeysNumberOverlay(activateMode) {
this._hotkeysOverlayActiveMode =
this._numberHotkeysOverlayLabel > -1 && activateMode
if (!this._notifications.total)
this._maybeToggleNumberOverlay(this._numberHotkeysOverlayLabel)
this._maybeUpdateNumberOverlay()
}
handleDragOver(source) {

View File

@@ -33,6 +33,7 @@ export const NotificationsMonitor = class extends EventEmitter {
constructor() {
super()
this._state = {}
this._signalsHandler = new Utils.GlobalSignalsHandler()
// pretty much useless, but might as well keep it for now
@@ -59,7 +60,7 @@ export const NotificationsMonitor = class extends EventEmitter {
() => {
// reset notifications from message tray on app focus
if (tracker.focus_app)
this.dispatch(tracker.focus_app.id, { trayCount: 0 }, true)
this._updateState(tracker.focus_app.id, { trayCount: 0 }, true)
},
])
this._acquireUnityDBus()
@@ -75,10 +76,11 @@ export const NotificationsMonitor = class extends EventEmitter {
this._signalsHandler.destroy()
}
dispatch(appId, state, ignoreMapping) {
_updateState(appId, state, ignoreMapping) {
// depending of the notification source, some app id end
// with ".desktop" and some don't ¯\_(ツ)_/¯
appId = appId.replace('.desktop', '')
appId = `${appId}.desktop`
// some app have different source app id, deamon and such,
// but it maps to a desktop app so match those here
@@ -88,7 +90,29 @@ export const NotificationsMonitor = class extends EventEmitter {
knownCorrespondances[k].some((regex) => appId.match(regex)),
) || appId
this.emit(`update-${appId}.desktop`, state)
this._state[appId] = this._state[appId] || {}
this._mergeState(appId, state)
this.emit(`update-${appId}`)
}
getState(app) {
return this._state[app.id]
}
_mergeState(appId, state) {
this._state[appId] = Object.assign(this._state[appId], state)
if (tracker.focus_app?.id == appId) this._state[appId].trayCount = 0
this._state[appId].urgent =
state.urgent ||
(this._state[appId].trayUrgent && this._state[appId].trayCount) ||
false
this._state[appId].total =
((this._state[appId]['count-visible'] || 0) &&
(this._state[appId].count || 0)) + (this._state[appId].trayCount || 0)
}
_acquireUnityDBus() {
@@ -120,26 +144,30 @@ export const NotificationsMonitor = class extends EventEmitter {
for (let property in properties)
updates[property] = properties[property].unpack()
this.dispatch(appId, updates)
this._updateState(appId, updates)
}
_checkNotifications() {
let addSource = (tray, source) => {
let appId = source?._appId || source?.app?.id
let updateTray = () => {
this._updateState(appId, {
trayCount: source.count, // always source.unseenCount might be less annoying
trayUrgent: !!source.notifications.find(
(n) => n.urgency > MessageTray.Urgency.NORMAL,
),
})
}
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,
),
}),
updateTray,
])
updateTray()
}
this._signalsHandler.add(

View File

@@ -144,8 +144,11 @@
#dashtopanelScrollview .badge {
color: rgba(255, 255, 255, 1);
padding: 0.2em 0.5em;
border-radius: 1em;
font-weight: bold;
text-align: center;
margin: 0 0 0 2px;
}
#dashtopanelScrollview .number-overlay {

View File

@@ -1303,7 +1303,9 @@ export const Taskbar = class extends EventEmitter {
toggleHotkeysNumberOverlay(activate) {
let appIcons = this._getAppIcons()
appIcons.forEach(function (icon) {
icon.toggleHotkeysNumberOverlay(activate)
icon.toggleHotkeysNumberOverlay(
activate ? SETTINGS.get_string('hotkeys-overlay-combo') : false,
)
})
}