pass the same info to all three mousemap callbacks

This commit is contained in:
Squibid 2026-03-07 18:49:47 -05:00
parent 790fad4074
commit cf779de4b4
Signed by: squibid
GPG key ID: BECE5684D3C4005D
2 changed files with 66 additions and 60 deletions

View file

@ -279,8 +279,10 @@ local master = function()
end end
mez.input.add_mousemap("alt", "BTN_LEFT", { mez.input.add_mousemap("alt", "BTN_LEFT", {
press = function() press = function(_, drag)
mez.input.set_cursor_type("pointer") if drag.view ~= nil then
mez.input.set_cursor_type("pointer")
end
end, end,
drag = function(pos, drag) drag = function(pos, drag)
if drag.view ~= nil then if drag.view ~= nil then
@ -295,8 +297,10 @@ local master = function()
-- This is so impractical -- This is so impractical
-- I love it -- I love it
mez.input.add_mousemap("alt|shift", "BTN_LEFT", { mez.input.add_mousemap("alt|shift", "BTN_LEFT", {
press = function() press = function(_, drag)
mez.input.set_cursor_type("cross") if drag.view ~= nil then
mez.input.set_cursor_type("cross")
end
move_all_drag = {} move_all_drag = {}
for _, id in ipairs(mez.view.get_all_ids()) do for _, id in ipairs(mez.view.get_all_ids()) do
move_all_drag[id] = mez.view.get_position(id) move_all_drag[id] = mez.view.get_position(id)
@ -314,8 +318,11 @@ local master = function()
}) })
mez.input.add_mousemap("alt", "BTN_RIGHT", { mez.input.add_mousemap("alt", "BTN_RIGHT", {
press = function() press = function(_, drag)
mez.input.set_cursor_type("cross") if drag.view ~= nil then
mez.input.set_cursor_type("cross")
mez.view.set_resizing(drag.view.id, true)
end
end, end,
drag = function(pos, drag) drag = function(pos, drag)
if drag.view ~= nil then if drag.view ~= nil then
@ -327,7 +334,10 @@ local master = function()
mez.view.set_size(drag.view.id, width, height) mez.view.set_size(drag.view.id, width, height)
end end
end, end,
release = function() release = function(_, drag)
if drag.view ~= nil then
mez.view.set_resizing(drag.view.id, false)
end
mez.input.set_cursor_type("default") mez.input.set_cursor_type("default")
end end
}) })

View file

@ -188,88 +188,84 @@ fn handleMotionAbsolute(
} }
fn handleButton(listener: *wl.Listener(*wlr.Pointer.event.Button), event: *wlr.Pointer.event.Button) void { fn handleButton(listener: *wl.Listener(*wlr.Pointer.event.Button), event: *wlr.Pointer.event.Button) void {
const cursor: *Cursor = @fieldParentPtr("button", listener); const self: *Cursor = @fieldParentPtr("button", listener);
switch (event.state) { if (event.state == .pressed) {
.pressed => { self.mode = .drag;
cursor.mode = .drag;
cursor.drag = .{ // Keep track of where the drag started
.event_code = event.button, self.drag = .{
.start = .{ .event_code = event.button,
.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)), .start = .{
.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)), .x = @as(c_int, @intFromFloat(self.wlr_cursor.x)),
}, .y = @as(c_int, @intFromFloat(self.wlr_cursor.y)),
.view = null, },
}; .view = view: {
const surfaceAtResult = server.seat.focused_output.?.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y);
// Keep track of where the drag started if (surfaceAtResult) |result| {
if (server.seat.focused_surface) |fs| { const fs = result.scene_node_data.*;
if (fs == .view) { if (fs == .view) break :view .{
cursor.drag.?.view = .{
.view = fs.view, .view = fs.view,
.dims = .{ .dims = .{
.width = fs.view.xdg_toplevel.base.geometry.width, .width = fs.view.xdg_toplevel.base.geometry.width,
.height = fs.view.xdg_toplevel.base.geometry.height, .height = fs.view.xdg_toplevel.base.geometry.height,
}, },
.offset = .{ .offset = .{
.x = cursor.drag.?.start.x - fs.view.scene_tree.node.x, .x = self.drag.?.start.x - fs.view.scene_tree.node.x,
.y = cursor.drag.?.start.y - fs.view.scene_tree.node.y, .y = self.drag.?.start.y - fs.view.scene_tree.node.y,
}, },
}; };
} }
} break :view null;
}, },
.released => { };
cursor.mode = .normal;
// How do we do this on the lua side
// if(cursor.drag.view) |view| {
// _ = view.xdg_toplevel.setResizing(false);
// }
cursor.drag.?.view = null;
},
else => {
std.log.err("Invalid/Unimplemented pointer button event type", .{});
},
} }
// run this as late as possible that way we can use the current drag info
// in the release callback
defer if (event.state == .released) {
self.mode = .normal;
self.drag.?.view = null; // the drag is over, don't keep any information
};
// by default we pass the mouse clicks through to the client
var passthrough = true; var passthrough = true;
const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers();
// Proceed if mousemap for current mouse and modifier state's exist // Proceed if mousemap for current mouse and modifier state's exist
const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers();
if (server.mousemaps.get(Mousemap.hash(modifiers, @bitCast(event.button)))) |map| { if (server.mousemaps.get(Mousemap.hash(modifiers, @bitCast(event.button)))) |map| {
const args = .{
.{
.x = @as(c_int, @intFromFloat(self.wlr_cursor.x)),
.y = @as(c_int, @intFromFloat(self.wlr_cursor.y)),
},
.{
.start = self.drag.?.start,
.view = if (self.drag.?.view != null) .{
.id = self.drag.?.view.?.view.id,
.dims = self.drag.?.view.?.dims,
.offset = self.drag.?.view.?.offset,
} else null,
}
};
switch (event.state) { switch (event.state) {
.pressed => { .pressed => {
// Only make callback if a callback function exists // Only call callback if a callback function exists
if (map.options.lua_press_ref_idx > 0) { if (map.options.lua_press_ref_idx > 0) {
passthrough = map.callback(.press, .{ passthrough = map.callback(.press, args);
.{
.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)),
.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)),
},
});
} }
}, },
.released => { .released => {
if (map.options.lua_press_ref_idx > 0) { // Only call callback if a callback function exists
passthrough = map.callback(.release, .{ if (map.options.lua_release_ref_idx > 0) {
.{ passthrough = map.callback(.release, args);
.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)),
.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)),
},
});
} }
}, },
else => { _ => undefined,
unreachable;
},
} }
} }
// If no keymap exists for button event, forward it to a surface // If no keymap exists for button event, forward it to a surface
// TODO: Allow for transparent mousemaps that pass mouse button events anyways
if (passthrough) { if (passthrough) {
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state); _ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
} }