aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Cursor.zig83
-rw-r--r--river/InputManager.zig1
2 files changed, 55 insertions, 29 deletions
diff --git a/river/Cursor.zig b/river/Cursor.zig
index 2913c7c..ec9a216 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -42,52 +42,66 @@ const ResizeData = struct {
const Mode = union(enum) {
passthrough: void,
+ down: *View,
move: *View,
resize: ResizeData,
/// Enter move or resize mode
fn enter(self: *Self, mode: @TagType(Mode), event: *c.wlr_event_pointer_button, view: *View) void {
- std.debug.assert(self.mode == .passthrough);
-
log.debug(.cursor, "enter {} mode", .{@tagName(mode)});
- const cur_box = &view.current.box;
- self.mode = switch (mode) {
+ switch (mode) {
.passthrough => unreachable,
- .move => .{ .move = view },
- .resize => .{
- .resize = .{
- .view = view,
- .x_offset = cur_box.x + @intCast(i32, cur_box.width) - @floatToInt(i32, self.wlr_cursor.x),
- .y_offset = cur_box.y + @intCast(i32, cur_box.height) - @floatToInt(i32, self.wlr_cursor.y),
- },
- },
- };
-
- // Automatically float all views being moved by the pointer
- if (!view.current.float) {
- view.pending.float = true;
- // Start a transaction to apply the pending state of the grabbed
- // view and rearrange the layout to fill the hole.
- view.output.root.arrange();
- }
+ .down => self.mode = .{ .down = view },
+ .move, .resize => {
+ const cur_box = &view.current.box;
+ self.mode = switch (mode) {
+ .passthrough, .down => unreachable,
+ .move => .{ .move = view },
+ .resize => .{
+ .resize = .{
+ .view = view,
+ .x_offset = cur_box.x + @intCast(i32, cur_box.width) - @floatToInt(i32, self.wlr_cursor.x),
+ .y_offset = cur_box.y + @intCast(i32, cur_box.height) - @floatToInt(i32, self.wlr_cursor.y),
+ },
+ },
+ };
+
+ // Automatically float all views being moved by the pointer
+ if (!view.current.float) {
+ view.pending.float = true;
+ // Start a transaction to apply the pending state of the grabbed
+ // view and rearrange the layout to fill the hole.
+ view.output.root.arrange();
+ }
- // Clear cursor focus, so that the surface does not receive events
- c.wlr_seat_pointer_clear_focus(self.seat.wlr_seat);
+ // Clear cursor focus, so that the surface does not receive events
+ c.wlr_seat_pointer_clear_focus(self.seat.wlr_seat);
- c.wlr_xcursor_manager_set_cursor_image(
- self.wlr_xcursor_manager,
- if (mode == .move) "move" else "se-resize",
- self.wlr_cursor,
- );
+ c.wlr_xcursor_manager_set_cursor_image(
+ self.wlr_xcursor_manager,
+ if (mode == .move) "move" else "se-resize",
+ self.wlr_cursor,
+ );
+ },
+ }
}
- /// Return from move/resize to passthrough
+ /// Return from down/move/resize to passthrough
fn leave(self: *Self, event: *c.wlr_event_pointer_button) void {
std.debug.assert(self.mode != .passthrough);
log.debug(.cursor, "leave {} mode", .{@tagName(self.mode)});
+ // If we were in down mode, we need pass along the release event
+ if (self.mode == .down)
+ _ = c.wlr_seat_pointer_notify_button(
+ self.seat.wlr_seat,
+ event.time_msec,
+ event.button,
+ event.state,
+ );
+
self.mode = .passthrough;
passthrough(self, event.time_msec);
}
@@ -100,6 +114,15 @@ const Mode = union(enum) {
c.wlr_cursor_move(self.wlr_cursor, device, delta_x, delta_y);
passthrough(self, time);
},
+ .down => |view| {
+ c.wlr_cursor_move(self.wlr_cursor, device, delta_x, delta_y);
+ c.wlr_seat_pointer_notify_motion(
+ self.seat.wlr_seat,
+ time,
+ self.wlr_cursor.x - @intToFloat(f64, view.current.box.x),
+ self.wlr_cursor.y - @intToFloat(f64, view.current.box.y),
+ );
+ },
.move => |view| {
var output_width: c_int = undefined;
var output_height: c_int = undefined;
@@ -364,6 +387,8 @@ fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
else => {},
}
return;
+ } else {
+ Mode.enter(self, .down, event, view);
}
}
}
diff --git a/river/InputManager.zig b/river/InputManager.zig
index ddcd017..ab6dda4 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -108,6 +108,7 @@ pub fn isCursorActionTarget(self: Self, view: *View) bool {
const seat = &node.data;
switch (seat.cursor.mode) {
.passthrough => {},
+ .down => |target_view| if (target_view == view) break true,
.move => |target_view| if (target_view == view) break true,
.resize => |data| if (data.view == view) break true,
}