11const Applet = imports . ui . applet ;
2- const Lang = imports . lang ;
32const Main = imports . ui . main ;
43const Gtk = imports . gi . Gtk ;
54const Gio = imports . gi . Gio ;
@@ -12,6 +11,7 @@ const NotificationDestroyedReason = imports.ui.messageTray.NotificationDestroyed
1211const Settings = imports . ui . settings ;
1312const Gettext = imports . gettext . domain ( "cinnamon-applets" ) ;
1413const Util = imports . misc . util ;
14+ const SignalManager = imports . misc . signalManager ;
1515
1616const PANEL_EDIT_MODE_KEY = "panel-edit-mode" ;
1717
@@ -34,17 +34,23 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
3434 // Layout
3535 this . _orientation = orientation ;
3636 this . menuManager = new PopupMenu . PopupMenuManager ( this ) ;
37+ this . menu = new Applet . AppletPopupMenu ( this , orientation ) ;
38+ this . menuManager . addMenu ( this . menu ) ;
3739
3840 // Lists
3941 this . notifications = [ ] ; // The list of notifications, in order from oldest to newest.
4042
4143 // Events
42- Main . messageTray . connect ( 'notify-applet-update' , Lang . bind ( this , this . _notification_added ) ) ;
43- this . panelEditModeHandler = global . settings . connect ( 'changed::' + PANEL_EDIT_MODE_KEY , Lang . bind ( this , this . _on_panel_edit_mode_changed ) ) ;
44+ this . signals = new SignalManager . SignalManager ( null ) ;
45+ this . signals . connect ( Main . messageTray , 'notify-applet-update' , this . _notification_added . bind ( this ) ) ;
46+ this . signals . connect ( global . settings , 'changed::' + PANEL_EDIT_MODE_KEY , this . _on_panel_edit_mode_changed . bind ( this ) ) ;
47+ this . signals . connect ( this . menu , 'menu-animated-closed' , this . _onMenuClosed . bind ( this ) ) ;
4448
4549 // States
4650 this . _blinking = false ;
4751 this . _blink_toggle = false ;
52+
53+ this . _display ( ) ;
4854 }
4955
5056 _setKeybinding ( ) {
@@ -55,19 +61,29 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
5561 on_applet_removed_from_panel ( ) {
5662 Main . keybindingManager . removeXletHotKey ( this , "notification-open" ) ;
5763 Main . keybindingManager . removeXletHotKey ( this , "notification-clear" ) ;
58- global . settings . disconnect ( this . panelEditModeHandler ) ;
5964
6065 MessageTray . extensionsHandlingNotifications -- ;
6166 if ( MessageTray . extensionsHandlingNotifications === 0 ) {
6267 this . _clear_all ( ) ;
6368 }
69+
70+ this . destroy ( ) ;
6471 }
6572
6673 _openMenu ( ) {
6774 this . _update_timestamp ( ) ;
75+
76+ this . notifications . forEach ( notification => {
77+ global . reparentActor ( notification . actor , this . _notificationbin ) ;
78+ } ) ;
79+
6880 this . menu . toggle ( ) ;
6981 }
7082
83+ _onMenuClosed ( ) {
84+ this . _notificationbin . remove_all_children ( ) ;
85+ }
86+
7187 _display ( ) {
7288 // Always start the applet empty, void of any notifications.
7389 this . set_applet_icon_symbolic_name ( "empty-notif" ) ;
@@ -76,7 +92,6 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
7692 // Setup the notification container.
7793 this . _maincontainer = new St . BoxLayout ( { name : 'traycontainer' , vertical : true } ) ;
7894 this . _notificationbin = new St . BoxLayout ( { vertical :true } ) ;
79- this . button_label_box = new St . BoxLayout ( ) ;
8095
8196 // Setup the tray icon.
8297 this . menu_label = new PopupMenu . PopupMenuItem ( stringify ( this . notifications . length ) ) ;
@@ -87,42 +102,50 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
87102 this . clear_separator = new PopupMenu . PopupSeparatorMenuItem ( ) ;
88103
89104 this . clear_action = new PopupMenu . PopupMenuItem ( _ ( "Clear notifications" ) ) ;
90- this . clear_action . connect ( 'activate' , Lang . bind ( this , this . _clear_all ) ) ;
105+ this . clear_action . connect ( 'activate' , this . _clear_all . bind ( this ) ) ;
91106 this . clear_action . actor . hide ( ) ;
92107
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-
108+ this . menu . addMenuItem ( this . clear_action ) ;
109+ this . menu . addMenuItem ( this . clear_separator ) ;
110+ this . menu . addMenuItem ( this . menu_label ) ;
111+ this . menu . addActor ( this . _maincontainer ) ;
112+
105113 this . scrollview = new St . ScrollView ( { x_fill : true , y_fill : true , y_align : St . Align . START , style_class : "vfade" } ) ;
106114 this . _maincontainer . add ( this . scrollview ) ;
107115 this . scrollview . add_actor ( this . _notificationbin ) ;
108116 this . scrollview . set_policy ( St . PolicyType . NEVER , St . PolicyType . AUTOMATIC ) ;
109117 this . scrollview . set_clip_to_allocation ( true ) ;
110118
111119 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- } ) ) ;
120+ vscroll . connect ( 'scroll-start' , ( ) => this . menu . passEvents = true ) ;
121+ vscroll . connect ( 'scroll-stop' , ( ) => this . menu . passEvents = false ) ;
118122
119123 // Alternative tray icons.
120124 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' } ) ;
121125 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' } ) ;
122126
123127 this . _on_panel_edit_mode_changed ( ) ;
124128
125- this . menu . addSettingsAction ( _ ( "Notification Settings" ) , 'notifications' ) ;
129+ this . settingsMenuItem = this . menu . addSettingsAction ( _ ( "Notification Settings" ) , 'notifications' ) ;
130+ }
131+
132+ _arrangeDisplay ( ) {
133+ // Remove menu actors so we can put them back in a different order according to orientation.
134+ this . menu . box . remove_all_children ( ) ;
135+
136+ if ( this . _orientation == St . Side . BOTTOM ) {
137+ this . menu . addActor ( this . menu_label . actor ) ;
138+ this . menu . addActor ( this . _maincontainer ) ;
139+ this . menu . addActor ( this . clear_separator . actor ) ;
140+ this . menu . addActor ( this . clear_action . actor ) ;
141+ } else {
142+ this . menu . addActor ( this . clear_action . actor ) ;
143+ this . menu . addActor ( this . clear_separator . actor ) ;
144+ this . menu . addActor ( this . menu_label . actor ) ;
145+ this . menu . addActor ( this . _maincontainer ) ;
146+ }
147+
148+ this . menu . addActor ( this . settingsMenuItem . actor ) ;
126149 }
127150
128151 _notification_added ( mtray , notification ) { // Notification event handler.
@@ -138,8 +161,6 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
138161 if ( notification . _destroyed ) {
139162 this . notifications . splice ( existing_index , 1 ) ;
140163 } else {
141- notification . _inNotificationBin = true ;
142- global . reparentActor ( notification . actor , this . _notificationbin ) ;
143164 notification . _timeLabel . show ( ) ;
144165 }
145166 this . update_list ( ) ;
@@ -148,11 +169,8 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
148169 return ;
149170 }
150171 // Add notification to list.
151- notification . _inNotificationBin = true ;
152172 this . notifications . push ( notification ) ;
153- // Steal the notification panel.
154- this . _notificationbin . add ( notification . actor ) ;
155- notification . actor . _parent_container = this . _notificationbin ;
173+
156174 notification . actor . add_style_class_name ( 'notification-applet-padding' ) ;
157175 // Register for destruction.
158176 notification . connect ( 'scrolling-changed' , ( notif , scrolling ) => { this . menu . passEvents = scrolling } ) ;
@@ -169,7 +187,7 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
169187
170188 update_list ( ) {
171189 try {
172- let count = this . notifications . length ;
190+ const count = this . notifications . length ;
173191 if ( count > 0 ) { // There are notifications.
174192 this . actor . show ( ) ;
175193 this . clear_action . actor . show ( ) ;
@@ -278,12 +296,7 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
278296 on_orientation_changed ( orientation ) {
279297 this . _orientation = orientation ;
280298
281- if ( this . menu ) {
282- this . menu . destroy ( ) ;
283- }
284- this . menu = new Applet . AppletPopupMenu ( this , orientation ) ;
285- this . menuManager . addMenu ( this . menu ) ;
286- this . _display ( ) ;
299+ this . _arrangeDisplay ( ) ;
287300 }
288301
289302 on_applet_clicked ( event ) {
@@ -314,7 +327,14 @@ class CinnamonNotificationsApplet extends Applet.TextIconApplet {
314327 this . _applet_icon_box . child = this . _alt_crit_icon ;
315328 }
316329 this . _blink_toggle = ! this . _blink_toggle ;
317- Mainloop . timeout_add_seconds ( 1 , Lang . bind ( this , this . critical_blink ) ) ;
330+ Mainloop . timeout_add_seconds ( 1 , this . critical_blink . bind ( this ) ) ;
331+ }
332+
333+ destroy ( ) {
334+ this . signals . disconnectAllSignals ( ) ;
335+ this . _crit_icon . destroy ( ) ;
336+ this . _alt_crit_icon . destroy ( ) ;
337+ this . menu . destroy ( ) ;
318338 }
319339}
320340
0 commit comments