notification: Pass policy in the Source contructor

Commit 932ccac1 changed Source to use a regular constructor
instead of `_init()`.

Unfortunately that results in ordering issues for subclasses
that override `_createPolicy()`, if that method needs to access
any properties that are set in the constructor (as `this` is
only available after chaining up to the parent).

We can fix that by simply setting the policy from the constructor,
instead of relying on some overriden method being called.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3170>
This commit is contained in:
Florian Müllner 2024-02-06 18:16:29 +01:00 committed by Marge Bot
parent 810391f41e
commit 3fc7ed4088
4 changed files with 53 additions and 81 deletions

View File

@ -307,13 +307,19 @@ class TelepathyClient extends Tp.BaseClient {
const ChatSource = HAVE_TP ? GObject.registerClass( const ChatSource = HAVE_TP ? GObject.registerClass(
class ChatSource extends MessageTray.Source { class ChatSource extends MessageTray.Source {
_init(account, conn, channel, contact, client) { constructor(account, conn, channel, contact, client) {
const appId = account.protocol_name === 'irc'
? 'org.gnome.Polari'
: 'empathy';
const policy =
new MessageTray.NotificationApplicationPolicy(appId);
super({policy});
this._account = account; this._account = account;
this._contact = contact; this._contact = contact;
this._client = client; this._client = client;
super._init();
this._pendingMessages = []; this._pendingMessages = [];
this._conn = conn; this._conn = conn;
@ -356,12 +362,6 @@ class ChatSource extends MessageTray.Source {
this.pushNotification(this._notification); this.pushNotification(this._notification);
} }
_createPolicy() {
if (this._account.protocol_name === 'irc')
return new MessageTray.NotificationApplicationPolicy('org.gnome.Polari');
return new MessageTray.NotificationApplicationPolicy('empathy');
}
createBanner() { createBanner() {
this._banner = new ChatNotificationBanner(this._notification); this._banner = new ChatNotificationBanner(this._notification);

View File

@ -824,20 +824,19 @@ export class ExtensionManager extends Signals.EventEmitter {
const ExtensionUpdateSource = GObject.registerClass( const ExtensionUpdateSource = GObject.registerClass(
class ExtensionUpdateSource extends MessageTray.Source { class ExtensionUpdateSource extends MessageTray.Source {
_init() { constructor() {
let appSys = Shell.AppSystem.get_default(); const appSys = Shell.AppSystem.get_default();
this._app = appSys.lookup_app('org.gnome.Extensions.desktop'); const app =
if (!this._app) appSys.lookup_app('org.gnome.Extensions.desktop') ||
this._app = appSys.lookup_app('com.mattjakeman.ExtensionManager.desktop'); appSys.lookup_app('com.mattjakeman.ExtensionManager.desktop');
super._init({ super({
title: this._app.get_name(), title: app.get_name(),
icon: this._app.get_icon(), icon: app.get_icon(),
policy: MessageTray.NotificationPolicy.newForApp(app),
}); });
}
_createPolicy() { this._app = app;
return new MessageTray.NotificationApplicationPolicy(this._app.id);
} }
open() { open() {

View File

@ -306,18 +306,30 @@ class FdoNotificationDaemon {
export const FdoNotificationDaemonSource = GObject.registerClass( export const FdoNotificationDaemonSource = GObject.registerClass(
class FdoNotificationDaemonSource extends MessageTray.Source { class FdoNotificationDaemonSource extends MessageTray.Source {
_init(title, pid, sender, appId) { constructor(title, pid, sender, appId) {
this.pid = pid; const appSys = Shell.AppSystem.get_default();
this.initialTitle = title; let app;
this.app = this._getApp(appId);
this._appIcon = null; app = Shell.WindowTracker.get_default().get_app_from_pid(pid);
if (!app && appId)
app = appSys.lookup_app(`${appId}.desktop`);
if (!app)
app = appSys.lookup_app(`${title}.desktop`);
// Use app name as title if available, instead of whatever is provided // Use app name as title if available, instead of whatever is provided
// through libnotify (usually garbage) // through libnotify (usually garbage)
super._init({ super({
title: this.app?.get_name() ?? title, title: app?.get_name() ?? title,
policy: MessageTray.NotificationPolicy.newForApp(app),
}); });
this.pid = pid;
this.initialTitle = title;
this.app = app;
this._appIcon = null;
if (sender) { if (sender) {
this._nameWatcherId = Gio.DBus.session.watch_name(sender, this._nameWatcherId = Gio.DBus.session.watch_name(sender,
Gio.BusNameWatcherFlags.NONE, Gio.BusNameWatcherFlags.NONE,
@ -328,15 +340,6 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
} }
} }
_createPolicy() {
if (this.app && this.app.get_app_info()) {
let id = this.app.get_id().replace(/\.desktop$/, '');
return new MessageTray.NotificationApplicationPolicy(id);
} else {
return new MessageTray.NotificationGenericPolicy();
}
}
_onNameVanished() { _onNameVanished() {
// Destroy the notification source when its sender is removed from DBus. // Destroy the notification source when its sender is removed from DBus.
// Only do so if this.app is set to avoid removing "notify-send" sources, senders // Only do so if this.app is set to avoid removing "notify-send" sources, senders
@ -361,23 +364,6 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
this.showNotification(notification); this.showNotification(notification);
} }
_getApp(appId) {
const appSys = Shell.AppSystem.get_default();
let app;
app = Shell.WindowTracker.get_default().get_app_from_pid(this.pid);
if (app != null)
return app;
if (appId)
app = appSys.lookup_app(`${appId}.desktop`);
if (!app)
app = appSys.lookup_app(`${this.initialTitle}.desktop`);
return app;
}
open() { open() {
this.openApp(); this.openApp();
this.destroyNonResidentNotifications(); this.destroyNonResidentNotifications();
@ -506,32 +492,29 @@ function InvalidAppError() {}
export const GtkNotificationDaemonAppSource = GObject.registerClass( export const GtkNotificationDaemonAppSource = GObject.registerClass(
class GtkNotificationDaemonAppSource extends MessageTray.Source { class GtkNotificationDaemonAppSource extends MessageTray.Source {
_init(appId) { constructor(appId) {
let objectPath = objectPathFromAppId(appId); const objectPath = objectPathFromAppId(appId);
if (!GLib.Variant.is_object_path(objectPath)) if (!GLib.Variant.is_object_path(objectPath))
throw new InvalidAppError(); throw new InvalidAppError();
let app = Shell.AppSystem.get_default().lookup_app(`${appId}.desktop`); const app = Shell.AppSystem.get_default().lookup_app(`${appId}.desktop`);
if (!app) if (!app)
throw new InvalidAppError(); throw new InvalidAppError();
super({
title: app.get_name(),
icon: app.get_icon(),
policy: new MessageTray.NotificationApplicationPolicy(appId),
});
this._appId = appId; this._appId = appId;
this._app = app; this._app = app;
this._objectPath = objectPath; this._objectPath = objectPath;
super._init({
title: app.get_name(),
icon: app.get_icon(),
});
this._notifications = {}; this._notifications = {};
this._notificationPending = false; this._notificationPending = false;
} }
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy(this._appId);
}
_createApp() { _createApp() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new FdoApplicationProxy(Gio.DBus.session, new FdoApplicationProxy(Gio.DBus.session,

View File

@ -56,15 +56,14 @@ export class WindowAttentionHandler {
const WindowAttentionSource = GObject.registerClass( const WindowAttentionSource = GObject.registerClass(
class WindowAttentionSource extends MessageTray.Source { class WindowAttentionSource extends MessageTray.Source {
_init(app, window) { constructor(app, window) {
this._window = window; super({
this._app = app; title: app.get_name(),
icon: app.get_icon(),
super._init({ policy: MessageTray.NotificationPolicy.newForApp(app),
title: this._app.get_name(),
icon: this._app.get_icon(),
}); });
this._window = window;
this._window.connectObject( this._window.connectObject(
'notify::demands-attention', this._sync.bind(this), 'notify::demands-attention', this._sync.bind(this),
'notify::urgent', this._sync.bind(this), 'notify::urgent', this._sync.bind(this),
@ -78,15 +77,6 @@ class WindowAttentionSource extends MessageTray.Source {
this.destroy(); this.destroy();
} }
_createPolicy() {
if (this._app && this._app.get_app_info()) {
let id = this._app.get_id().replace(/\.desktop$/, '');
return new MessageTray.NotificationApplicationPolicy(id);
} else {
return new MessageTray.NotificationGenericPolicy();
}
}
destroy(params) { destroy(params) {
this._window.disconnectObject(this); this._window.disconnectObject(this);