Skip to content

Commit 2c19c41

Browse files
committed
Notifications applet: Do not recreate menu on orientation change.
Disconnect signals on applet close. Cleanup code a little bit
1 parent 949372d commit 2c19c41

File tree

1 file changed

+53
-34
lines changed

1 file changed

+53
-34
lines changed

files/usr/share/cinnamon/applets/[email protected]/applet.js

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const Applet = imports.ui.applet;
2-
const Lang = imports.lang;
32
const Main = imports.ui.main;
43
const Gtk = imports.gi.Gtk;
54
const Gio = imports.gi.Gio;
@@ -11,6 +10,7 @@ const NotificationDestroyedReason = imports.ui.messageTray.NotificationDestroyed
1110
const Settings = imports.ui.settings;
1211
const Gettext = imports.gettext.domain("cinnamon-applets");
1312
const Util = imports.misc.util;
13+
const SignalManager = imports.misc.signalManager;
1414

1515
const PANEL_EDIT_MODE_KEY = "panel-edit-mode";
1616

@@ -33,17 +33,23 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
3333
// Layout
3434
this._orientation = orientation;
3535
this.menuManager = new PopupMenu.PopupMenuManager(this);
36+
this.menu = new Applet.AppletPopupMenu(this, orientation);
37+
this.menuManager.addMenu(this.menu);
3638

3739
// Lists
3840
this.notifications = []; // The list of notifications, in order from oldest to newest.
3941

4042
// Events
41-
Main.messageTray.connect('notify-applet-update', Lang.bind(this, this._notification_added));
42-
this.panelEditModeHandler = global.settings.connect('changed::' + PANEL_EDIT_MODE_KEY, Lang.bind(this, this._on_panel_edit_mode_changed));
43+
this.signals = new SignalManager.SignalManager(null);
44+
this.signals.connect(Main.messageTray, 'notify-applet-update', this._notification_added.bind(this));
45+
this.signals.connect(global.settings, 'changed::' + PANEL_EDIT_MODE_KEY, this._on_panel_edit_mode_changed.bind(this));
46+
this.signals.connect(this.menu, 'menu-animated-closed', this._onMenuClosed.bind(this));
4347

4448
// States
4549
this._blinking = false;
4650
this._blink_toggle = false;
51+
52+
this._display();
4753
}
4854

