mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-08 04:57:32 -04:00
drag working, good callback arguments for moving and resizing views
This commit is contained in:
parent
9d8463255c
commit
973ea9d509
3 changed files with 142 additions and 99 deletions
199
src/Cursor.zig
199
src/Cursor.zig
|
|
@ -29,12 +29,17 @@ hold_end: wl.Listener(*wlr.Pointer.event.HoldEnd) = .init(handleHoldEnd),
|
|||
mode: enum { normal, drag } = .normal,
|
||||
|
||||
// Drag information
|
||||
drag: struct {
|
||||
start_x: c_int,
|
||||
start_y: c_int,
|
||||
view: ?*View,
|
||||
view_offset_x: ?c_int,
|
||||
view_offset_y: ?c_int,
|
||||
drag: ?struct {
|
||||
event_code: u32,
|
||||
start: struct {
|
||||
x: c_int,
|
||||
y: c_int
|
||||
},
|
||||
view: ?struct {
|
||||
view: *View,
|
||||
dims: struct { width: c_int, height: c_int },
|
||||
offset: struct { x: c_int, y: c_int, }
|
||||
},
|
||||
},
|
||||
|
||||
pub fn init(self: *Cursor) void {
|
||||
|
|
@ -43,13 +48,7 @@ pub fn init(self: *Cursor) void {
|
|||
self.* = .{
|
||||
.wlr_cursor = try wlr.Cursor.create(),
|
||||
.x_cursor_manager = try wlr.XcursorManager.create(null, 24),
|
||||
.drag = .{
|
||||
.start_x = 0,
|
||||
.start_y = 0,
|
||||
.view = null,
|
||||
.view_offset_x = null,
|
||||
.view_offset_y = null,
|
||||
}
|
||||
.drag = null
|
||||
};
|
||||
|
||||
try self.x_cursor_manager.load(1);
|
||||
|
|
@ -79,55 +78,57 @@ pub fn deinit(self: *Cursor) void {
|
|||
}
|
||||
|
||||
pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
||||
server.events.exec("PointerMotion", .{self.wlr_cursor.x, self.wlr_cursor.y});
|
||||
self.wlr_cursor.setXcursor(self.x_cursor_manager, "default");
|
||||
|
||||
switch (self.mode) {
|
||||
.normal => {
|
||||
const output = server.seat.focused_output;
|
||||
// Exit the switch if no focused output exists
|
||||
if (output == null) return;
|
||||
var handled = false;
|
||||
|
||||
const surfaceAtResult = output.?.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y);
|
||||
if (surfaceAtResult == null) {
|
||||
self.wlr_cursor.setXcursor(self.x_cursor_manager, "default");
|
||||
server.seat.wlr_seat.pointerClearFocus();
|
||||
if (self.mode == .drag) {
|
||||
const modifiers = server.seat.keyboard_group.keyboard.getModifiers();
|
||||
|
||||
// This is gonna be fun
|
||||
// server.seat.wlr_seat.keyboardSendKey(time_msec: u32, key: u32, state: u32);
|
||||
// server.seat.wlr_seat.pointerSendMotion(time_msec: u32, sx: f64, sy: f64)
|
||||
// server.seat.wlr_seat.pointerSendButton(time_msec: u32, button: u32, state: ButtonState)
|
||||
return;
|
||||
std.debug.assert(self.drag != null);
|
||||
|
||||
// Proceed if mousemap for current mouse and modifier state's exist
|
||||
if (server.mousemaps.get(Mousemap.hash(modifiers, @bitCast(self.drag.?.event_code)))) |map| {
|
||||
if(map.options.lua_drag_ref_idx > 0) {
|
||||
handled = true;
|
||||
map.callback(.drag, .{
|
||||
.{
|
||||
.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 (surfaceAtResult.?.scene_node_data.*) {
|
||||
.view => {
|
||||
// TODO: If serious performance issues arise from this, we need to be able to disable unused hooks
|
||||
// Perhaps after the config is executed, if no callbacks are present on this hook, we disable it entirely
|
||||
server.events.exec("ViewPointerMotion", .{surfaceAtResult.?.scene_node_data.view.id, self.wlr_cursor.x, self.wlr_cursor.y});
|
||||
},
|
||||
.layer_surface => { },
|
||||
else => unreachable
|
||||
if(!handled) {
|
||||
const output = server.seat.focused_output;
|
||||
// Exit the switch if no focused output exists
|
||||
std.debug.assert(output != null);
|
||||
|
||||
const surfaceAtResult = output.?.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y);
|
||||
if (surfaceAtResult) |surface| {
|
||||
if(surface.scene_node_data.* == .view) {
|
||||
server.events.exec("ViewPointerMotion", .{
|
||||
surface.scene_node_data.view.id,
|
||||
@as(c_int, @intFromFloat(self.wlr_cursor.x)),
|
||||
@as(c_int, @intFromFloat(self.wlr_cursor.y))
|
||||
});
|
||||
}
|
||||
|
||||
server.seat.wlr_seat.pointerNotifyEnter(surfaceAtResult.?.surface, surfaceAtResult.?.sx, surfaceAtResult.?.sy);
|
||||
server.seat.wlr_seat.pointerNotifyMotion(time_msec, surfaceAtResult.?.sx, surfaceAtResult.?.sy);
|
||||
},
|
||||
.drag => {
|
||||
|
||||
// @hook PointerDragMotion
|
||||
// @param button string // TODO Translate a button to a string or smth
|
||||
// @param state string - "pressed" or "released"
|
||||
// @param time_msecs number // TODO idk what the hell msecs is
|
||||
server.events.exec("PointerDragMotion", .{
|
||||
self.wlr_cursor.x,
|
||||
self.wlr_cursor.y,
|
||||
|
||||
self.drag.start_x,
|
||||
self.drag.start_y,
|
||||
self.drag.view.?.id,
|
||||
self.drag.view_offset_x,
|
||||
self.drag.view_offset_y
|
||||
});
|
||||
} else {
|
||||
// This may not be necessary, remove if no bugs
|
||||
server.seat.wlr_seat.pointerClearFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,45 +158,49 @@ fn handleButton(
|
|||
|
||||
switch (event.state) {
|
||||
.pressed => {
|
||||
cursor.drag.start_x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x));
|
||||
cursor.drag.start_y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
|
||||
cursor.mode = .drag;
|
||||
|
||||
cursor.drag = .{
|
||||
.event_code = event.button,
|
||||
.start = .{
|
||||
.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)),
|
||||
.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y))
|
||||
},
|
||||
.view = null
|
||||
};
|
||||
|
||||
// Keep track of where the drag started
|
||||
if(server.seat.focused_surface) |fs| {
|
||||
// Keep track of where the drag started
|
||||
|
||||
if(fs == .view) {
|
||||
cursor.drag.view = fs.view;
|
||||
cursor.drag.view_offset_x = cursor.drag.start_x - fs.view.scene_tree.node.x;
|
||||
cursor.drag.view_offset_y = cursor.drag.start_y - fs.view.scene_tree.node.y;
|
||||
cursor.drag.?.view = .{
|
||||
.view = fs.view,
|
||||
.dims = .{
|
||||
.width = fs.view.xdg_toplevel.base.geometry.width,
|
||||
.height = fs.view.xdg_toplevel.base.geometry.height
|
||||
},
|
||||
.offset = .{
|
||||
.x = cursor.drag.?.start.x - fs.view.scene_tree.node.x,
|
||||
.y = cursor.drag.?.start.y - fs.view.scene_tree.node.y
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Maybe comptime this for later reference
|
||||
// if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) {
|
||||
// cursor.mode = .move;
|
||||
// } else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) {
|
||||
// if(fs == .view) {
|
||||
// cursor.mode = .resize;
|
||||
// _ = fs.view.xdg_toplevel.setResizing(true);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
},
|
||||
.released => {
|
||||
cursor.mode = .normal;
|
||||
|
||||
if(cursor.drag.view) |view| {
|
||||
_ = view.xdg_toplevel.setResizing(false);
|
||||
}
|
||||
// How do we do this on the lua side
|
||||
// if(cursor.drag.view) |view| {
|
||||
// _ = view.xdg_toplevel.setResizing(false);
|
||||
// }
|
||||
|
||||
cursor.drag.view = null;
|
||||
cursor.drag.view_offset_x = null;
|
||||
cursor.drag.view_offset_y = null;
|
||||
cursor.drag.?.view = null;
|
||||
},
|
||||
else => {
|
||||
std.log.err("Invalid/Unimplemented pointer button event type", .{});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var handled = false;
|
||||
const modifiers = server.seat.keyboard_group.keyboard.getModifiers();
|
||||
|
||||
|
|
@ -205,13 +210,23 @@ fn handleButton(
|
|||
.pressed => {
|
||||
// Only make callback if a callback function exists
|
||||
if(map.options.lua_press_ref_idx > 0) {
|
||||
map.callback(.press);
|
||||
map.callback(.press, .{
|
||||
.{
|
||||
.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)),
|
||||
.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y))
|
||||
},
|
||||
});
|
||||
handled = true;
|
||||
}
|
||||
},
|
||||
.released => {
|
||||
if(map.options.lua_press_ref_idx > 0) {
|
||||
map.callback(.release);
|
||||
map.callback(.release, .{
|
||||
.{
|
||||
.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)),
|
||||
.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y))
|
||||
},
|
||||
});
|
||||
handled = true;
|
||||
}
|
||||
},
|
||||
|
|
@ -227,8 +242,8 @@ fn handleButton(
|
|||
}
|
||||
|
||||
fn handleHoldBegin(
|
||||
listener: *wl.Listener(*wlr.Pointer.event.HoldBegin),
|
||||
event: *wlr.Pointer.event.HoldBegin
|
||||
listener: *wl.Listener(*wlr.Pointer.event.HoldBegin),
|
||||
event: *wlr.Pointer.event.HoldBegin
|
||||
) void {
|
||||
_ = listener;
|
||||
_ = event;
|
||||
|
|
@ -236,8 +251,8 @@ event: *wlr.Pointer.event.HoldBegin
|
|||
}
|
||||
|
||||
fn handleHoldEnd(
|
||||
listener: *wl.Listener(*wlr.Pointer.event.HoldEnd),
|
||||
event: *wlr.Pointer.event.HoldEnd
|
||||
listener: *wl.Listener(*wlr.Pointer.event.HoldEnd),
|
||||
event: *wlr.Pointer.event.HoldEnd
|
||||
) void {
|
||||
_ = listener;
|
||||
_ = event;
|
||||
|
|
@ -245,17 +260,17 @@ event: *wlr.Pointer.event.HoldEnd
|
|||
}
|
||||
|
||||
fn handleAxis(
|
||||
_: *wl.Listener(*wlr.Pointer.event.Axis),
|
||||
event: *wlr.Pointer.event.Axis,
|
||||
_: *wl.Listener(*wlr.Pointer.event.Axis),
|
||||
event: *wlr.Pointer.event.Axis,
|
||||
) void {
|
||||
server.seat.wlr_seat.pointerNotifyAxis(
|
||||
event.time_msec,
|
||||
event.orientation,
|
||||
event.delta,
|
||||
event.delta_discrete,
|
||||
event.source,
|
||||
event.relative_direction,
|
||||
);
|
||||
event.time_msec,
|
||||
event.orientation,
|
||||
event.delta,
|
||||
event.delta_discrete,
|
||||
event.source,
|
||||
event.relative_direction,
|
||||
);
|
||||
}
|
||||
|
||||
fn handleFrame(_: *wl.Listener(*wlr.Cursor), _: *wlr.Cursor) void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue