Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gala.Barrier #1855

Merged
merged 4 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/HotCorners/Barrier.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*/

/**
* A pointer barrier supporting pressured activation.
*/
public class Gala.Barrier : Meta.Barrier {
public signal void trigger ();

public bool triggered { get; set; default = false; }

public int trigger_pressure_threshold { get; construct; }
public int release_pressure_threshold { get; construct; }
public int retrigger_pressure_threshold { get; construct; }
public int retrigger_delay { get; construct; }

private uint32 triggered_time;
private double pressure;

/**
* @param trigger_pressure_threshold The amount of pixels to travel additionally for
* the barrier to trigger. Set to 0 to immediately activate.
* @param retrigger_pressure_threshold The amount of pixels to travel additionally for
* the barrier to trigger again. Set to int.MAX to disallow retrigger.
*/
public Barrier (
Meta.Display display,
int x1,
int y1,
int x2,
int y2,
Meta.BarrierDirection directions,
int trigger_pressure_threshold,
int release_pressure_threshold,
int retrigger_pressure_threshold,
int retrigger_delay
) {
Object (
display: display,
x1: x1,
y1: y1,
x2: x2,
y2: y2,
directions: directions,
trigger_pressure_threshold: trigger_pressure_threshold,
release_pressure_threshold: release_pressure_threshold,
retrigger_pressure_threshold: retrigger_pressure_threshold,
retrigger_delay: retrigger_delay
);
}

construct {
hit.connect (on_hit);
left.connect (on_left);
}

private void on_hit (Meta.BarrierEvent event) {
if (POSITIVE_X in directions || NEGATIVE_X in directions) {
pressure += event.dx.abs ();
} else {
pressure += event.dy.abs ();
}

if (!triggered && pressure > trigger_pressure_threshold) {
emit_trigger (event.time);
}

if (!triggered && pressure > release_pressure_threshold) {
release (event);
}

if (triggered && pressure.abs () > retrigger_pressure_threshold && event.time > retrigger_delay + triggered_time) {
emit_trigger (event.time);
}
}

private void emit_trigger (uint32 time) {
triggered = true;
pressure = 0;
triggered_time = time;

trigger ();
}

private void on_left () {
pressure = 0;
triggered = false;
}
}
89 changes: 21 additions & 68 deletions src/HotCorners/HotCorner.vala
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/



private class Gala.Barrier : Meta.Barrier {
public bool is_hit { get; set; default = false; }
public double pressure_x { get; set; default = 0; }
public double pressure_y { get; set; default = 0; }

public Barrier (Meta.Display display, int x1, int y1, int x2, int y2, Meta.BarrierDirection directions) {
#if HAS_MUTTER46
Object (x1: x1, y1: y1, x2: x2, y2: y2, directions: directions);
#else
Object (display: display, x1: x1, y1: y1, x2: x2, y2: y2, directions: directions);
#endif
}
}

public class Gala.HotCorner : Object {
public const string POSITION_TOP_LEFT = "hotcorner-topleft";
public const string POSITION_TOP_RIGHT = "hotcorner-topright";
Expand Down Expand Up @@ -63,8 +47,6 @@ public class Gala.HotCorner : Object {

private Gala.Barrier? vertical_barrier = null;
private Gala.Barrier? horizontal_barrier = null;
private bool triggered = false;
private uint32 triggered_time;

public HotCorner (Meta.Display display, float x, float y, float scale, string hot_corner_position) {
add_barriers (display, x, y, scale, hot_corner_position);
Expand All @@ -86,14 +68,24 @@ public class Gala.HotCorner : Object {
var vdir = get_barrier_direction (hot_corner_position, Clutter.Orientation.VERTICAL);
var hdir = get_barrier_direction (hot_corner_position, Clutter.Orientation.HORIZONTAL);

vertical_barrier = new Gala.Barrier (display, vrect.x, vrect.y, vrect.x + vrect.width, vrect.y + vrect.height, vdir);
horizontal_barrier = new Gala.Barrier (display, hrect.x, hrect.y, hrect.x + hrect.width, hrect.y + hrect.height, hdir);

vertical_barrier.hit.connect ((event) => on_barrier_hit (vertical_barrier, event));
horizontal_barrier.hit.connect ((event) => on_barrier_hit (horizontal_barrier, event));

vertical_barrier.left.connect ((event) => on_barrier_left (vertical_barrier, event));
horizontal_barrier.left.connect ((event) => on_barrier_left (horizontal_barrier, event));
vertical_barrier = new Gala.Barrier (
display, vrect.x, vrect.y, vrect.x + vrect.width, vrect.y + vrect.height, vdir,
TRIGGER_PRESSURE_THRESHOLD,
RELEASE_PRESSURE_THRESHOLD,
RETRIGGER_PRESSURE_THRESHOLD,
RETRIGGER_DELAY
);

horizontal_barrier = new Gala.Barrier (
display, hrect.x, hrect.y, hrect.x + hrect.width, hrect.y + hrect.height, hdir,
TRIGGER_PRESSURE_THRESHOLD,
RELEASE_PRESSURE_THRESHOLD,
RETRIGGER_PRESSURE_THRESHOLD,
RETRIGGER_DELAY
);

vertical_barrier.trigger.connect (on_barrier_trigger);
horizontal_barrier.trigger.connect (on_barrier_trigger);
}

private static Meta.BarrierDirection get_barrier_direction (string hot_corner_position, Clutter.Orientation orientation) {
Expand Down Expand Up @@ -147,48 +139,9 @@ public class Gala.HotCorner : Object {
return { x1, y1, x2 - x1, y2 - y1 };
}

private void on_barrier_hit (Gala.Barrier barrier, Meta.BarrierEvent event) {
barrier.is_hit = true;
barrier.pressure_x += event.dx;
barrier.pressure_y += event.dy;

var pressure = (barrier == vertical_barrier) ?
barrier.pressure_x.abs () :
barrier.pressure_y.abs ();

if (!triggered && vertical_barrier.is_hit && horizontal_barrier.is_hit) {
if (pressure.abs () > TRIGGER_PRESSURE_THRESHOLD) {
trigger_hot_corner ();
pressure = 0;
triggered_time = event.time;
}
private void on_barrier_trigger () {
if (vertical_barrier.triggered && horizontal_barrier.triggered) {
trigger ();
}

if (!triggered && pressure.abs () > RELEASE_PRESSURE_THRESHOLD) {
barrier.release (event);
}

if (triggered && pressure.abs () > RETRIGGER_PRESSURE_THRESHOLD && event.time > RETRIGGER_DELAY + triggered_time) {
trigger_hot_corner ();
}
}

private void on_barrier_left (Gala.Barrier barrier, Meta.BarrierEvent event) {
barrier.is_hit = false;
barrier.pressure_x = 0;
barrier.pressure_y = 0;

if (!vertical_barrier.is_hit && !horizontal_barrier.is_hit) {
triggered = false;
}
}

private void trigger_hot_corner () {
triggered = true;
vertical_barrier.pressure_x = 0;
vertical_barrier.pressure_y = 0;
horizontal_barrier.pressure_x = 0;
horizontal_barrier.pressure_y = 0;
trigger ();
}
}
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ gala_bin_sources = files(
'Gestures/GestureTracker.vala',
'Gestures/ScrollBackend.vala',
'Gestures/ToucheggBackend.vala',
'HotCorners/Barrier.vala',
'HotCorners/HotCorner.vala',
'HotCorners/HotCornerManager.vala',
'Widgets/DwellClickTimer.vala',
Expand Down