Change window's output when being dragged between them

This commit is contained in:
Basil Keeler 2026-03-28 20:03:04 -05:00
commit 86808dbf47
2 changed files with 31 additions and 0 deletions

View file

@ -15,6 +15,7 @@ layer_focus: LayerFocus = .focus_none,
pointer_op: PointerOp = .none,
pointer_pos: utils.Pos = .{},
/// State consumed in manage phase, reset at end of manage().
pending_manage: PendingManage = .{},
@ -107,6 +108,11 @@ fn seatListener(river_seat_v1: *river.SeatV1, event: river.SeatV1.Event, seat: *
.op_release => {
seat.pending_manage.op_released = true;
},
.pointer_position => |ev| {
seat.pointer_pos.x = ev.x;
seat.pointer_pos.y = ev.y;
},
else => |ev| {
log.debug("unhandled event: {s}", .{@tagName(ev)});
},
@ -308,8 +314,24 @@ pub fn manage(seat: *Seat) void {
switch (seat.pointer_op) {
.none => {},
.move => {
const window = seat.focused_window orelse return;
seat.river_seat_v1.opEnd();
seat.pointer_op = .none;
// Iterate over every display and check if the curser is inside it
var it = seat.context.wm.outputs.iterator(.forward);
while (it.next()) |output| {
if (utils.isPosInRect(seat.pointer_pos, output.geometry)) {
window.pending_manage.pending_output = .{ .output = output };
std.log.debug("{}\n\n", .{output.geometry});
// We have to remove window from current output's windows list first
window.link.remove();
output.windows.append(window);
seat.pending_manage.output = .{ .output = output };
window.pending_manage.pending_output = .{ .output = output };
}
}
},
.resize => |op| {
op.window.river_window_v1.informResizeEnd();

View file

@ -19,6 +19,15 @@ pub const Rect = struct {
y: i32 = 0,
};
pub const Pos = struct {
x: i32 = 0,
y: i32 = 0,
};
pub fn isPosInRect(pos: Pos, rect: Rect) bool {
return (pos.x > rect.x and pos.x < rect.x + rect.width) and (pos.y > rect.y and pos.y < rect.y + rect.height);
}
/// Parse a color in the format 0xRRGGBB or 0xRRGGBBAA and convert it to
/// 32-bit color values (used by Window.set_borders in rwm).
pub fn parseRgba(s: []const u8) !RiverColor {