Skip to content

Commit 2553be9

Browse files
committed
fix(meetingClock): improve resource cleanup and timer management
fix(trayIconItem): streamline menu management and cleanup fix(weatherClock): enhance timer handling and resource deallocation (cherry picked from commit b989b89)
1 parent 840e8ae commit 2553be9

4 files changed

Lines changed: 157 additions & 85 deletions

File tree

src/modules/meetingClock/calendarServerBackend.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ export class CalendarServerBackend {
6565
this._signalId = 0;
6666
}
6767

68-
this._proxy?.run_dispose();
6968
this._proxy = null;
7069
this._eventsById.clear();
7170
}

src/modules/meetingClock/meetingClock.ts

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ export class MeetingClock extends Module {
4949
private _panelWidget: St.BoxLayout | null = null;
5050
private _panelLabel: St.Label | null = null;
5151
private _notificationSource: MessageTray.Source | null = null;
52+
private _notificationSourceDestroyId = 0;
5253
private _activeNotification: MessageTray.Notification | null = null;
54+
private _activeNotificationDestroyId = 0;
5355
private _uiAlive = false;
5456
private _enabled = false;
5557
private _settingsIds: number[] = [];
@@ -123,17 +125,23 @@ export class MeetingClock extends Module {
123125
for (const id of this._settingsIds) this.context.settings.disconnect(id);
124126
this._settingsIds = [];
125127

126-
this._clearTimer('_refreshTimerId');
127-
this._clearTimer('_labelTimerId');
128-
this._clearTimer('_alertTimerId');
129-
this._clearTimer('_panelRevealTimerId');
130-
this._clearTimer('_panelHideTimerId');
128+
this._clearRefreshTimer();
129+
this._clearLabelTimer();
130+
this._clearAlertTimer();
131+
this._clearPanelRevealTimer();
132+
this._clearPanelHideTimer();
131133

132-
this._backend?.stop();
134+
if (this._backend) this._backend.stop();
133135
this._backend = null;
134136
this._activeAlertEventId = null;
135137
this._destroyActiveNotification(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
136-
this._notificationSource?.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
138+
if (this._notificationSource) {
139+
if (this._notificationSourceDestroyId) {
140+
this._notificationSource.disconnect(this._notificationSourceDestroyId);
141+
this._notificationSourceDestroyId = 0;
142+
}
143+
this._notificationSource.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
144+
}
137145
this._notificationSource = null;
138146
this._eventsBySource.clear();
139147
this._events = [];
@@ -142,11 +150,12 @@ export class MeetingClock extends Module {
142150
this._ignoredEventIds.clear();
143151
this._snoozedUntilByEventId.clear();
144152

145-
this._clockPillRegistration?.unregister();
153+
if (this._clockPillRegistration) this._clockPillRegistration.unregister();
146154
this._clockPillRegistration = null;
147-
this._panelWidget?.destroy();
148-
this._panelWidget = null;
155+
if (this._panelLabel) this._panelLabel.destroy();
149156
this._panelLabel = null;
157+
if (this._panelWidget) this._panelWidget.destroy();
158+
this._panelWidget = null;
150159
this._lastPanelEventId = '';
151160
}
152161

@@ -260,7 +269,7 @@ export class MeetingClock extends Module {
260269
private _scheduleAlerts(): void {
261270
if (!this._enabled || !this._uiAlive) return;
262271

263-
this._clearTimer('_alertTimerId');
272+
this._clearAlertTimer();
264273
if (this._activeAlertEventId) return;
265274

266275
const now = this._now();
@@ -287,7 +296,7 @@ export class MeetingClock extends Module {
287296
private _schedulePanelRevealTimer(): void {
288297
if (!this._enabled || !this._uiAlive) return;
289298

290-
this._clearTimer('_panelRevealTimerId');
299+
this._clearPanelRevealTimer();
291300
const intervalSeconds =
292301
Math.max(1, this.context.settings.getInt(PANEL_REVEAL_INTERVAL_MINUTES_KEY)) * 60;
293302
this._panelRevealTimerId = GLib.timeout_add_seconds(
@@ -360,8 +369,11 @@ export class MeetingClock extends Module {
360369
notification.addAction(_('Snooze'), () => this._snoozeEvent(event));
361370
notification.addAction(_('Dismiss'), () => this._dismissEvent(event));
362371
if (event.meetingUrl) notification.addAction(_('Ignore'), () => this._ignoreEvent(event));
363-
notification.connect('destroy', () => {
364-
if (this._activeNotification === notification) this._activeNotification = null;
372+
this._activeNotificationDestroyId = notification.connect('destroy', () => {
373+
if (this._activeNotification === notification) {
374+
this._activeNotification = null;
375+
this._activeNotificationDestroyId = 0;
376+
}
365377
if (this._activeAlertEventId !== event.id) return;
366378

367379
this._alertedEventIds.add(event.id);
@@ -415,7 +427,7 @@ export class MeetingClock extends Module {
415427
const widget = this._panelWidget;
416428
if (!this._enabled || !this._uiAlive || !widget || !this._lastPanelEventId) return;
417429

418-
this._clearTimer('_panelHideTimerId');
430+
this._clearPanelHideTimer();
419431
widget.remove_transition('opacity');
420432
widget.remove_transition('translation-x');
421433
widget.remove_transition('width');
@@ -452,7 +464,7 @@ export class MeetingClock extends Module {
452464
const widget = this._panelWidget;
453465
if (!widget) return;
454466

455-
this._clearTimer('_panelHideTimerId');
467+
this._clearPanelHideTimer();
456468
widget.remove_transition('opacity');
457469
widget.remove_transition('translation-x');
458470
widget.remove_transition('width');
@@ -480,17 +492,34 @@ export class MeetingClock extends Module {
480492
});
481493
}
482494

483-
private _clearTimer(
484-
prop:
485-
| '_refreshTimerId'
486-
| '_labelTimerId'
487-
| '_alertTimerId'
488-
| '_panelRevealTimerId'
489-
| '_panelHideTimerId',
490-
): void {
491-
if (!this[prop]) return;
492-
GLib.source_remove(this[prop]);
493-
this[prop] = 0;
495+
private _clearRefreshTimer(): void {
496+
if (!this._refreshTimerId) return;
497+
GLib.source_remove(this._refreshTimerId);
498+
this._refreshTimerId = 0;
499+
}
500+
501+
private _clearLabelTimer(): void {
502+
if (!this._labelTimerId) return;
503+
GLib.source_remove(this._labelTimerId);
504+
this._labelTimerId = 0;
505+
}
506+
507+
private _clearAlertTimer(): void {
508+
if (!this._alertTimerId) return;
509+
GLib.source_remove(this._alertTimerId);
510+
this._alertTimerId = 0;
511+
}
512+
513+
private _clearPanelRevealTimer(): void {
514+
if (!this._panelRevealTimerId) return;
515+
GLib.source_remove(this._panelRevealTimerId);
516+
this._panelRevealTimerId = 0;
517+
}
518+
519+
private _clearPanelHideTimer(): void {
520+
if (!this._panelHideTimerId) return;
521+
GLib.source_remove(this._panelHideTimerId);
522+
this._panelHideTimerId = 0;
494523
}
495524

496525
private _now(): number {
@@ -512,8 +541,9 @@ export class MeetingClock extends Module {
512541
title: _('Meeting Clock'),
513542
iconName: 'x-office-calendar-symbolic',
514543
});
515-
source.connect('destroy', () => {
544+
this._notificationSourceDestroyId = source.connect('destroy', () => {
516545
if (this._notificationSource === source) this._notificationSource = null;
546+
this._notificationSourceDestroyId = 0;
517547
});
518548
Main.messageTray.add(source);
519549
this._notificationSource = source;
@@ -523,7 +553,11 @@ export class MeetingClock extends Module {
523553
private _destroyActiveNotification(reason: MessageTray.NotificationDestroyedReason): void {
524554
const notification = this._activeNotification;
525555
this._activeNotification = null;
526-
notification?.destroy(reason);
556+
if (this._activeNotificationDestroyId && notification) {
557+
notification.disconnect(this._activeNotificationDestroyId);
558+
}
559+
this._activeNotificationDestroyId = 0;
560+
if (notification) notification.destroy(reason);
527561
}
528562

529563
private _clearAlertState(eventIds: ReadonlySet<string | undefined>): void {

src/modules/trayIcons/trayIconItem.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const LOG_PREFIX = 'AuroraTray';
2020

2121
// Module-level tooltip shared by all TrayIconItems to avoid allocating one per icon.
2222
let _tooltipLabel: St.Label | null = null;
23+
const _menuManagers = new WeakMap<PopupMenu.PopupMenu, PopupMenu.PopupMenuManager>();
2324

2425
function _showTooltip(anchor: Clutter.Actor, text: string): void {
2526
if (!_tooltipLabel) {
@@ -60,10 +61,8 @@ export class TrayIconItem extends St.Button {
6061
declare private _badge: St.Widget;
6162
declare private _iconSize: number;
6263
declare private _menu: PopupMenu.PopupMenu | null;
63-
declare private _menuManager: PopupMenu.PopupMenuManager | null;
6464
declare private _dbusMenuClient: DBusMenuClient | null;
6565
declare private _localMenu: PopupMenu.PopupMenu | null;
66-
declare private _localMenuManager: PopupMenu.PopupMenuManager | null;
6766

6867
override _init(item: TrayItem, iconSize: number): void {
6968
super._init({
@@ -76,17 +75,14 @@ export class TrayIconItem extends St.Button {
7675
this._trayItem = item;
7776
this._iconSize = iconSize;
7877
this._menu = null;
79-
this._menuManager = null;
8078
this._dbusMenuClient = null;
8179
this._localMenu = null;
82-
this._localMenuManager = null;
8380

8481
if (item.menuBusName && item.menuObjectPath) {
8582
this._dbusMenuClient = new DBusMenuClient(item.menuBusName, item.menuObjectPath);
8683
this._menu = new PopupMenu.PopupMenu(this, 0.5, St.Side.TOP);
8784
this._menu.actor.add_style_class_name('aurora-tray-menu');
88-
this._menuManager = new PopupMenu.PopupMenuManager(this);
89-
this._menuManager.addMenu(this._menu);
85+
this._addManagedMenu(this._menu);
9086

9187
Main.uiGroup.add_child(this._menu.actor);
9288
this._menu.actor.hide();
@@ -95,8 +91,7 @@ export class TrayIconItem extends St.Button {
9591
if (item.menuItems && item.menuItems.length > 0) {
9692
this._localMenu = new PopupMenu.PopupMenu(this, 0.5, St.Side.TOP);
9793
this._localMenu.actor.add_style_class_name('aurora-tray-menu');
98-
this._localMenuManager = new PopupMenu.PopupMenuManager(this);
99-
this._localMenuManager.addMenu(this._localMenu);
94+
this._addManagedMenu(this._localMenu);
10095
Main.uiGroup.add_child(this._localMenu.actor);
10196
this._localMenu.actor.hide();
10297

@@ -180,6 +175,20 @@ export class TrayIconItem extends St.Button {
180175
});
181176
}
182177

178+
private _addManagedMenu(menu: PopupMenu.PopupMenu): void {
179+
const manager = new PopupMenu.PopupMenuManager(this);
180+
manager.addMenu(menu);
181+
_menuManagers.set(menu, manager);
182+
}
183+
184+
private _removeManagedMenu(menu: PopupMenu.PopupMenu): void {
185+
const manager = _menuManagers.get(menu);
186+
if (!manager) return;
187+
188+
manager.removeMenu(menu);
189+
_menuManagers.delete(menu);
190+
}
191+
183192
private async _showDbusMenu(): Promise<void> {
184193
if (!this._dbusMenuClient || !this._menu) return;
185194

@@ -264,19 +273,16 @@ export class TrayIconItem extends St.Button {
264273

265274
override destroy(): void {
266275
_hideTooltip();
267-
this._dbusMenuClient?.destroy();
268-
if (this._menu && this._menuManager) {
269-
this._menuManager.removeMenu(this._menu);
270-
}
271-
this._menu?.destroy();
276+
if (this._dbusMenuClient) this._dbusMenuClient.destroy();
277+
this._dbusMenuClient = null;
278+
if (this._menu) this._removeManagedMenu(this._menu);
279+
if (this._menu) this._menu.destroy();
272280
this._menu = null;
273-
this._menuManager = null;
274-
if (this._localMenu && this._localMenuManager) {
275-
this._localMenuManager.removeMenu(this._localMenu);
276-
}
277-
this._localMenu?.destroy();
281+
if (this._localMenu) this._removeManagedMenu(this._localMenu);
282+
if (this._localMenu) this._localMenu.destroy();
278283
this._localMenu = null;
279-
this._localMenuManager = null;
284+
this._badge.destroy();
285+
this._iconWidget.destroy();
280286
this._trayItem.destroy();
281287
super.destroy();
282288
}

0 commit comments

Comments
 (0)