From 2e2cfeebae38170d2ef1e83d4c85d93ef1f722bf Mon Sep 17 00:00:00 2001 From: Harrison DiAmbrosio Date: Fri, 24 Oct 2025 23:43:11 -0400 Subject: [PATCH] added process spawning --- 2 | 244 ------------------------------- runtime/share/mezzaluna/init.lua | 10 ++ src/keymap.zig | 3 +- src/lua/api.zig | 31 +++- src/main.zig | 8 +- 5 files changed, 47 insertions(+), 249 deletions(-) delete mode 100644 2 diff --git a/2 b/2 deleted file mode 100644 index ce39e5f..0000000 --- a/2 +++ /dev/null @@ -1,244 +0,0 @@ -//! Maintains state related to cursor position, rendering, and -//! events such as button presses and dragging - -pub const Cursor = @This(); - -const std = @import("std"); -const wl = @import("wayland").server.wl; -const wlr = @import("wlroots"); -const xkb = @import("xkbcommon"); - -const View = @import("view.zig"); -const Utils = @import("utils.zig"); - -const c = @import("c.zig").c; - -const server = &@import("main.zig").server; -const linux = std.os.linux; - -wlr_cursor: *wlr.Cursor, -x_cursor_manager: *wlr.XcursorManager, - -motion: wl.Listener(*wlr.Pointer.event.Motion) = .init(handleMotion), -motion_absolute: wl.Listener(*wlr.Pointer.event.MotionAbsolute) = .init(handleMotionAbsolute), -button: wl.Listener(*wlr.Pointer.event.Button) = .init(handleButton), -axis: wl.Listener(*wlr.Pointer.event.Axis) = .init(handleAxis), -frame: wl.Listener(*wlr.Cursor) = .init(handleFrame), -hold_begin: wl.Listener(*wlr.Pointer.event.HoldBegin) = .init(handleHoldBegin), -hold_end: wl.Listener(*wlr.Pointer.event.HoldEnd) = .init(handleHoldEnd), - -mode: enum { passthrough, move, resize } = .passthrough, - -// Drag information -selected_view: ?*View = null, -drag_start_x: c_int = 0, -drag_start_y: c_int = 0, -drag_view_offset_x: c_int = 0, -drag_view_offset_y: c_int = 0, - -pub fn init(self: *Cursor) void { - errdefer Utils.oomPanic(); - - self.* = .{ - .wlr_cursor = try wlr.Cursor.create(), - .x_cursor_manager = try wlr.XcursorManager.create(null, 24), - }; - - try self.x_cursor_manager.load(1); - - self.wlr_cursor.attachOutputLayout(server.root.output_layout); - - self.wlr_cursor.events.motion.add(&self.motion); - self.wlr_cursor.events.motion_absolute.add(&self.motion_absolute); - self.wlr_cursor.events.button.add(&self.button); - self.wlr_cursor.events.axis.add(&self.axis); - self.wlr_cursor.events.frame.add(&self.frame); - self.wlr_cursor.events.hold_begin.add(&self.hold_begin); - self.wlr_cursor.events.hold_end.add(&self.hold_end); -} - -pub fn deinit(self: *Cursor) void { - self.wlr_cursor.destroy(); - self.x_cursor_manager.destroy(); - - self.motion.link.remove(); - self.motion_absolute.link.remove(); - self.button.link.remove(); - self.axis.link.remove(); - self.frame.link.remove(); -} - -fn updateDrag(self: *Cursor) void { - self.drag_box.width = @as(c_int, @intFromFloat(self.wlr_cursor.x)) - self.drag_box.x; - self.drag_box.height = @as(c_int, @intFromFloat(self.wlr_cursor.y)) - self.drag_box.y; - - std.log.debug("{d}, {d}, {d}, {d}", .{self.drag_box.x, self.drag_box.y, self.drag_box.width, self.drag_box.height}); -} - -pub fn processCursorMotion(self: *Cursor, time_msec: u32) void { - switch (self.mode) { - .passthrough => { - if (server.root.viewAt(self.wlr_cursor.x, self.wlr_cursor.y)) |res| { - server.seat.wlr_seat.pointerNotifyEnter(res.surface, res.sx, res.sy); - server.seat.wlr_seat.pointerNotifyMotion(time_msec, res.sx, res.sy); - } else { - self.wlr_cursor.setXcursor(self.x_cursor_manager, "default"); - server.seat.wlr_seat.pointerClearFocus(); - } - }, - .move => { - const view = self.selected_view.?; - self.updateDrag(); - - // const half_width = @divFloor(view.xdg_surface.geometry.width, 2); - // const half_height = @divFloor(view.xdg_surface.geometry.width, 2); - - view.scene_tree.node.setPosition( - self.drag_box.x + @divFloor(self.drag_box.width, 2), - self.drag_box.y + @divFloor(self.drag_box.height, 2) - ); - }, - .resize => { - self.updateDrag(); - // Fix this resize - // - // REDOING RESIZING AND MOVING TOPLEVELS - // REDOING RESIZING AND MOVING TOPLEVELS - // REDOING RESIZING AND MOVING TOPLEVELS - // REDOING RESIZING AND MOVING TOPLEVELS - // - // const view = self.grabbed_view.?; - // const border_x = @as(i32, @intFromFloat(self.wlr_cursor.x - self.grab_x)); - // const border_y = @as(i32, @intFromFloat(self.wlr_cursor.y - self.grab_y)); - // - // var new_left = self.grab_box.x; - // var new_right = self.grab_box.x + self.grab_box.width; - // var new_top = self.grab_box.y; - // var new_bottom = self.grab_box.y + self.grab_box.height; - // - // if (self.resize_edges.top) { - // new_top = border_y; - // if (new_top >= new_bottom) - // new_top = new_bottom - 1; - // } else if (self.resize_edges.bottom) { - // new_bottom = border_y; - // if (new_bottom <= new_top) - // new_bottom = new_top + 1; - // } - // - // if (self.resize_edges.left) { - // new_left = border_x; - // if (new_left >= new_right) - // new_left = new_right - 1; - // } else if (self.resize_edges.right) { - // new_right = border_x; - // if (new_right <= new_left) - // new_right = new_left + 1; - // } - // - // // view.x = new_left - view.xdg_toplevel.base.geometry.x; - // // view.y = new_top - view.xdg_toplevel.base.geometry.y; - // view.scene_tree.node.setPosition(view.geometry.x, view.geometry.y); - // - // const new_width = new_right - new_left; - // const new_height = new_bottom - new_top; - // _ = view.xdg_toplevel.setSize(new_width, new_height); - }, - } -} - -// --------- WLR Cursor event handlers --------- -fn handleMotion( - _: *wl.Listener(*wlr.Pointer.event.Motion), - event: *wlr.Pointer.event.Motion, -) void { - server.cursor.wlr_cursor.move(event.device, event.delta_x, event.delta_y); - server.cursor.processCursorMotion(event.time_msec); -} - -fn handleMotionAbsolute( - _: *wl.Listener(*wlr.Pointer.event.MotionAbsolute), - event: *wlr.Pointer.event.MotionAbsolute, -) void { - server.cursor.wlr_cursor.warpAbsolute(event.device, event.x, event.y); - server.cursor.processCursorMotion(event.time_msec); -} - -fn handleButton( - listener: *wl.Listener(*wlr.Pointer.event.Button), - event: *wlr.Pointer.event.Button -) void { - const cursor: *Cursor = @fieldParentPtr("button", listener); - - _ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state); - - const view_at_result = server.root.viewAt(cursor.wlr_cursor.x, cursor.wlr_cursor.y); - if (view_at_result) |res| { - server.root.focusView(res.view); - } - - std.log.debug("Button pressed {}", .{event.button}); - - switch (event.state) { - .pressed => { - if(server.keyboard.wlr_keyboard.getModifiers().alt) { - // Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE - if(view_at_result) |res| { - // Keep track of where the drag started - cursor.selected_view = res.view; - cursor.drag_box.x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)); - cursor.drag_box.y = @as(c_int, @intFromFloat(cursor.wlr_cursor.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")) { - cursor.mode = .resize; - } - } - } - }, - .released => { - cursor.mode = .passthrough; - }, - else => { - std.log.err("Invalid/Unimplemented pointer button event type", .{}); - } - } -} - -fn handleHoldBegin( - listener: *wl.Listener(*wlr.Pointer.event.HoldBegin), - event: *wlr.Pointer.event.HoldBegin -) void { - _ = listener; - _ = event; - std.log.err("Unimplemented cursor start hold", .{}); -} - -fn handleHoldEnd( - listener: *wl.Listener(*wlr.Pointer.event.HoldEnd), - event: *wlr.Pointer.event.HoldEnd -) void { - _ = listener; - _ = event; - std.log.err("Unimplemented cursor end hold", .{}); -} - -fn handleAxis( - _: *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, - ); -} - -fn handleFrame(_: *wl.Listener(*wlr.Cursor), _: *wlr.Cursor) void { - server.seat.wlr_seat.pointerNotifyFrame(); -} diff --git a/runtime/share/mezzaluna/init.lua b/runtime/share/mezzaluna/init.lua index 767c610..6d6cbdd 100644 --- a/runtime/share/mezzaluna/init.lua +++ b/runtime/share/mezzaluna/init.lua @@ -14,3 +14,13 @@ package.path = package.path..";"..mez.fs.joinpath(env_conf, "mez", "lua", "?.lua mez.api.add_keymap("alt", "a", function() print("hello from my keymap") end) + +mez.api.add_keymap("alt", "t", function() + print("spawning foot") + mez.api.spawn("foot") +end) + +mez.api.add_keymap("alt", "p", function() + print("spawning foot") + mez.api.spawn("wmenu-run") +end) diff --git a/src/keymap.zig b/src/keymap.zig index c6363d6..84b9868 100644 --- a/src/keymap.zig +++ b/src/keymap.zig @@ -23,9 +23,10 @@ pub fn callback(self: *const Keymap) void { const t = Lua.state.rawGetIndex(zlua.registry_index, self.lua_ref_idx); if (t != zlua.LuaType.function) { std.log.err("Failed to call keybind, it doesn't have a callback.", .{}); + Lua.state.pop(1); return; } - Lua.state.pushValue(1); + Lua.state.call(.{ .args = 0, .results = 0 }); Lua.state.pop(-1); } diff --git a/src/lua/api.zig b/src/lua/api.zig index 0f097c6..c2aebb7 100644 --- a/src/lua/api.zig +++ b/src/lua/api.zig @@ -1,7 +1,6 @@ const Api = @This(); const std = @import("std"); -const server = &@import("../main.zig").server; const Keymap = @import("../keymap.zig"); const zlua = @import("zlua"); @@ -9,9 +8,12 @@ const xkb = @import("xkbcommon"); const wlr = @import("wlroots"); const gpa = std.heap.c_allocator; +const server = &@import("../main.zig").server; +const env_map = &@import("../main.zig").env_map; pub fn add_keymap(L: *zlua.Lua) i32 { const nargs: i32 = L.getTop(); + if (nargs < 3) { L.raiseErrorStr("Expected at least three arguments", .{}); return 0; @@ -23,6 +25,9 @@ pub fn add_keymap(L: *zlua.Lua) i32 { L.checkType(3, .function); var keymap: Keymap = undefined; + keymap.options = .{ + .on_release = false, + }; const mod = L.toString(1) catch { L.raiseErrorStr("Lua error check your config", .{}); @@ -89,3 +94,27 @@ pub fn get_keybind(L: *zlua.Lua) i32 { _ = L; return 0; } + +pub fn spawn(L: *zlua.Lua) i32 { + const nargs: i32 = L.getTop(); + + if (nargs < 1) { + L.raiseErrorStr("Expected at least one arguments", .{}); + return 0; + } + + L.checkType(1, .string); + + const cmd = L.toString(1) catch { + L.raiseErrorStr("Lua error check your config", .{}); + return 0; + }; + + var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa); + child.env_map = env_map; + child.spawn() catch { + std.log.err("Unable to spawn process \"{s}\"", .{cmd}); + }; + + return 0; +} diff --git a/src/main.zig b/src/main.zig index ab4bb16..d28f93b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,6 +8,7 @@ const gpa = std.heap.c_allocator; pub var server: Server = undefined; pub var lua: Lua = undefined; +pub var env_map: std.process.EnvMap = undefined; pub fn main() !void { wlr.log.init(.err, null); @@ -21,15 +22,16 @@ pub fn main() !void { var buf: [11]u8 = undefined; const socket = try server.wl_server.addSocketAuto(&buf); + env_map = try std.process.getEnvMap(gpa); + try env_map.put("WAYLAND_DISPLAY", socket); + if (std.os.argv.len >= 2) { const cmd = std.mem.span(std.os.argv[1]); var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa); - var env_map = try std.process.getEnvMap(gpa); - defer env_map.deinit(); - try env_map.put("WAYLAND_DISPLAY", socket); child.env_map = &env_map; try child.spawn(); } + defer env_map.deinit(); std.log.info("Starting backend", .{}); server.backend.start() catch |err| {