4955
_setKeybinding() {
@@ -54,20 +60,24 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
5460
on_applet_removed_from_panel () {
5561
Main.keybindingManager.removeXletHotKey(this, "notification-open");
5662
Main.keybindingManager.removeXletHotKey(this, "notification-clear");
57-
global.settings.disconnect(this.panelEditModeHandler);
63+
64+
this.destroy();
5865
}
5966

6067
_openMenu() {
6168
this._update_timestamp();
6269

63-
this._notificationbin.remove_all_children();
6470
this.notifications.forEach(notification => {
6571
global.reparentActor(notification.actor, this._notificationbin);
6672
});
6773

6874
this.menu.toggle();
6975
}
7076

77+
_onMenuClosed() {
78+
this._notificationbin.remove_all_children();
79+
}
80+
7181
_display() {
7282
// Always start the applet empty, void of any notifications.
7383
this.set_applet_icon_symbolic_name("empty-notif");
@@ -76,7 +86,6 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
7686
// Setup the notification container.
7787
this._maincontainer = new St.BoxLayout({name: 'traycontainer', vertical: true});
7888
this._notificationbin = new St.BoxLayout({vertical:true});
79-
this.button_label_box = new St.BoxLayout();
8089

8190
// Setup the tray icon.
8291
this.menu_label = new PopupMenu.PopupMenuItem(stringify(this.notifications.length));
@@ -87,42 +96,50 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
8796
this.clear_separator = new PopupMenu.PopupSeparatorMenuItem();
8897

8998
this.clear_action = new PopupMenu.PopupMenuItem(_("Clear notifications"));
90-
this.clear_action.connect('activate', Lang.bind(this, this._clear_all));
99+
this.clear_action.connect('activate', this._clear_all.bind(this));
91100
this.clear_action.actor.hide();
92101

93-
if (this._orientation == St.Side.BOTTOM) {
94-
this.menu.addMenuItem(this.menu_label);
95-
this.menu.addActor(this._maincontainer);
96-
this.menu.addMenuItem(this.clear_separator);
97-
this.menu.addMenuItem(this.clear_action);
98-
} else {
99-
this.menu.addMenuItem(this.clear_action);
100-
this.menu.addMenuItem(this.clear_separator);
101-
this.menu.addMenuItem(this.menu_label);
102-
this.menu.addActor(this._maincontainer);
103-
}
104-
102+
this.menu.addMenuItem(this.clear_action);
103+
this.menu.addMenuItem(this.clear_separator);
104+
this.menu.addMenuItem(this.menu_label);
105+
this.menu.addActor(this._maincontainer);
106+
105107
this.scrollview = new St.ScrollView({ x_fill: true, y_fill: true, y_align: St.Align.START, style_class: "vfade"});
106108
this._maincontainer.add(this.scrollview);
107109
this.scrollview.add_actor(this._notificationbin);
108110
this.scrollview.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
109111
this.scrollview.set_clip_to_allocation(true);
110112

111113
let vscroll = this.scrollview.get_vscroll_bar();
112-
vscroll.connect('scroll-start', Lang.bind(this, function() {
113-
this.menu.passEvents = true;
114-
}));
115-
vscroll.connect('scroll-stop', Lang.bind(this, function() {
116-
this.menu.passEvents = false;
117-
}));
114+
vscroll.connect('scroll-start', () => this.menu.passEvents = true);
115+
vscroll.connect('scroll-stop', () => this.menu.passEvents = false);
118116

119117
// Alternative tray icons.
120118
this._crit_icon = new St.Icon({icon_name: 'critical-notif', icon_type: St.IconType.SYMBOLIC, reactive: true, track_hover: true, style_class: 'system-status-icon' });
121119
this._alt_crit_icon = new St.Icon({icon_name: 'alt-critical-notif', icon_type: St.IconType.SYMBOLIC, reactive: true, track_hover: true, style_class: 'system-status-icon' });
122120

123121
this._on_panel_edit_mode_changed();
124122

125-
this.menu.addSettingsAction(_("Notification Settings"), 'notifications');
123+
this.settingsMenuItem = this.menu.addSettingsAction(_("Notification Settings"), 'notifications');
124+
}
125+
126+
_arrangeDisplay() {
127+
// Remove menu actors so we can put them back in a different order according to orientation.
128+
this.menu.box.remove_all_children();
129+
130+
if (this._orientation == St.Side.BOTTOM) {
131+
this.menu.addActor(this.menu_label.actor);
132+
this.menu.addActor(this._maincontainer);
133+
this.menu.addActor(this.clear_separator.actor);
134+
this.menu.addActor(this.clear_action.actor);
135+
} else {
136+
this.menu.addActor(this.clear_action.actor);
137+
this.menu.addActor(this.clear_separator.actor);
138+
this.menu.addActor(this.menu_label.actor);
139+
this.menu.addActor(this._maincontainer);
140+
}
141+
142+
this.menu.addActor(this.settingsMenuItem.actor);
126143
}
127144

128145
_notification_added (mtray, notification) { // Notification event handler.
@@ -164,7 +181,7 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
164181

165182
update_list () {
166183
try {
167-
let count = this.notifications.length;
184+
const count = this.notifications.length;
168185
if (count > 0) { // There are notifications.
169186
this.actor.show();
170187
this.clear_action.actor.show();
@@ -272,12 +289,7 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
272289
on_orientation_changed (orientation) {
273290
this._orientation = orientation;
274291

275-
if (this.menu) {
276-
this.menu.destroy();
277-
}
278-
this.menu = new Applet.AppletPopupMenu(this, orientation);
279-
this.menuManager.addMenu(this.menu);
280-
this._display();
292+
this._arrangeDisplay();
281293
}
282294

283295
on_applet_clicked(event) {
@@ -308,7 +320,14 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
308320
this._applet_icon_box.child = this._alt_crit_icon;
309321
}
310322
this._blink_toggle = !this._blink_toggle;
311-
Mainloop.timeout_add_seconds(1, Lang.bind(this, this.critical_blink));
323+
Mainloop.timeout_add_seconds(1, this.critical_blink.bind(this));
324+
}
325+
326+
destroy() {
327+
this.signals.disconnectAllSignals();
328+
this._crit_icon.destroy();
329+
this._alt_crit_icon.destroy();
330+
this.menu.destroy();
312331
}
313332
}
314333

0 commit comments

Comments
 (0)