@@ -15,25 +15,19 @@ public class Gala.HideTracker : Object {
1515
1616 public Meta . Display display { get ; construct; }
1717 public unowned PanelWindow panel { get ; construct; }
18- public Pantheon . Desktop . HideMode hide_mode { get ; set ; }
1918
2019 private static GLib . Settings behavior_settings;
2120
2221 private Clutter . PanAction pan_action;
2322
2423 private bool hovered = false ;
2524
26- private bool overlap = false ;
27- private bool focus_overlap = false ;
28- private bool focus_maximized_overlap = false ;
29- private bool fullscreen_overlap = false ;
30-
31- private Meta . Window current_focus_window;
25+ private uint num_transients = 0 ;
26+ private bool has_transients { get { return num_transients > 0 ; } }
3227
3328 private Barrier ? barrier;
3429
3530 private uint hide_timeout_id = 0 ;
36- private uint update_timeout_id = 0 ;
3731
3832 public HideTracker (Meta .Display display , PanelWindow panel ) {
3933 Object (display: display, panel: panel);
@@ -49,22 +43,6 @@ public class Gala.HideTracker : Object {
4943 // access the panel which was already freed. To prevent that make sure we reset
5044 // the timeouts so that we get freed immediately
5145 reset_hide_timeout ();
52- reset_update_timeout ();
53- });
54-
55- // Can't be local otherwise we get a memory leak :(
56- // See https://gitlab.gnome.org/GNOME/vala/-/issues/1548
57- current_focus_window = display. focus_window;
58- track_focus_window (current_focus_window);
59- display. notify[" focus-window" ]. connect (() = > {
60- untrack_focus_window (current_focus_window);
61- current_focus_window = display. focus_window;
62- track_focus_window (current_focus_window);
63- });
64-
65- display. window_created. connect ((window) = > {
66- schedule_update ();
67- window. unmanaged. connect (schedule_update);
6846 });
6947
7048#if HAS_MUTTER48
@@ -77,11 +55,23 @@ public class Gala.HideTracker : Object {
7755
7856 if (hovered != has_pointer) {
7957 hovered = has_pointer;
80- schedule_update ();
58+ check_trigger_conditions ();
8159 }
8260 });
8361
84- display. get_workspace_manager (). active_workspace_changed. connect (schedule_update);
62+ display. window_created. connect ((new_window) = > {
63+ InternalUtils . wait_for_window_actor (new_window, (new_window_actor) = > {
64+ if (panel. window. is_ancestor_of_transient (new_window_actor. meta_window)) {
65+ num_transients++ ;
66+ check_trigger_conditions ();
67+
68+ new_window_actor. meta_window. unmanaged. connect (() = > {
69+ num_transients = uint . max (num_transients - 1 , 0 );
70+ check_trigger_conditions ();
71+ });
72+ }
73+ });
74+ });
8575
8676 pan_action = new Clutter .PanAction () {
8777 n_touch_points = 1 ,
@@ -100,147 +90,22 @@ public class Gala.HideTracker : Object {
10090
10191 var monitor_manager = display. get_context (). get_backend (). get_monitor_manager ();
10292 monitor_manager. monitors_changed. connect (() = > {
103- setup_barrier (); // Make sure barriers are still on the primary monitor
104- schedule_update ();
93+ setup_barrier (); // Make sure barriers are still on the primary monitor
10594 });
10695
10796 setup_barrier ();
10897 }
10998
110-
111- private void track_focus_window (Meta .Window ? window ) {
112- if (window == null ) {
113- return ;
114- }
115-
116- window. position_changed. connect (schedule_update);
117- window. size_changed. connect (schedule_update);
118- schedule_update ();
119- }
120-
121- private void untrack_focus_window (Meta .Window ? window ) {
122- if (window == null ) {
123- return ;
124- }
125-
126- window. position_changed. disconnect (schedule_update);
127- window. size_changed. disconnect (schedule_update);
128- schedule_update ();
129- }
130-
131- public void schedule_update () {
132- if (update_timeout_id != 0 ) {
133- return ;
134- }
135-
136- update_timeout_id = Timeout . add (UPDATE_TIMEOUT , () = > {
137- update_overlap ();
138- update_timeout_id = 0 ;
139- return Source . REMOVE ;
140- });
141- }
142-
143- private void reset_update_timeout () {
144- if (update_timeout_id != 0 ) {
145- Source . remove (update_timeout_id);
146- update_timeout_id = 0 ;
147- }
148- }
149-
150- public void update_overlap () {
151- overlap = false ;
152- focus_overlap = false ;
153- focus_maximized_overlap = false ;
154- fullscreen_overlap = display. get_monitor_in_fullscreen (panel. window. get_monitor ());
155-
156- unowned var active_workspace = display. get_workspace_manager (). get_active_workspace ();
157-
158- Meta . Window ? normal_mru_window, any_mru_window;
159- normal_mru_window = InternalUtils . get_mru_window (active_workspace, out any_mru_window);
160-
161- foreach (var window in active_workspace. list_windows ()) {
162- if (window == panel. window) {
163- continue ;
164- }
165-
166- if (window. minimized) {
167- continue ;
168- }
169-
170- var type = window. get_window_type ();
171- if (type == DESKTOP || type == DOCK || type == MENU || type == SPLASHSCREEN ) {
172- continue ;
173- }
174-
175- if (! panel. get_custom_window_rect (). overlap (window. get_frame_rect ())) {
176- continue ;
177- }
178-
179- overlap = true ;
180-
181- if (window != normal_mru_window && window != any_mru_window) {
182- continue ;
183- }
184-
185- focus_overlap = true ;
186- focus_maximized_overlap = window. maximized_vertically;
187- }
188-
189- update_hidden ();
190- }
191-
192- private void update_hidden () {
193- switch (hide_mode) {
194- case MAXIMIZED_FOCUS_WINDOW :
195- toggle_display (focus_maximized_overlap);
196- break ;
197-
198- case OVERLAPPING_FOCUS_WINDOW :
199- toggle_display (focus_overlap);
200- break ;
201-
202- case OVERLAPPING_WINDOW :
203- toggle_display (overlap);
204- break ;
205-
206- case ALWAYS :
207- toggle_display (true );
208- break ;
209-
210- case NEVER :
211- toggle_display (fullscreen_overlap);
212- break ;
213- }
214- }
215-
216- private void toggle_display (bool should_hide ) {
217- hovered = panel. window. has_pointer ();
218-
219- // Showing panels in fullscreen is broken in X11
220- if (should_hide && ! hovered && ! panel. window. has_focus () || InternalUtils . get_x11_in_fullscreen (display)) {
221- trigger_hide ();
222- } else {
99+ private void check_trigger_conditions () {
100+ if (hovered || has_transients) {
223101 trigger_show ();
102+ } else {
103+ trigger_hide ();
224104 }
225105 }
226106
227107 private void trigger_hide () {
228- if (hide_timeout_id != 0 ) {
229- return ;
230- }
231-
232- // Don't hide if we have transients, e.g. an open popover, dialog, etc.
233- var has_transients = false ;
234- panel. window. foreach_transient (() = > {
235- has_transients = true ;
236- return false ;
237- });
238-
239- if (has_transients) {
240- reset_hide_timeout ();
241-
242- return ;
243- }
108+ reset_hide_timeout ();
244109
245110 hide_timeout_id = Timeout . add_once (HIDE_DELAY , () = > {
246111 hide ();
@@ -349,9 +214,10 @@ public class Gala.HideTracker : Object {
349214 return ;
350215 }
351216
352- if (hide_mode != NEVER || behavior_settings. get_boolean (" enable-hotcorners-in-fullscreen" )) {
217+ if (! display. get_monitor_in_fullscreen (panel. window. get_monitor ()) ||
218+ behavior_settings. get_boolean (" enable-hotcorners-in-fullscreen" )
219+ ) {
353220 trigger_show ();
354- schedule_update ();
355221 }
356222 }
357223}
0 commit comments