66 */
77
88public class Gala.HideTracker : Object {
9- private const uint UPDATE_TIMEOUT = 200 ;
9+ private const int BARRIER_OFFSET = 50 ; // Allow hot corner trigger
10+ private const int UPDATE_TIMEOUT = 200 ;
11+ private const int HIDE_DELAY = 500 ;
1012
1113 public signal void hide ();
1214 public signal void show ();
1315
1416 public Meta . Display display { get ; construct; }
1517 public unowned PanelWindow panel { get ; construct; }
16- public Pantheon . Desktop . HideMode hide_mode { get ; set ; default = NEVER ; }
18+
19+ private Pantheon . Desktop . HideMode _hide_mode = NEVER ;
20+ public Pantheon . Desktop . HideMode hide_mode {
21+ get {
22+ return _hide_mode;
23+ }
24+ set {
25+ _hide_mode = value ;
26+
27+ setup_barrier ();
28+ }
29+ }
1730
1831 private Clutter . PanAction pan_action;
1932
@@ -25,12 +38,21 @@ public class Gala.HideTracker : Object {
2538
2639 private Meta . Window current_focus_window;
2740
41+ private Barrier ? barrier;
42+
43+ private uint hide_timeout_id = 0 ;
2844 private uint update_timeout_id = 0 ;
2945
3046 public HideTracker (Meta .Display display , PanelWindow panel ) {
3147 Object (display: display, panel: panel);
3248 }
3349
50+ ~HideTracker () {
51+ if (hide_timeout_id != 0 ) {
52+ Source . remove (hide_timeout_id);
53+ }
54+ }
55+
3456 construct {
3557 // Can't be local otherwise we get a memory leak :(
3658 // See https://gitlab.gnome.org/GNOME/vala/-/issues/1548
@@ -163,10 +185,6 @@ public class Gala.HideTracker : Object {
163185
164186 private void update_hidden () {
165187 switch (hide_mode) {
166- case NEVER :
167- toggle_display (false );
168- break ;
169-
170188 case MAXIMIZED_FOCUS_WINDOW :
171189 toggle_display (focus_maximized_overlap);
172190 break ;
@@ -182,6 +200,10 @@ public class Gala.HideTracker : Object {
182200 case ALWAYS :
183201 toggle_display (true );
184202 break ;
203+
204+ default:
205+ warning (" HideTracker: unsupported hide mode." );
206+ break ;
185207 }
186208 }
187209
@@ -196,23 +218,44 @@ public class Gala.HideTracker : Object {
196218#endif
197219
198220 if (should_hide && ! hovered && ! panel. window. has_focus ()) {
199- // Don't hide if we have transients, e.g. an open popover, dialog, etc.
200- var has_transients = false ;
201- panel. window. foreach_transient (() = > {
202- has_transients = true ;
203- return false ;
204- });
205-
206- if (has_transients) {
207- return ;
208- }
221+ trigger_hide ();
222+ } else {
223+ trigger_show ();
224+ }
225+ }
226+
227+ private void trigger_hide () {
228+ // Don't hide if we have transients, e.g. an open popover, dialog, etc.
229+ var has_transients = false ;
230+ panel. window. foreach_transient (() = > {
231+ has_transients = true ;
232+ return false ;
233+ });
234+
235+ if (has_transients) {
236+ reset_hide_timeout ();
237+
238+ return ;
239+ }
209240
241+ hide_timeout_id = Timeout . add_once (HIDE_DELAY , () = > {
210242 hide ();
211- } else {
212- show ();
243+ hide_timeout_id = 0 ;
244+ });
245+ }
246+
247+ private void reset_hide_timeout () {
248+ if (hide_timeout_id != 0 ) {
249+ Source . remove (hide_timeout_id);
250+ hide_timeout_id = 0 ;
213251 }
214252 }
215253
254+ private void trigger_show () {
255+ reset_hide_timeout ();
256+ show ();
257+ }
258+
216259 private bool check_valid_gesture () {
217260 if (panel. anchor != BOTTOM ) {
218261 debug (" Swipe to reveal is currently only supported for bottom anchors" );
@@ -236,9 +279,71 @@ public class Gala.HideTracker : Object {
236279
237280 if (delta_y < 0 ) { // Only allow swipes upwards
238281 panel. window. focus (pan_action. get_last_event (0 ). get_time ());
239- show ();
282+ trigger_show ();
240283 }
241284
242285 return false ;
243286 }
287+
288+ private void setup_barrier () {
289+ var monitor_geom = display. get_monitor_geometry (display. get_primary_monitor ());
290+ var scale = display. get_monitor_scale (display. get_primary_monitor ());
291+ var offset = InternalUtils . scale_to_int (BARRIER_OFFSET , scale);
292+
293+ switch (panel. anchor) {
294+ case TOP :
295+ setup_barrier_top (monitor_geom, offset);
296+ break ;
297+
298+ case BOTTOM :
299+ setup_barrier_bottom (monitor_geom, offset);
300+ break ;
301+
302+ default:
303+ warning (" Barrier side not supported yet" );
304+ break ;
305+ }
306+ }
307+
308+ #if HAS_MUTTER45
309+ private void setup_barrier_top (Mtk .Rectangle monitor_geom , int offset ) {
310+ #else
311+ private void setup_barrier_top (Meta . Rectangle monitor_geom, int offset) {
312+ #endif
313+ barrier = new Barrier (
314+ display. get_context (). get_backend (),
315+ monitor_geom. x + offset,
316+ monitor_geom. y,
317+ monitor_geom. x + monitor_geom. width - offset,
318+ monitor_geom. y,
319+ POSITIVE_Y ,
320+ 0 ,
321+ 0 ,
322+ int . MAX ,
323+ int . MAX
324+ );
325+
326+ barrier. trigger. connect (trigger_show);
327+ }
328+
329+ #if HAS_MUTTER45
330+ private void setup_barrier_bottom (Mtk . Rectangle monitor_geom, int offset) {
331+ #else
332+ private void setup_barrier_bottom (Meta . Rectangle monitor_geom, int offset) {
333+ #endif
334+ barrier = new Barrier (
335+ display. get_context (). get_backend (),
336+ monitor_geom. x + offset,
337+ monitor_geom. y + monitor_geom. height,
338+ monitor_geom. x + monitor_geom. width - offset,
339+ monitor_geom. y + monitor_geom. height,
340+ NEGATIVE_Y ,
341+ 0 ,
342+ 0 ,
343+ int . MAX ,
344+ int . MAX
345+ );
346+
347+ barrier. trigger. connect (trigger_show);
348+ }
244349}
0 commit comments