messageTray: Let the tray decide whether to show a banner
Always use the same code path to add new messages to a source, and let the `MessageTray` decide whether it shows a banner. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3173>
This commit is contained in:
parent
940b658071
commit
34f05b075b
@ -203,7 +203,7 @@ class AutorunDispatcher {
|
|||||||
});
|
});
|
||||||
notification.connect('destroy', () => this._notifications.delete(mount));
|
notification.connect('destroy', () => this._notifications.delete(mount));
|
||||||
this._notifications.set(mount, notification);
|
this._notifications.set(mount, notification);
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
addMount(mount, apps, contentTypes) {
|
addMount(mount, apps, contentTypes) {
|
||||||
|
@ -797,7 +797,7 @@ class NetworkAgent {
|
|||||||
delete this._notifications[requestId];
|
delete this._notifications[requestId];
|
||||||
});
|
});
|
||||||
|
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
_newRequest(agent, requestId, connection, settingName, hints, flags) {
|
_newRequest(agent, requestId, connection, settingName, hints, flags) {
|
||||||
|
@ -354,7 +354,7 @@ export class ExtensionManager extends Signals.EventEmitter {
|
|||||||
_('Extension updates are ready to be installed.'));
|
_('Extension updates are ready to be installed.'));
|
||||||
notification.connect('activated',
|
notification.connect('activated',
|
||||||
() => source.open());
|
() => source.open());
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ async function _initializeUI() {
|
|||||||
notification.addAction(_('Undo'),
|
notification.addAction(_('Undo'),
|
||||||
() => (global.context.unsafe_mode = false));
|
() => (global.context.unsafe_mode = false));
|
||||||
notification.setTransient(true);
|
notification.setTransient(true);
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Provide the bus object for gnome-session to
|
// Provide the bus object for gnome-session to
|
||||||
@ -616,7 +616,7 @@ export function notify(msg, details) {
|
|||||||
const source = MessageTray.getSystemSource();
|
const source = MessageTray.getSystemSource();
|
||||||
let notification = new MessageTray.Notification(source, msg, details);
|
let notification = new MessageTray.Notification(source, msg, details);
|
||||||
notification.setTransient(true);
|
notification.setTransient(true);
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -590,7 +590,7 @@ export const Source = GObject.registerClass({
|
|||||||
'destroy': {param_types: [GObject.TYPE_UINT]},
|
'destroy': {param_types: [GObject.TYPE_UINT]},
|
||||||
'notification-added': {param_types: [Notification.$gtype]},
|
'notification-added': {param_types: [Notification.$gtype]},
|
||||||
'notification-removed': {param_types: [Notification.$gtype]},
|
'notification-removed': {param_types: [Notification.$gtype]},
|
||||||
'notification-show': {param_types: [Notification.$gtype]},
|
'notification-request-banner': {param_types: [Notification.$gtype]},
|
||||||
},
|
},
|
||||||
}, class Source extends MessageList.Source {
|
}, class Source extends MessageList.Source {
|
||||||
constructor(params) {
|
constructor(params) {
|
||||||
@ -647,7 +647,7 @@ export const Source = GObject.registerClass({
|
|||||||
this.destroy();
|
this.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
pushNotification(notification) {
|
addNotification(notification) {
|
||||||
if (this.notifications.includes(notification))
|
if (this.notifications.includes(notification))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -655,22 +655,17 @@ export const Source = GObject.registerClass({
|
|||||||
this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED);
|
this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED);
|
||||||
|
|
||||||
notification.connect('destroy', this._onNotificationDestroy.bind(this));
|
notification.connect('destroy', this._onNotificationDestroy.bind(this));
|
||||||
notification.connect('notify::acknowledged', this.countUpdated.bind(this));
|
notification.connect('notify::acknowledged', () => {
|
||||||
|
this.countUpdated();
|
||||||
|
|
||||||
|
// If acknowledged was set to false try to show the notification again
|
||||||
|
if (!notification.acknowledged)
|
||||||
|
this.emit('notification-request-banner', notification);
|
||||||
|
});
|
||||||
this.notifications.push(notification);
|
this.notifications.push(notification);
|
||||||
|
|
||||||
this.emit('notification-added', notification);
|
this.emit('notification-added', notification);
|
||||||
|
this.emit('notification-request-banner', notification);
|
||||||
this.countUpdated();
|
|
||||||
}
|
|
||||||
|
|
||||||
showNotification(notification) {
|
|
||||||
notification.acknowledged = false;
|
|
||||||
this.pushNotification(notification);
|
|
||||||
|
|
||||||
if (notification.urgency === Urgency.LOW)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this.policy.showBanners || notification.urgency === Urgency.CRITICAL)
|
|
||||||
this.emit('notification-show', notification);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy(reason) {
|
destroy(reason) {
|
||||||
@ -876,7 +871,7 @@ export const MessageTray = GObject.registerClass({
|
|||||||
this._sources.add(source);
|
this._sources.add(source);
|
||||||
|
|
||||||
source.connectObject(
|
source.connectObject(
|
||||||
'notification-show', this._onNotificationShow.bind(this),
|
'notification-request-banner', this._onNotificationRequestBanner.bind(this),
|
||||||
'notification-removed', this._onNotificationRemoved.bind(this),
|
'notification-removed', this._onNotificationRemoved.bind(this),
|
||||||
'destroy', () => this._removeSource(source), this);
|
'destroy', () => this._removeSource(source), this);
|
||||||
|
|
||||||
@ -923,7 +918,17 @@ export const MessageTray = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onNotificationShow(_source, notification) {
|
_onNotificationRequestBanner(_source, notification) {
|
||||||
|
// We never display a banner for already acknowledged notifications
|
||||||
|
if (notification.acknowledged)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (notification.urgency === Urgency.LOW)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!notification.source.policy.showBanners && notification.urgency !== Urgency.CRITICAL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (this._notification === notification) {
|
if (this._notification === notification) {
|
||||||
// If a notification that is being shown is updated, we update
|
// If a notification that is being shown is updated, we update
|
||||||
// how it is shown and extend the time until it auto-hides.
|
// how it is shown and extend the time until it auto-hides.
|
||||||
|
@ -200,6 +200,7 @@ class FdoNotificationDaemon {
|
|||||||
const soundFile = 'sound-file' in hints
|
const soundFile = 'sound-file' in hints
|
||||||
? Gio.File.new_for_path(hints['sound-file']) : null;
|
? Gio.File.new_for_path(hints['sound-file']) : null;
|
||||||
|
|
||||||
|
notification.acknowledged = false;
|
||||||
notification.update(summary, body, {
|
notification.update(summary, body, {
|
||||||
gicon,
|
gicon,
|
||||||
bannerMarkup: true,
|
bannerMarkup: true,
|
||||||
@ -355,10 +356,12 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
// Acknowledge notifications that are resident and their app has the
|
||||||
|
// current focus so that we don't show a banner.
|
||||||
if (notification.resident && this.app && tracker.focus_app === this.app)
|
if (notification.resident && this.app && tracker.focus_app === this.app)
|
||||||
this.pushNotification(notification);
|
notification.acknowledged = true;
|
||||||
else
|
|
||||||
this.showNotification(notification);
|
this.addNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
@ -402,9 +405,10 @@ const PRIORITY_URGENCY_MAP = {
|
|||||||
|
|
||||||
const GtkNotificationDaemonNotification = GObject.registerClass(
|
const GtkNotificationDaemonNotification = GObject.registerClass(
|
||||||
class GtkNotificationDaemonNotification extends MessageTray.Notification {
|
class GtkNotificationDaemonNotification extends MessageTray.Notification {
|
||||||
_init(source, notification) {
|
_init(source, id, notification) {
|
||||||
super._init(source);
|
super._init(source);
|
||||||
this._serialized = GLib.Variant.new('a{sv}', notification);
|
this._serialized = GLib.Variant.new('a{sv}', notification);
|
||||||
|
this.id = id;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
title,
|
title,
|
||||||
@ -499,15 +503,12 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
|||||||
this._notificationPending = false;
|
this._notificationPending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createNotification(params) {
|
|
||||||
return new GtkNotificationDaemonNotification(this, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
activateAction(actionId, target) {
|
activateAction(actionId, target) {
|
||||||
const params = target ? GLib.Variant.new('av', [target]) : null;
|
const params = target ? GLib.Variant.new('av', [target]) : null;
|
||||||
this._app.activate_action(actionId, params, 0, -1, null).catch(error => {
|
this._app.activate_action(actionId, params, 0, -1, null).catch(error => {
|
||||||
logError(error, `Failed to activate action for ${this._appId}`);
|
logError(error, `Failed to activate action for ${this._appId}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
Main.panel.closeCalendar();
|
Main.panel.closeCalendar();
|
||||||
}
|
}
|
||||||
@ -518,22 +519,18 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
|||||||
Main.panel.closeCalendar();
|
Main.panel.closeCalendar();
|
||||||
}
|
}
|
||||||
|
|
||||||
addNotification(notificationId, notificationParams, showBanner) {
|
addNotification(notification) {
|
||||||
this._notificationPending = true;
|
this._notificationPending = true;
|
||||||
|
|
||||||
if (this._notifications[notificationId])
|
this._notifications[notification.id]?.destroy(
|
||||||
this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.REPLACED);
|
MessageTray.NotificationDestroyedReason.REPLACED);
|
||||||
|
|
||||||
let notification = this._createNotification(notificationParams);
|
|
||||||
notification.connect('destroy', () => {
|
notification.connect('destroy', () => {
|
||||||
delete this._notifications[notificationId];
|
delete this._notifications[notification.id];
|
||||||
});
|
});
|
||||||
this._notifications[notificationId] = notification;
|
this._notifications[notification.id] = notification;
|
||||||
|
|
||||||
if (showBanner)
|
super.addNotification(notification);
|
||||||
this.showNotification(notification);
|
|
||||||
else
|
|
||||||
this.pushNotification(notification);
|
|
||||||
|
|
||||||
this._notificationPending = false;
|
this._notificationPending = false;
|
||||||
}
|
}
|
||||||
@ -609,8 +606,13 @@ class GtkNotificationDaemon {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
notifications.forEach(([notificationId, notification]) => {
|
notifications.forEach(([notificationId, notificationPacked]) => {
|
||||||
source.addNotification(notificationId, notification.deepUnpack(), false);
|
const notification = new GtkNotificationDaemonNotification(source,
|
||||||
|
notificationId,
|
||||||
|
notificationPacked.deepUnpack());
|
||||||
|
// Acknowledge all stored notification so that we don't show a banner again
|
||||||
|
notification.acknowledged = true;
|
||||||
|
source.addNotification(notification);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -635,7 +637,7 @@ class GtkNotificationDaemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddNotificationAsync(params, invocation) {
|
AddNotificationAsync(params, invocation) {
|
||||||
let [appId, notificationId, notification] = params;
|
let [appId, notificationId, notificationSerialized] = params;
|
||||||
|
|
||||||
let source;
|
let source;
|
||||||
try {
|
try {
|
||||||
@ -651,9 +653,12 @@ class GtkNotificationDaemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let timestamp = GLib.DateTime.new_now_local().to_unix();
|
let timestamp = GLib.DateTime.new_now_local().to_unix();
|
||||||
notification['timestamp'] = new GLib.Variant('x', timestamp);
|
notificationSerialized['timestamp'] = new GLib.Variant('x', timestamp);
|
||||||
|
|
||||||
source.addNotification(notificationId, notification, true);
|
const notification = new GtkNotificationDaemonNotification(source,
|
||||||
|
notificationId,
|
||||||
|
notificationSerialized);
|
||||||
|
source.addNotification(notification);
|
||||||
|
|
||||||
invocation.return_value(null);
|
invocation.return_value(null);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class ShellInfo {
|
|||||||
if (undoCallback)
|
if (undoCallback)
|
||||||
this._notification.addAction(_('Undo'), () => undoCallback());
|
this._notification.addAction(_('Undo'), () => undoCallback());
|
||||||
|
|
||||||
source.showNotification(this._notification);
|
source.addNotification(this._notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2122,7 +2122,7 @@ export const ScreenshotUI = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
get screencast_in_progress() {
|
get screencast_in_progress() {
|
||||||
@ -2364,7 +2364,7 @@ function _storeScreenshot(bytes, pixbuf) {
|
|||||||
|
|
||||||
notification.setTransient(true);
|
notification.setTransient(true);
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ export class ShellMountOperation {
|
|||||||
this._notification.setTransient(true);
|
this._notification.setTransient(true);
|
||||||
this._notification.iconName = 'media-removable-symbolic';
|
this._notification.iconName = 'media-removable-symbolic';
|
||||||
this._notification.connect('destroy', () => delete this._notification);
|
this._notification.connect('destroy', () => delete this._notification);
|
||||||
source.showNotification(this._notification);
|
source.addNotification(this._notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
_showUnmountNotificationDone(message) {
|
_showUnmountNotificationDone(message) {
|
||||||
|
@ -2039,7 +2039,7 @@ class Indicator extends SystemIndicator {
|
|||||||
this._notification.connect('destroy',
|
this._notification.connect('destroy',
|
||||||
() => (this._notification = null));
|
() => (this._notification = null));
|
||||||
|
|
||||||
source.showNotification(this._notification);
|
source.addNotification(this._notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
_syncMainConnection() {
|
_syncMainConnection() {
|
||||||
|
@ -268,7 +268,7 @@ class Indicator extends SystemIndicator {
|
|||||||
const app = Shell.AppSystem.get_default().lookup_app('gnome-thunderbolt-panel.desktop');
|
const app = Shell.AppSystem.get_default().lookup_app('gnome-thunderbolt-panel.desktop');
|
||||||
app?.activate();
|
app?.activate();
|
||||||
});
|
});
|
||||||
source.showNotification(this._notification);
|
source.addNotification(this._notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Session callbacks */
|
/* Session callbacks */
|
||||||
|
@ -45,7 +45,7 @@ export class WindowAttentionHandler {
|
|||||||
});
|
});
|
||||||
notification.setForFeedback(true);
|
notification.setForFeedback(true);
|
||||||
|
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
|
|
||||||
window.connectObject('notify::title', () => {
|
window.connectObject('notify::title', () => {
|
||||||
[title, banner] = this._getTitleAndBanner(app, window);
|
[title, banner] = this._getTitleAndBanner(app, window);
|
||||||
|
@ -53,12 +53,12 @@ export async function run() {
|
|||||||
const source = new MessageTray.getSystemSource();
|
const source = new MessageTray.getSystemSource();
|
||||||
|
|
||||||
Scripting.scriptEvent('notificationShowStart');
|
Scripting.scriptEvent('notificationShowStart');
|
||||||
source.connect('notification-show',
|
source.connect('notification-request-banner',
|
||||||
() => Scripting.scriptEvent('notificationShowDone'));
|
() => Scripting.scriptEvent('notificationShowDone'));
|
||||||
|
|
||||||
const notification = new MessageTray.Notification(source,
|
const notification = new MessageTray.Notification(source,
|
||||||
'A test notification');
|
'A test notification');
|
||||||
source.showNotification(notification);
|
source.addNotification(notification);
|
||||||
await Scripting.sleep(400);
|
await Scripting.sleep(400);
|
||||||
|
|
||||||
console.debug('Show date menu');
|
console.debug('Show date menu');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user