@@ -28,8 +28,9 @@ public class Gala.NotificationStack : Object {
2828
2929 private const int WIDTH = 300 ;
3030
31- private int stack_y;
32- private int stack_width;
31+ private int offset_stack_y;
32+
33+ private Mtk . Rectangle notification_area = { 0 , 0 , 0 , 0 };
3334
3435 public Meta . Display display { get ; construct; }
3536
@@ -46,6 +47,13 @@ public class Gala.NotificationStack : Object {
4647 monitor_manager. monitors_changed_internal. connect (update_stack_allocation);
4748 display. workareas_changed. connect (update_stack_allocation);
4849 update_stack_allocation ();
50+
51+ ShellClientsManager . get_instance (). positioned_window_created. connect ((window) = > {
52+ window. size_changed. connect (update_offset_y);
53+ window. position_changed. connect (update_offset_y);
54+ window. unmanaged. connect (update_offset_y);
55+ update_offset_y ();
56+ });
4957 }
5058
5159 public void show_notification (Meta .WindowActor notification , bool animate )
@@ -103,7 +111,7 @@ public class Gala.NotificationStack : Object {
103111 notification_x_pos = 0 ;
104112 }
105113
106- move_window (notification, notification_x_pos, stack_y + TOP_OFFSET + InternalUtils . scale_to_int (ADDITIONAL_MARGIN , scale));
114+ move_window (notification, notification_x_pos, offset_stack_y + TOP_OFFSET + InternalUtils . scale_to_int (ADDITIONAL_MARGIN , scale));
107115 notifications. insert (0 , notification);
108116 }
109117
@@ -112,13 +120,15 @@ public class Gala.NotificationStack : Object {
112120 var area = display. get_workspace_manager (). get_active_workspace (). get_work_area_for_monitor (primary);
113121
114122 var scale = display. get_monitor_scale (primary);
115- stack_width = InternalUtils . scale_to_int (WIDTH + MARGIN , scale);
123+ var stack_width = InternalUtils . scale_to_int (WIDTH + MARGIN , scale);
116124
117- stack_y = area. y;
125+ notification_area. x = area. x + area. width - stack_width;
126+ notification_area. y = area. y;
127+ notification_area. width = stack_width;
118128 }
119129
120130 private void update_positions (bool animate , float scale , float add_y = 0 .0f ) {
121- var y = stack_y + TOP_OFFSET + add_y + InternalUtils . scale_to_int (ADDITIONAL_MARGIN , scale);
131+ var y = offset_stack_y + TOP_OFFSET + add_y + InternalUtils . scale_to_int (ADDITIONAL_MARGIN , scale);
122132 var i = notifications. size;
123133 var delay_step = i > 0 ? 150 / i : 0 ;
124134 var iterator = 0 ;
@@ -158,6 +168,8 @@ public class Gala.NotificationStack : Object {
158168
159169 y + = window. get_frame_rect (). height;
160170 }
171+
172+ notification_area. height = (int ) y - notification_area. y;
161173 }
162174
163175 public void destroy_notification (Meta .WindowActor notification , bool animate ) {
@@ -167,11 +179,11 @@ public class Gala.NotificationStack : Object {
167179 notification. set_easing_mode (Clutter . AnimationMode . EASE_IN_QUAD );
168180 notification. opacity = 0 ;
169181
170- notification. x + = stack_width ;
182+ notification. x + = notification_area . width ;
171183 notification. restore_easing_state ();
172184 } else {
173185 notification. opacity = 0 ;
174- notification. x + = stack_width ;
186+ notification. x + = notification_area . width ;
175187 }
176188
177189 var primary = display. get_primary_monitor ();
@@ -181,6 +193,36 @@ public class Gala.NotificationStack : Object {
181193 update_positions (animate, scale);
182194 }
183195
196+ private void update_offset_y () {
197+ int max_y = notification_area. y;
198+ foreach (var window in display. list_all_windows ()) {
199+ if (! ShellClientsManager . get_instance (). is_positioned_window (window)) {
200+ continue ;
201+ }
202+
203+ if (! window. get_frame_rect (). overlap (notification_area)) {
204+ continue ;
205+ }
206+
207+ // Ignore windows that are too big to fit even a single notification on screen
208+ // Conveniently this will make us ignore the fullscreen invisible wingpanel window
209+ var primary = display. get_primary_monitor ();
210+ var area = display. get_workspace_manager (). get_active_workspace (). get_work_area_for_monitor (primary);
211+ if (window. get_frame_rect (). height > area. height - notification_area. height / notifications. size) {
212+ continue ;
213+ }
214+
215+ max_y = (int ) Math . fmax (max_y, window. get_frame_rect (). y + window. get_frame_rect (). height);
216+ }
217+
218+ if (max_y != offset_stack_y) {
219+ offset_stack_y = max_y;
220+
221+ var scale = display. get_monitor_scale (display. get_primary_monitor ());
222+ update_positions (true , scale);
223+ }
224+ }
225+
184226 /**
185227 * This function takes care of properly updating both the actor
186228 * position and the actual window position.
0 commit comments