Skip to content

Commit

Permalink
Add panel hide delay (#2103)
Browse files Browse the repository at this point in the history
Co-authored-by: Stanisław <[email protected]>
  • Loading branch information
lenemter and stsdc authored Nov 11, 2024
1 parent 60fd6ca commit 98f8caf
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 96 deletions.
143 changes: 124 additions & 19 deletions src/ShellClients/HideTracker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,27 @@
*/

public class Gala.HideTracker : Object {
private const uint UPDATE_TIMEOUT = 200;
private const int BARRIER_OFFSET = 50; // Allow hot corner trigger
private const int UPDATE_TIMEOUT = 200;
private const int HIDE_DELAY = 500;

public signal void hide ();
public signal void show ();

public Meta.Display display { get; construct; }
public unowned PanelWindow panel { get; construct; }
public Pantheon.Desktop.HideMode hide_mode { get; set; default = NEVER; }

private Pantheon.Desktop.HideMode _hide_mode = NEVER;
public Pantheon.Desktop.HideMode hide_mode {
get {
return _hide_mode;
}
set {
_hide_mode = value;

setup_barrier ();
}
}

private Clutter.PanAction pan_action;

Expand All @@ -25,12 +38,21 @@ public class Gala.HideTracker : Object {

private Meta.Window current_focus_window;

private Barrier? barrier;

private uint hide_timeout_id = 0;
private uint update_timeout_id = 0;

public HideTracker (Meta.Display display, PanelWindow panel) {
Object (display: display, panel: panel);
}

~HideTracker () {
if (hide_timeout_id != 0) {
Source.remove (hide_timeout_id);
}
}

construct {
// Can't be local otherwise we get a memory leak :(
// See https://gitlab.gnome.org/GNOME/vala/-/issues/1548
Expand Down Expand Up @@ -163,10 +185,6 @@ public class Gala.HideTracker : Object {

private void update_hidden () {
switch (hide_mode) {
case NEVER:
toggle_display (false);
break;

case MAXIMIZED_FOCUS_WINDOW:
toggle_display (focus_maximized_overlap);
break;
Expand All @@ -182,6 +200,10 @@ public class Gala.HideTracker : Object {
case ALWAYS:
toggle_display (true);
break;

default:
warning ("HideTracker: unsupported hide mode.");
break;
}
}

Expand All @@ -196,23 +218,44 @@ public class Gala.HideTracker : Object {
#endif

if (should_hide && !hovered && !panel.window.has_focus ()) {
// Don't hide if we have transients, e.g. an open popover, dialog, etc.
var has_transients = false;
panel.window.foreach_transient (() => {
has_transients = true;
return false;
});

if (has_transients) {
return;
}
trigger_hide ();
} else {
trigger_show ();
}
}

private void trigger_hide () {
// Don't hide if we have transients, e.g. an open popover, dialog, etc.
var has_transients = false;
panel.window.foreach_transient (() => {
has_transients = true;
return false;
});

if (has_transients) {
reset_hide_timeout ();

return;
}

hide_timeout_id = Timeout.add_once (HIDE_DELAY, () => {
hide ();
} else {
show ();
hide_timeout_id = 0;
});
}

private void reset_hide_timeout () {
if (hide_timeout_id != 0) {
Source.remove (hide_timeout_id);
hide_timeout_id = 0;
}
}

private void trigger_show () {
reset_hide_timeout ();
show ();
}

private bool check_valid_gesture () {
if (panel.anchor != BOTTOM) {
debug ("Swipe to reveal is currently only supported for bottom anchors");
Expand All @@ -236,9 +279,71 @@ public class Gala.HideTracker : Object {

if (delta_y < 0) { // Only allow swipes upwards
panel.window.focus (pan_action.get_last_event (0).get_time ());
show ();
trigger_show ();
}

return false;
}

private void setup_barrier () {
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
var scale = display.get_monitor_scale (display.get_primary_monitor ());
var offset = InternalUtils.scale_to_int (BARRIER_OFFSET, scale);

switch (panel.anchor) {
case TOP:
setup_barrier_top (monitor_geom, offset);
break;

case BOTTOM:
setup_barrier_bottom (monitor_geom, offset);
break;

default:
warning ("Barrier side not supported yet");
break;
}
}

#if HAS_MUTTER45
private void setup_barrier_top (Mtk.Rectangle monitor_geom, int offset) {
#else
private void setup_barrier_top (Meta.Rectangle monitor_geom, int offset) {
#endif
barrier = new Barrier (
display.get_context ().get_backend (),
monitor_geom.x + offset,
monitor_geom.y,
monitor_geom.x + monitor_geom.width - offset,
monitor_geom.y,
POSITIVE_Y,
0,
0,
int.MAX,
int.MAX
);

barrier.trigger.connect (trigger_show);
}

#if HAS_MUTTER45
private void setup_barrier_bottom (Mtk.Rectangle monitor_geom, int offset) {
#else
private void setup_barrier_bottom (Meta.Rectangle monitor_geom, int offset) {
#endif
barrier = new Barrier (
display.get_context ().get_backend (),
monitor_geom.x + offset,
monitor_geom.y + monitor_geom.height,
monitor_geom.x + monitor_geom.width - offset,
monitor_geom.y + monitor_geom.height,
NEGATIVE_Y,
0,
0,
int.MAX,
int.MAX
);

barrier.trigger.connect (trigger_show);
}
}
2 changes: 1 addition & 1 deletion src/ShellClients/PanelClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public class Gala.PanelClone : Object {
clone.restore_easing_state ();
}

public void show () {
private void show () {
if (!panel_hidden) {
return;
}
Expand Down
76 changes: 0 additions & 76 deletions src/ShellClients/PanelWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
*/

public class Gala.PanelWindow : Object {
private const int BARRIER_OFFSET = 50; // Allow hot corner trigger

private static HashTable<Meta.Window, Meta.Strut?> window_struts = new HashTable<Meta.Window, Meta.Strut?> (null, null);

public WindowManager wm { get; construct; }
Expand All @@ -17,8 +15,6 @@ public class Gala.PanelWindow : Object {

public Meta.Side anchor;

private Barrier? barrier;

private PanelClone clone;

private uint idle_move_id = 0;
Expand All @@ -42,8 +38,6 @@ public class Gala.PanelWindow : Object {
Source.remove (idle_move_id);
}

destroy_barrier ();

if (window_struts.remove (window)) {
update_struts ();
}
Expand Down Expand Up @@ -154,13 +148,10 @@ public class Gala.PanelWindow : Object {
public void set_hide_mode (Pantheon.Desktop.HideMode hide_mode) {
clone.hide_mode = hide_mode;

destroy_barrier ();

if (hide_mode == NEVER) {
make_exclusive ();
} else {
unmake_exclusive ();
setup_barrier ();
}
}

Expand Down Expand Up @@ -203,71 +194,4 @@ public class Gala.PanelWindow : Object {
update_struts ();
}
}

private void destroy_barrier () {
barrier = null;
}

private void setup_barrier () {
var display = wm.get_display ();
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
var scale = display.get_monitor_scale (display.get_primary_monitor ());
var offset = InternalUtils.scale_to_int (BARRIER_OFFSET, scale);

switch (anchor) {
case TOP:
setup_barrier_top (monitor_geom, offset);
break;

case BOTTOM:
setup_barrier_bottom (monitor_geom, offset);
break;

default:
warning ("Barrier side not supported yet");
break;
}
}

#if HAS_MUTTER45
private void setup_barrier_top (Mtk.Rectangle monitor_geom, int offset) {
#else
private void setup_barrier_top (Meta.Rectangle monitor_geom, int offset) {
#endif
barrier = new Barrier (
wm.get_display ().get_context ().get_backend (),
monitor_geom.x + offset,
monitor_geom.y,
monitor_geom.x + monitor_geom.width - offset,
monitor_geom.y,
POSITIVE_Y,
0,
0,
int.MAX,
int.MAX
);

barrier.trigger.connect (clone.show);
}

#if HAS_MUTTER45
private void setup_barrier_bottom (Mtk.Rectangle monitor_geom, int offset) {
#else
private void setup_barrier_bottom (Meta.Rectangle monitor_geom, int offset) {
#endif
barrier = new Barrier (
wm.get_display ().get_context ().get_backend (),
monitor_geom.x + offset,
monitor_geom.y + monitor_geom.height,
monitor_geom.x + monitor_geom.width - offset,
monitor_geom.y + monitor_geom.height,
NEGATIVE_Y,
0,
0,
int.MAX,
int.MAX
);

barrier.trigger.connect (clone.show);
}
}

0 comments on commit 98f8caf

Please sign in to comment.