aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de>2021-06-23 15:56:38 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2021-07-23 11:48:01 +0000
commita3c657132674520de9f52de805057a598abfc5a2 (patch)
tree1fa923ccb853b6f37ffbc2d664dd08add09f1e89
parentb7d330c0dabdebf7fb844ed8cafff4aa44ed79bc (diff)
downloadriver-a3c657132674520de9f52de805057a598abfc5a2.tar.gz
river-a3c657132674520de9f52de805057a598abfc5a2.tar.xz
cursor: reset state if needed on transaction commit
A transaction may move the current target of a cursor action to a non-visible tag, make it fullscreen, or otherwise change things such that the current cursor state no longer makes sense. To handle this, check if we should reset cursor state every time a transaction is committed.
-rw-r--r--river/Cursor.zig35
-rw-r--r--river/Root.zig5
-rw-r--r--river/util.zig1
3 files changed, 41 insertions, 0 deletions
diff --git a/river/Cursor.zig b/river/Cursor.zig
index 5a09a88..dd1f51b 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -20,6 +20,7 @@ const Self = @This();
const build_options = @import("build_options");
const std = @import("std");
const assert = std.debug.assert;
+const os = std.os;
const math = std.math;
const wlr = @import("wlroots");
const wayland = @import("wayland");
@@ -674,6 +675,40 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
}
}
+/// Handle potential change in location of views on the output, as well as
+/// the target view of a cursor operation potentially being moved to a non-visible tag,
+/// becoming fullscreen, etc.
+pub fn maybeResetState(self: *Self) void {
+ switch (self.mode) {
+ .passthrough => {},
+ .down => |target| {
+ // If the target view is no longer visible, abort the operation.
+ if (target.current.tags & target.output.current.tags == 0) {
+ self.mode = .passthrough;
+ }
+ },
+ .resize, .move => {
+ // If the target view is no longer visible, or now fullscreen or no
+ // longer floating, abort the operation.
+ const target = if (self.mode == .resize) self.mode.resize.view else self.mode.move;
+ if (target.current.tags & target.output.current.tags == 0 or
+ (!target.current.float and target.output.current.layout != null) or
+ target.current.fullscreen)
+ {
+ self.mode = .passthrough;
+ }
+ },
+ }
+
+ if (self.mode == .passthrough) {
+ var now: os.timespec = undefined;
+ os.clock_gettime(os.CLOCK_MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
+ const msec = @intCast(u32, now.tv_sec * std.time.ms_per_s +
+ @divFloor(now.tv_nsec, std.time.ns_per_ms));
+ self.passthrough(msec);
+ }
+}
+
/// Pass an event on to the surface under the cursor, if any.
fn passthrough(self: *Self, time: u32) void {
assert(self.mode == .passthrough);
diff --git a/river/Root.zig b/river/Root.zig
index aad7541..b51abed 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -405,6 +405,11 @@ fn commitTransaction(self: *Self) void {
output.damage.addWhole();
}
+
+ var seat_it = server.input_manager.seats.first;
+ while (seat_it) |seat_node| : (seat_it = seat_node.next) {
+ seat_node.data.cursor.maybeResetState();
+ }
}
/// Send the new output configuration to all wlr-output-manager clients
diff --git a/river/util.zig b/river/util.zig
index d28122c..ceeea07 100644
--- a/river/util.zig
+++ b/river/util.zig
@@ -16,6 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
const std = @import("std");
+const os = std.os;
/// The global general-purpose allocator used throughout river's code
pub const gpa = std.heap.c_allocator;