Add intellihide option to reveal the panel on notification

gh-2245
This commit is contained in:
Charles Gagnon
2025-02-24 17:42:58 -05:00
parent b5bca768f0
commit 880d5c6867
7 changed files with 98 additions and 15 deletions

View File

@@ -363,9 +363,13 @@
</key> </key>
<key type="b" name="intellihide-show-in-fullscreen"> <key type="b" name="intellihide-show-in-fullscreen">
<default>false</default> <default>false</default>
<summary>Intellihide pressure</summary> <summary>Allow revealing the panel while in fullscreen</summary>
<description>Allow the panel to be revealed while an application is in fullscreen mode</description> <description>Allow the panel to be revealed while an application is in fullscreen mode</description>
</key> </key>
<key type="b" name="intellihide-show-on-notification">
<default>false</default>
<summary>Reveal the panel on notification</summary>
</key>
<key type="b" name="intellihide-only-secondary"> <key type="b" name="intellihide-only-secondary">
<default>false</default> <default>false</default>
<summary>Intellihide only secondary</summary> <summary>Intellihide only secondary</summary>

View File

@@ -40,6 +40,7 @@ import * as Util from 'resource:///org/gnome/shell/misc/util.js'
import * as BoxPointer from 'resource:///org/gnome/shell/ui/boxpointer.js' import * as BoxPointer from 'resource:///org/gnome/shell/ui/boxpointer.js'
import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js' import { EventEmitter } from 'resource:///org/gnome/shell/misc/signals.js'
import { Hold } from './intellihide.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
import * as Taskbar from './taskbar.js' import * as Taskbar from './taskbar.js'
import { import {
@@ -224,7 +225,10 @@ export const TaskbarAppIcon = GObject.registerClass(
[ [
this, this,
'notify::mapped', 'notify::mapped',
() => (this.mapped ? this._handleNotifications() : null), () =>
this.mapped && !this.dtpPanel.intellihide.enabled
? this._handleNotifications()
: null,
], ],
[ [
Utils.getStageTheme(), Utils.getStageTheme(),
@@ -1614,7 +1618,10 @@ export const TaskbarAppIcon = GObject.registerClass(
'dance', 'dance',
) )
if (state.total) count = state.total > 9 ? '9+' : state.total if (state.total) {
count = state.total > 9 ? '9+' : state.total
this.dtpPanel.intellihide.revealAndHold(Hold.NOTIFY)
} else this.dtpPanel.intellihide.release(Hold.NOTIFY)
} }
this._notificationsCount = count this._notificationsCount = count

View File

@@ -50,6 +50,7 @@ export const Hold = {
NONE: 0, NONE: 0,
TEMPORARY: 1, TEMPORARY: 1,
PERMANENT: 2, PERMANENT: 2,
NOTIFY: 4,
} }
export const Intellihide = class { export const Intellihide = class {
@@ -59,6 +60,7 @@ export const Intellihide = class {
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._holdCount = {}
this._signalsHandler = new Utils.GlobalSignalsHandler() this._signalsHandler = new Utils.GlobalSignalsHandler()
this._timeoutsHandler = new Utils.TimeoutsHandler() this._timeoutsHandler = new Utils.TimeoutsHandler()
@@ -129,6 +131,8 @@ export const Intellihide = class {
} }
disable(reset) { disable(reset) {
this.enabled = false
if (this._proximityWatchId) { if (this._proximityWatchId) {
this._proximityManager.removeWatch(this._proximityWatchId) this._proximityManager.removeWatch(this._proximityWatchId)
} }
@@ -141,8 +145,6 @@ export const Intellihide = class {
this._removeRevealMechanism() this._removeRevealMechanism()
this._revealPanel(!reset) this._revealPanel(!reset)
this.enabled = false
} }
destroy() { destroy() {
@@ -161,18 +163,35 @@ export const Intellihide = class {
} }
revealAndHold(holdStatus) { revealAndHold(holdStatus) {
if (this.enabled && !this._holdStatus) { if (
this._revealPanel() !this.enabled ||
} (holdStatus == Hold.NOTIFY &&
!SETTINGS.get_boolean('intellihide-show-on-notification'))
)
return
if (!this._holdStatus) this._revealPanel()
this._holdStatus |= holdStatus this._holdStatus |= holdStatus
this._holdCount[holdStatus] = (this._holdCount[holdStatus] || 0) + 1
this._maybePersistHoldStatus() this._maybePersistHoldStatus()
} }
release(holdStatus) { release(holdStatus) {
this._holdStatus -= holdStatus if (!this.enabled) return
if (this.enabled && !this._holdStatus) { if (this._holdStatus & holdStatus && !--this._holdCount[holdStatus])
this._holdStatus -= holdStatus
if (holdStatus == Hold.PERMANENT && this._holdStatus & Hold.NOTIFY) {
// the user pressed the keyboard shortcut to hide the panel while a
// notification hold is present, clear it to hide the panel
this._holdStatus -= Hold.NOTIFY
this._holdCount[Hold.NOTIFY] = 0
}
if (!this._holdStatus) {
this._maybePersistHoldStatus() this._maybePersistHoldStatus()
this._queueUpdatePanelPosition() this._queueUpdatePanelPosition()
} }

View File

@@ -58,9 +58,11 @@ export const NotificationsMonitor = class extends EventEmitter {
tracker, tracker,
'notify::focus-app', 'notify::focus-app',
() => { () => {
let appId = tracker.focus_app?.id
// reset notifications from message tray on app focus // reset notifications from message tray on app focus
if (tracker.focus_app) if (tracker.focus_app && this._state[appId])
this._updateState(tracker.focus_app.id, { trayCount: 0 }, true) this._updateState(tracker.focus_app.id, this._getDefaultState(), true)
}, },
]) ])
this._acquireUnityDBus() this._acquireUnityDBus()
@@ -90,10 +92,13 @@ export const NotificationsMonitor = class extends EventEmitter {
) || appId ) || appId
appId = `${appId}.desktop` appId = `${appId}.desktop`
this._state[appId] = this._state[appId] || {} this._state[appId] = this._state[appId] || this._getDefaultState()
this._mergeState(appId, state)
this.emit(`update-${appId}`) if (this._mergeState(appId, state)) this.emit(`update-${appId}`)
}
_getDefaultState() {
return { trayCount: 0, trayUrgent: false, urgent: false, total: 0 }
} }
getState(app) { getState(app) {
@@ -101,6 +106,8 @@ export const NotificationsMonitor = class extends EventEmitter {
} }
_mergeState(appId, state) { _mergeState(appId, state) {
let currenState = JSON.stringify(this._state[appId])
this._state[appId] = Object.assign(this._state[appId], state) this._state[appId] = Object.assign(this._state[appId], state)
if (tracker.focus_app?.id == appId) this._state[appId].trayCount = 0 if (tracker.focus_app?.id == appId) this._state[appId].trayCount = 0
@@ -113,6 +120,8 @@ export const NotificationsMonitor = class extends EventEmitter {
this._state[appId].total = this._state[appId].total =
((this._state[appId]['count-visible'] || 0) && ((this._state[appId]['count-visible'] || 0) &&
(this._state[appId].count || 0)) + (this._state[appId].trayCount || 0) (this._state[appId].count || 0)) + (this._state[appId].trayCount || 0)
return currenState != JSON.stringify(this._state[appId])
} }
_acquireUnityDBus() { _acquireUnityDBus() {

View File

@@ -803,6 +803,22 @@ export const IconAnimator = class {
} }
addAnimation(target, name) { addAnimation(target, name) {
// before adding a new animation, remove previous one to only have one running
let animationNames = Object.keys(this._animations)
for (let i = 0; i < animationNames.length; ++i) {
let n = animationNames[i]
let currentAnimationPair = this._animations[n].find(
(p) => p.target == target,
)
if (currentAnimationPair) {
if (n == name) return // already have this animation running, nothing else to do
this.removeAnimation(currentAnimationPair.target, n)
}
}
const targetDestroyId = target.connect('destroy', () => const targetDestroyId = target.connect('destroy', () =>
this.removeAnimation(target, name), this.removeAnimation(target, name),
) )

View File

@@ -1695,6 +1695,13 @@ const Preferences = class {
) )
}) })
this._settings.bind(
'intellihide-show-on-notification',
this._builder.get_object('intellihide_show_on_notification_switch'),
'active',
Gio.SettingsBindFlags.DEFAULT,
)
this._builder this._builder
.get_object('intellihide_animation_time_spinbutton') .get_object('intellihide_animation_time_spinbutton')
.set_value(this._settings.get_int('intellihide-animation-time')) .set_value(this._settings.get_int('intellihide-animation-time'))
@@ -1751,6 +1758,16 @@ const Preferences = class {
'intellihide-show-in-fullscreen', 'intellihide-show-in-fullscreen',
), ),
) )
this._settings.set_value(
'intellihide-show-on-notification',
this._settings.get_default_value(
'intellihide-show-on-notification',
),
)
this._settings.set_value(
'intellihide-persisted-state',
this._settings.get_default_value('intellihide-persisted-state'),
)
this._settings.set_value( this._settings.set_value(
'intellihide-only-secondary', 'intellihide-only-secondary',
this._settings.get_default_value('intellihide-only-secondary'), this._settings.get_default_value('intellihide-only-secondary'),

View File

@@ -157,6 +157,17 @@
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="AdwActionRow">
<property name="subtitle">(requires show notification counter badge option)</property>
<property name="title" translatable="yes">Reveal and hold the panel on notification</property>
<child>
<object class="GtkSwitch" id="intellihide_show_on_notification_switch">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
<child> <child>