From 6be66b6a715f23d944ebaf3c353890c2d4ad28c5 Mon Sep 17 00:00:00 2001 From: Squibid Date: Sun, 1 Mar 2026 22:23:31 -0500 Subject: [PATCH] reformatted with zig fmt --- .editorconfig | 5 - build.zig | 142 ++++++------ src/Cursor.zig | 339 ++++++++++++---------------- src/Debug.zig | 13 +- src/Keyboard.zig | 160 +++++++------ src/KeyboardGroup.zig | 69 +++--- src/LayerSurface.zig | 140 ++++++------ src/Output.zig | 470 +++++++++++++++++++-------------------- src/Popup.zig | 92 ++++---- src/RemoteLua.zig | 132 +++++------ src/RemoteLuaManager.zig | 48 ++-- src/Root.zig | 127 ++++++----- src/SceneNodeData.zig | 8 +- src/Seat.zig | 221 +++++++++--------- src/Server.zig | 308 ++++++++++++------------- src/Utils.zig | 4 +- src/View.zig | 372 +++++++++++++++---------------- src/lua/Api.zig | 62 +++--- src/lua/Bridge.zig | 32 +-- src/lua/Fs.zig | 44 ++-- src/lua/Hook.zig | 84 +++---- src/lua/Input.zig | 186 ++++++++-------- src/lua/Lua.zig | 279 +++++++++++------------ src/lua/LuaUtils.zig | 68 +++--- src/lua/Output.zig | 185 ++++++++------- src/lua/Remote.zig | 4 +- src/lua/View.zig | 421 +++++++++++++++++------------------ src/main.zig | 106 ++++----- src/types/Events.zig | 64 +++--- src/types/Hook.zig | 48 ++-- src/types/Keymap.zig | 38 ++-- src/types/Mousemap.zig | 74 +++--- 32 files changed, 2108 insertions(+), 2237 deletions(-) diff --git a/.editorconfig b/.editorconfig index 18446ef..9aa39da 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,11 +6,6 @@ root = true end_of_line = lf insert_final_newline = true -[*.zig] -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true - [*.lua] indent_style = space indent_size = 2 diff --git a/build.zig b/build.zig index 0ed33e0..f55356c 100644 --- a/build.zig +++ b/build.zig @@ -4,89 +4,89 @@ const builtin = @import("builtin"); const Scanner = @import("wayland").Scanner; pub fn build(b: *std.Build) void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); - // TODO: this will probably change based on the install paths, make this a var - // that can be passed at comptime? - const runtime_path_prefix = switch (builtin.mode) { - .Debug => "runtime/", - else => "/usr/share", - }; + // TODO: this will probably change based on the install paths, make this a var + // that can be passed at comptime? + const runtime_path_prefix = switch (builtin.mode) { + .Debug => "runtime/", + else => "/usr/share", + }; - // Add protocol xml files - const scanner = Scanner.create(b, .{}); - scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml"); - scanner.addSystemProtocol("stable/tablet/tablet-v2.xml"); - scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"); - scanner.addCustomProtocol(b.path("protocols/wlr-layer-shell-unstable-v1.xml")); - scanner.addCustomProtocol(b.path("protocols/mez-remote-lua-unstable-v1.xml")); + // Add protocol xml files + const scanner = Scanner.create(b, .{}); + scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml"); + scanner.addSystemProtocol("stable/tablet/tablet-v2.xml"); + scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"); + scanner.addCustomProtocol(b.path("protocols/wlr-layer-shell-unstable-v1.xml")); + scanner.addCustomProtocol(b.path("protocols/mez-remote-lua-unstable-v1.xml")); - // Generate protocol code - scanner.generate("zmez_remote_lua_manager_v1", 1); - scanner.generate("wl_compositor", 6); - scanner.generate("wl_subcompositor", 1); - scanner.generate("wl_shm", 2); - scanner.generate("wl_output", 4); - scanner.generate("wl_seat", 9); - scanner.generate("wl_data_device_manager", 3); - scanner.generate("zxdg_decoration_manager_v1", 1); - scanner.generate("xdg_wm_base", 7); - scanner.generate("zwp_tablet_manager_v2", 2); - scanner.generate("zwlr_layer_shell_v1", 5); + // Generate protocol code + scanner.generate("zmez_remote_lua_manager_v1", 1); + scanner.generate("wl_compositor", 6); + scanner.generate("wl_subcompositor", 1); + scanner.generate("wl_shm", 2); + scanner.generate("wl_output", 4); + scanner.generate("wl_seat", 9); + scanner.generate("wl_data_device_manager", 3); + scanner.generate("zxdg_decoration_manager_v1", 1); + scanner.generate("xdg_wm_base", 7); + scanner.generate("zwp_tablet_manager_v2", 2); + scanner.generate("zwlr_layer_shell_v1", 5); - const wayland = b.createModule(.{ .root_source_file = scanner.result }); - const xkbcommon = b.dependency("xkbcommon", .{}).module("xkbcommon"); - const pixman = b.dependency("pixman", .{}).module("pixman"); - const wlroots = b.dependency("wlroots", .{}).module("wlroots"); - const zlua = b.dependency("zlua", .{ .optimize = optimize, .target = target, .lang = .lua51 }).module("zlua"); - const clap = b.dependency("clap", .{}).module("clap"); + const wayland = b.createModule(.{ .root_source_file = scanner.result }); + const xkbcommon = b.dependency("xkbcommon", .{}).module("xkbcommon"); + const pixman = b.dependency("pixman", .{}).module("pixman"); + const wlroots = b.dependency("wlroots", .{}).module("wlroots"); + const zlua = b.dependency("zlua", .{ .optimize = optimize, .target = target, .lang = .lua51 }).module("zlua"); + const clap = b.dependency("clap", .{}).module("clap"); - wlroots.addImport("wayland", wayland); - wlroots.addImport("xkbcommon", xkbcommon); - wlroots.addImport("pixman", pixman); + wlroots.addImport("wayland", wayland); + wlroots.addImport("xkbcommon", xkbcommon); + wlroots.addImport("pixman", pixman); - wlroots.resolved_target = target; - wlroots.linkSystemLibrary("wlroots-0.19", .{}); + wlroots.resolved_target = target; + wlroots.linkSystemLibrary("wlroots-0.19", .{}); - const mez = b.addExecutable(.{ - .name = "mez", - .root_module = b.createModule(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }), - }); + const mez = b.addExecutable(.{ + .name = "mez", + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }), + }); - mez.root_module.link_libc = true; + mez.root_module.link_libc = true; - mez.root_module.addImport("wayland", wayland); - mez.root_module.addImport("xkbcommon", xkbcommon); - mez.root_module.addImport("wlroots", wlroots); - mez.root_module.addImport("zlua", zlua); - mez.root_module.addImport("clap", clap); + mez.root_module.addImport("wayland", wayland); + mez.root_module.addImport("xkbcommon", xkbcommon); + mez.root_module.addImport("wlroots", wlroots); + mez.root_module.addImport("zlua", zlua); + mez.root_module.addImport("clap", clap); - mez.root_module.linkSystemLibrary("wayland-server", .{}); - mez.root_module.linkSystemLibrary("xkbcommon", .{}); - mez.root_module.linkSystemLibrary("pixman-1", .{}); - mez.root_module.linkSystemLibrary("libevdev", .{}); + mez.root_module.linkSystemLibrary("wayland-server", .{}); + mez.root_module.linkSystemLibrary("xkbcommon", .{}); + mez.root_module.linkSystemLibrary("pixman-1", .{}); + mez.root_module.linkSystemLibrary("libevdev", .{}); - var ret: u8 = undefined; - const version = b.runAllowFail( - &.{"git", "-C", b.build_root.path orelse ".", "describe", "--tags", "--dirty"}, - &ret, - .Inherit, - ) catch "dev\n"; + var ret: u8 = undefined; + const version = b.runAllowFail( + &.{ "git", "-C", b.build_root.path orelse ".", "describe", "--tags", "--dirty" }, + &ret, + .Inherit, + ) catch "dev\n"; - const options = b.addOptions(); - options.addOption([]const u8, "runtime_path_prefix", runtime_path_prefix); - options.addOption([]const u8, "version", version); - mez.root_module.addOptions("config", options); + const options = b.addOptions(); + options.addOption([]const u8, "runtime_path_prefix", runtime_path_prefix); + options.addOption([]const u8, "version", version); + mez.root_module.addOptions("config", options); - b.installArtifact(mez); + b.installArtifact(mez); - const run_step = b.step("run", "Run the compositor"); - const run_cmd = b.addRunArtifact(mez); - run_step.dependOn(&run_cmd.step); - run_cmd.step.dependOn(b.getInstallStep()); + const run_step = b.step("run", "Run the compositor"); + const run_cmd = b.addRunArtifact(mez); + run_step.dependOn(&run_cmd.step); + run_cmd.step.dependOn(b.getInstallStep()); } diff --git a/src/Cursor.zig b/src/Cursor.zig index 3223245..38a5843 100644 --- a/src/Cursor.zig +++ b/src/Cursor.zig @@ -30,245 +30,198 @@ mode: enum { normal, drag } = .normal, // Drag information 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, } - }, + 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 { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - self.* = .{ - .wlr_cursor = try wlr.Cursor.create(), - .x_cursor_manager = try wlr.XcursorManager.create(null, 24), - .drag = null - }; + self.* = .{ + .wlr_cursor = try wlr.Cursor.create(), + .x_cursor_manager = try wlr.XcursorManager.create(null, 24), + .drag = null, + }; - try self.x_cursor_manager.load(1); + try self.x_cursor_manager.load(1); - self.wlr_cursor.attachOutputLayout(server.root.output_layout); + 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); + 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.motion.link.remove(); - self.motion_absolute.link.remove(); - self.button.link.remove(); - self.axis.link.remove(); - self.frame.link.remove(); - self.hold_begin.link.remove(); - self.hold_end.link.remove(); + self.motion.link.remove(); + self.motion_absolute.link.remove(); + self.button.link.remove(); + self.axis.link.remove(); + self.frame.link.remove(); + self.hold_begin.link.remove(); + self.hold_end.link.remove(); - self.wlr_cursor.destroy(); - self.x_cursor_manager.destroy(); + self.wlr_cursor.destroy(); + self.x_cursor_manager.destroy(); } pub fn processCursorMotion(self: *Cursor, time_msec: u32) void { - var passthrough = true; + var passthrough = true; - if (self.mode == .drag) { - const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers(); + if (self.mode == .drag) { + const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers(); - std.debug.assert(self.drag != null); + 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) { - passthrough = 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 - } - }); - } + // 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) { + passthrough = 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 } }); + } + } } - } - if(passthrough) { - const output = server.seat.focused_output; - // Exit the switch if no focused output exists - std.debug.assert(output != null); + if (passthrough) { + 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)) - }); - } + 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); - } else { - // This may not be necessary, remove if no bugs - server.seat.wlr_seat.pointerClearFocus(); - self.wlr_cursor.setXcursor(self.x_cursor_manager, "default"); + server.seat.wlr_seat.pointerNotifyEnter(surfaceAtResult.?.surface, surfaceAtResult.?.sx, surfaceAtResult.?.sy); + server.seat.wlr_seat.pointerNotifyMotion(time_msec, surfaceAtResult.?.sx, surfaceAtResult.?.sy); + } else { + // This may not be necessary, remove if no bugs + server.seat.wlr_seat.pointerClearFocus(); + self.wlr_cursor.setXcursor(self.x_cursor_manager, "default"); + } } - } } // --------- WLR Cursor event handlers --------- fn handleMotion( -_: *wl.Listener(*wlr.Pointer.event.Motion), -event: *wlr.Pointer.event.Motion, + _: *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); + 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, + _: *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); + 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); +fn handleButton(listener: *wl.Listener(*wlr.Pointer.event.Button), event: *wlr.Pointer.event.Button) void { + const cursor: *Cursor = @fieldParentPtr("button", listener); - switch (event.state) { - .pressed => { - 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| { - if(fs == .view) { - 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 - }, - }; - } - } - }, - .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", .{}); - } - } - - var passthrough = true; - const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers(); - - // Proceed if mousemap for current mouse and modifier state's exist - if (server.mousemaps.get(Mousemap.hash(modifiers, @bitCast(event.button)))) |map| { switch (event.state) { - .pressed => { - // Only make callback if a callback function exists - if(map.options.lua_press_ref_idx > 0) { - passthrough = map.callback(.press, .{ - .{ - .x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)), - .y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)) - }, - }); - } - }, - .released => { - if(map.options.lua_press_ref_idx > 0) { - passthrough = map.callback(.release, .{ - .{ - .x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)), - .y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)) - }, - }); - } - }, - else => { unreachable; } + .pressed => { + 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| { + if (fs == .view) { + 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 }, + }; + } + } + }, + .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", .{}); + }, } - } - // 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) { - _ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state); - } + var passthrough = true; + const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers(); + + // Proceed if mousemap for current mouse and modifier state's exist + if (server.mousemaps.get(Mousemap.hash(modifiers, @bitCast(event.button)))) |map| { + switch (event.state) { + .pressed => { + // Only make callback if a callback function exists + if (map.options.lua_press_ref_idx > 0) { + passthrough = map.callback(.press, .{ + .{ .x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)), .y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)) }, + }); + } + }, + .released => { + if (map.options.lua_press_ref_idx > 0) { + passthrough = map.callback(.release, .{ + .{ .x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x)), .y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y)) }, + }); + } + }, + else => { + unreachable; + }, + } + } + + // 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) { + _ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state); + } } -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 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 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, + _: *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, - ); + 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(); + server.seat.wlr_seat.pointerNotifyFrame(); } diff --git a/src/Debug.zig b/src/Debug.zig index 426b5ac..5457315 100644 --- a/src/Debug.zig +++ b/src/Debug.zig @@ -31,15 +31,10 @@ fn printNode(node: *wlr.SceneNode, depth: usize) void { const type_name = switch (node.type) { .tree => "TREE", .rect => "RECT", - .buffer => "BUFFER" + .buffer => "BUFFER", }; - writer.print("{s} @ ({d}, {d}) enabled={}", .{ - type_name, - node.x, - node.y, - node.enabled - }) catch unreachable; + writer.print("{s} @ ({d}, {d}) enabled={}", .{ type_name, node.x, node.y, node.enabled }) catch unreachable; // Add associated data if present if (node.data) |data| { @@ -56,7 +51,7 @@ fn printNode(node: *wlr.SceneNode, depth: usize) void { }) catch unreachable; }, .output_layer => { - writer.print(" → Output Layer", .{}) catch unreachable; + writer.print(" → Output Layer", .{}) catch unreachable; }, .view => |view| { writer.print(" → View: id={} mapped={} focused={}", .{ @@ -84,7 +79,7 @@ fn printNode(node: *wlr.SceneNode, depth: usize) void { if (namespace.len > 0) { writer.print(" namespace=\"{s}\"", .{namespace}) catch unreachable; } - } + }, } } diff --git a/src/Keyboard.zig b/src/Keyboard.zig index fa1f3e8..527ebd9 100644 --- a/src/Keyboard.zig +++ b/src/Keyboard.zig @@ -26,120 +26,114 @@ modifiers: wl.Listener(*wlr.Keyboard) = .init(handleModifiers), destroy: wl.Listener(*wlr.InputDevice) = .init(handleDestroy), pub fn init(device: *wlr.InputDevice) *Keyboard { - const self = gpa.create(Keyboard) catch Utils.oomPanic(); + const self = gpa.create(Keyboard) catch Utils.oomPanic(); - errdefer { - std.log.err("Unable to initialize new keyboard, exiting", .{}); - std.process.exit(6); - } + errdefer { + std.log.err("Unable to initialize new keyboard, exiting", .{}); + std.process.exit(6); + } - self.* = .{ - .context = xkb.Context.new(.no_flags) orelse return error.ContextFailed, - .wlr_keyboard = device.toKeyboard(), - .device = device, - }; + self.* = .{ + .context = xkb.Context.new(.no_flags) orelse return error.ContextFailed, + .wlr_keyboard = device.toKeyboard(), + .device = device, + }; - // TODO: configure this via lua later - // Should handle this error here - if (!self.wlr_keyboard.setKeymap(server.seat.keymap)) return error.SetKeymapFailed; - self.wlr_keyboard.setRepeatInfo(25, 600); + // TODO: configure this via lua later + // Should handle this error here + if (!self.wlr_keyboard.setKeymap(server.seat.keymap)) return error.SetKeymapFailed; + self.wlr_keyboard.setRepeatInfo(25, 600); - self.wlr_keyboard.events.modifiers.add(&self.modifiers); - self.wlr_keyboard.events.key.add(&self.key); - self.wlr_keyboard.events.keymap.add(&self.key_map); + self.wlr_keyboard.events.modifiers.add(&self.modifiers); + self.wlr_keyboard.events.key.add(&self.key); + self.wlr_keyboard.events.keymap.add(&self.key_map); - device.events.destroy.add(&self.destroy); + device.events.destroy.add(&self.destroy); - self.wlr_keyboard.data = self; + self.wlr_keyboard.data = self; - std.log.err("Adding new keyboard {s}", .{device.name orelse "(unnamed)"}); - if(!server.seat.keyboard_group.wlr_group.addKeyboard(self.wlr_keyboard)) { - std.log.err("Adding new keyboard {s} failed", .{device.name orelse "(unnamed)"}); - } + std.log.err("Adding new keyboard {s}", .{device.name orelse "(unnamed)"}); + if (!server.seat.keyboard_group.wlr_group.addKeyboard(self.wlr_keyboard)) { + std.log.err("Adding new keyboard {s} failed", .{device.name orelse "(unnamed)"}); + } - return self; + return self; } -pub fn deinit (self: *Keyboard) void { - self.key.link.remove(); - self.key_map.link.remove(); - self.modifiers.link.remove(); +pub fn deinit(self: *Keyboard) void { + self.key.link.remove(); + self.key_map.link.remove(); + self.modifiers.link.remove(); } fn handleModifiers(_: *wl.Listener(*wlr.Keyboard), wlr_keyboard: *wlr.Keyboard) void { - server.seat.wlr_seat.setKeyboard(wlr_keyboard); - server.seat.wlr_seat.keyboardNotifyModifiers(&wlr_keyboard.modifiers); + server.seat.wlr_seat.setKeyboard(wlr_keyboard); + server.seat.wlr_seat.keyboardNotifyModifiers(&wlr_keyboard.modifiers); } fn handleKey(listener: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboard.event.Key) void { - const keyboard: *Keyboard = @fieldParentPtr("key", listener); - // Translate libinput keycode -> xkbcommon - const keycode = event.keycode + 8; + const keyboard: *Keyboard = @fieldParentPtr("key", listener); + // Translate libinput keycode -> xkbcommon + const keycode = event.keycode + 8; - var handled: bool = false; - const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers(); - if (server.seat.keyboard_group.wlr_group.keyboard.xkb_state) |xkb_state| { - const keysyms = xkb_state.keyGetSyms(keycode); - for (keysyms) |sym| { - handled = keypress(modifiers, sym, event.state); + var handled: bool = false; + const modifiers = server.seat.keyboard_group.wlr_group.keyboard.getModifiers(); + if (server.seat.keyboard_group.wlr_group.keyboard.xkb_state) |xkb_state| { + const keysyms = xkb_state.keyGetSyms(keycode); + for (keysyms) |sym| { + handled = keypress(modifiers, sym, event.state); + } + + // give the keyboard group information about what to repeat and update it + if (handled and keyboard.wlr_keyboard.repeat_info.delay > 0) { + server.seat.keyboard_group.modifiers = modifiers; + server.seat.keyboard_group.keysyms = keysyms; + server.seat.keyboard_group.repeat_source.?.timerUpdate( + keyboard.wlr_keyboard.repeat_info.delay, + ) catch { + std.log.warn("failed to update keyboard repeat timer", .{}); + }; + } else { + server.seat.keyboard_group.modifiers = null; + server.seat.keyboard_group.keysyms = null; + } } - // give the keyboard group information about what to repeat and update it - if (handled and keyboard.wlr_keyboard.repeat_info.delay > 0) { - server.seat.keyboard_group.modifiers = modifiers; - server.seat.keyboard_group.keysyms = keysyms; - server.seat.keyboard_group.repeat_source.?.timerUpdate( - keyboard.wlr_keyboard.repeat_info.delay, - ) catch { - std.log.warn("failed to update keyboard repeat timer", .{}); - }; - } else { - server.seat.keyboard_group.modifiers = null; - server.seat.keyboard_group.keysyms = null; + if (handled and keyboard.wlr_keyboard.repeat_info.delay > 0) {} + + if (!handled) { + server.seat.wlr_seat.setKeyboard(&server.seat.keyboard_group.wlr_group.keyboard); + server.seat.wlr_seat.keyboardNotifyKey(event.time_msec, event.keycode, event.state); } - } - - if (handled and keyboard.wlr_keyboard.repeat_info.delay > 0) { - - } - - if (!handled) { - server.seat.wlr_seat.setKeyboard(&server.seat.keyboard_group.wlr_group.keyboard); - server.seat.wlr_seat.keyboardNotifyKey(event.time_msec, event.keycode, event.state); - } } -pub fn keypress( - modifiers: wlr.Keyboard.ModifierMask, - sym: xkb.Keysym, - state: wl.Keyboard.KeyState -) bool { - if (server.keymaps.get(Keymap.hash(modifiers, sym))) |map| { - if (state == .pressed and map.options.lua_press_ref_idx > 0) { - map.callback(false); - return true; - } else if (state == .released and map.options.lua_release_ref_idx > 0) { - map.callback(true); - return true; +pub fn keypress(modifiers: wlr.Keyboard.ModifierMask, sym: xkb.Keysym, state: wl.Keyboard.KeyState) bool { + if (server.keymaps.get(Keymap.hash(modifiers, sym))) |map| { + if (state == .pressed and map.options.lua_press_ref_idx > 0) { + map.callback(false); + return true; + } else if (state == .released and map.options.lua_release_ref_idx > 0) { + map.callback(true); + return true; + } } - } - return false; + return false; } fn handleKeyMap(_: *wl.Listener(*wlr.Keyboard), _: *wlr.Keyboard) void { - std.log.err("Unimplemented handle keyboard keymap", .{}); + std.log.err("Unimplemented handle keyboard keymap", .{}); } pub fn handleDestroy(listener: *wl.Listener(*wlr.InputDevice), _: *wlr.InputDevice) void { - const keyboard: *Keyboard = @fieldParentPtr("destroy", listener); + const keyboard: *Keyboard = @fieldParentPtr("destroy", listener); - std.log.debug("removing keyboard: {s}", .{keyboard.device.name orelse "(null)"}); + std.log.debug("removing keyboard: {s}", .{keyboard.device.name orelse "(null)"}); - keyboard.modifiers.link.remove(); - keyboard.key.link.remove(); - keyboard.key_map.link.remove(); - keyboard.destroy.link.remove(); + keyboard.modifiers.link.remove(); + keyboard.key.link.remove(); + keyboard.key_map.link.remove(); + keyboard.destroy.link.remove(); - gpa.destroy(keyboard); + gpa.destroy(keyboard); } diff --git a/src/KeyboardGroup.zig b/src/KeyboardGroup.zig index 46327a4..596a156 100644 --- a/src/KeyboardGroup.zig +++ b/src/KeyboardGroup.zig @@ -6,7 +6,7 @@ const wlr = @import("wlroots"); const xkb = @import("xkbcommon"); const Keyboard = @import("Keyboard.zig"); -const Utils = @import("Utils.zig"); +const Utils = @import("Utils.zig"); const server = &@import("main.zig").server; const gpa = std.heap.c_allocator; @@ -17,47 +17,48 @@ modifiers: ?wlr.Keyboard.ModifierMask, keysyms: ?[]const xkb.Keysym, pub fn init() *KeyboardGroup { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const self = try gpa.create(KeyboardGroup); - self.* = .{ - .wlr_group = wlr.KeyboardGroup.create() catch Utils.oomPanic(), - .repeat_source = blk: { - break :blk server.event_loop.addTimer(?*KeyboardGroup, handleRepeat, self) catch { - std.log.err("Failed to create event loop timer, keyboard repeating will not work!", .{}); - break :blk null; - }; - }, - .modifiers = null, - .keysyms = null, - }; + const self = try gpa.create(KeyboardGroup); + self.* = .{ + .wlr_group = wlr.KeyboardGroup.create() catch Utils.oomPanic(), + .repeat_source = blk: { + break :blk server.event_loop.addTimer(?*KeyboardGroup, handleRepeat, self) catch { + std.log.err("Failed to create event loop timer, keyboard repeating will not work!", .{}); + break :blk null; + }; + }, + .modifiers = null, + .keysyms = null, + }; - return self; + return self; } pub fn deinit(self: *KeyboardGroup) void { - self.wlr_group.destroy(); - gpa.destroy(self); + self.wlr_group.destroy(); + gpa.destroy(self); } fn handleRepeat(data: ?*KeyboardGroup) c_int { - // we failed to create the event loop timer, which means we can't repeat keys - if (data.?.repeat_source == null) return 0; + // we failed to create the event loop timer, which means we can't repeat keys + if (data.?.repeat_source == null) return 0; + + if (data == null or data.?.keysyms == null or data.?.modifiers == null or + data.?.wlr_group.keyboard.repeat_info.rate <= 0) + { + return 0; + } + + data.?.repeat_source.?.timerUpdate( + @divTrunc(1000, data.?.wlr_group.keyboard.repeat_info.rate), + ) catch { + // not sure how big of a deal it is if we miss a timer update + std.log.warn("failed to update keyboard repeat timer", .{}); + }; + for (data.?.keysyms.?) |sym| { + _ = Keyboard.keypress(data.?.modifiers.?, sym, .pressed); + } - if (data == null or data.?.keysyms == null or data.?.modifiers == null or - data.?.wlr_group.keyboard.repeat_info.rate <= 0) { return 0; - } - - data.?.repeat_source.?.timerUpdate( - @divTrunc(1000, data.?.wlr_group.keyboard.repeat_info.rate), - ) catch { - // not sure how big of a deal it is if we miss a timer update - std.log.warn("failed to update keyboard repeat timer", .{}); - }; - for (data.?.keysyms.?) |sym| { - _ = Keyboard.keypress(data.?.modifiers.?, sym, .pressed); - } - - return 0; } diff --git a/src/LayerSurface.zig b/src/LayerSurface.zig index 6ae493b..bb7247f 100644 --- a/src/LayerSurface.zig +++ b/src/LayerSurface.zig @@ -23,109 +23,97 @@ commit: wl.Listener(*wlr.Surface) = .init(handleCommit), // new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup), pub fn init(wlr_layer_surface: *wlr.LayerSurfaceV1) *LayerSurface { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const self = try gpa.create(LayerSurface); + const self = try gpa.create(LayerSurface); - self.* = .{ - .output = undefined, - .wlr_layer_surface = wlr_layer_surface, - .scene_layer_surface = undefined, - .scene_node_data = .{ .layer_surface = self } - }; - - if(wlr_layer_surface.output.?.data == null) { - std.log.err("Wlr_output arbitrary data not assigned", .{}); - unreachable; - } - self.output = @ptrCast(@alignCast(wlr_layer_surface.output.?.data)); - - if(server.seat.focused_output) |output| { - self.scene_layer_surface = switch (wlr_layer_surface.current.layer) { - .background => try output.layers.background.createSceneLayerSurfaceV1(wlr_layer_surface), - .bottom => try output.layers.bottom.createSceneLayerSurfaceV1(wlr_layer_surface), - .top => try output.layers.top.createSceneLayerSurfaceV1(wlr_layer_surface), - .overlay => try output.layers.overlay.createSceneLayerSurfaceV1(wlr_layer_surface), - else => { - std.log.err("New layer surface of unidentified type", .{}); - unreachable; - } + self.* = .{ + .output = undefined, + .wlr_layer_surface = wlr_layer_surface, + .scene_layer_surface = undefined, + .scene_node_data = .{ .layer_surface = self }, }; - } - self.wlr_layer_surface.surface.data = &self.scene_node_data; - self.scene_layer_surface.tree.node.data = &self.scene_node_data; + if (wlr_layer_surface.output.?.data == null) { + std.log.err("Wlr_output arbitrary data not assigned", .{}); + unreachable; + } + self.output = @ptrCast(@alignCast(wlr_layer_surface.output.?.data)); - self.wlr_layer_surface.events.destroy.add(&self.destroy); - self.wlr_layer_surface.surface.events.map.add(&self.map); - self.wlr_layer_surface.surface.events.unmap.add(&self.unmap); - self.wlr_layer_surface.surface.events.commit.add(&self.commit); + if (server.seat.focused_output) |output| { + self.scene_layer_surface = switch (wlr_layer_surface.current.layer) { + .background => try output.layers.background.createSceneLayerSurfaceV1(wlr_layer_surface), + .bottom => try output.layers.bottom.createSceneLayerSurfaceV1(wlr_layer_surface), + .top => try output.layers.top.createSceneLayerSurfaceV1(wlr_layer_surface), + .overlay => try output.layers.overlay.createSceneLayerSurfaceV1(wlr_layer_surface), + else => { + std.log.err("New layer surface of unidentified type", .{}); + unreachable; + }, + }; + } - return self; + self.wlr_layer_surface.surface.data = &self.scene_node_data; + self.scene_layer_surface.tree.node.data = &self.scene_node_data; + + self.wlr_layer_surface.events.destroy.add(&self.destroy); + self.wlr_layer_surface.surface.events.map.add(&self.map); + self.wlr_layer_surface.surface.events.unmap.add(&self.unmap); + self.wlr_layer_surface.surface.events.commit.add(&self.commit); + + return self; } pub fn deinit(self: *LayerSurface) void { - self.destroy.link.remove(); - self.map.link.remove(); - self.unmap.link.remove(); - self.commit.link.remove(); + self.destroy.link.remove(); + self.map.link.remove(); + self.unmap.link.remove(); + self.commit.link.remove(); - self.wlr_layer_surface.surface.data = null; + self.wlr_layer_surface.surface.data = null; - gpa.destroy(self); + gpa.destroy(self); } pub fn allowKeyboard(self: *LayerSurface) void { - const keyboard_interactive = self.wlr_layer_surface.current.keyboard_interactive; - if(keyboard_interactive == .exclusive or keyboard_interactive == .on_demand) { - server.seat.wlr_seat.keyboardNotifyEnter( - self.wlr_layer_surface.surface, - &server.seat.keyboard_group.wlr_group.keyboard.keycodes, - &server.seat.keyboard_group.wlr_group.keyboard.modifiers - ); - } + const keyboard_interactive = self.wlr_layer_surface.current.keyboard_interactive; + if (keyboard_interactive == .exclusive or keyboard_interactive == .on_demand) { + server.seat.wlr_seat.keyboardNotifyEnter(self.wlr_layer_surface.surface, &server.seat.keyboard_group.wlr_group.keyboard.keycodes, &server.seat.keyboard_group.wlr_group.keyboard.modifiers); + } } // --------- LayerSurface event handlers --------- -fn handleDestroy( - listener: *wl.Listener(*wlr.LayerSurfaceV1), - _: *wlr.LayerSurfaceV1 -) void { - const layer: *LayerSurface = @fieldParentPtr("destroy", listener); - layer.deinit(); +fn handleDestroy(listener: *wl.Listener(*wlr.LayerSurfaceV1), _: *wlr.LayerSurfaceV1) void { + const layer: *LayerSurface = @fieldParentPtr("destroy", listener); + layer.deinit(); } -fn handleMap( - listener: *wl.Listener(void) -) void { - const layer_suraface: *LayerSurface = @fieldParentPtr("map", listener); - std.log.debug("layer surface mapped", .{}); - layer_suraface.output.arrangeLayers(); - layer_suraface.allowKeyboard(); +fn handleMap(listener: *wl.Listener(void)) void { + const layer_suraface: *LayerSurface = @fieldParentPtr("map", listener); + std.log.debug("layer surface mapped", .{}); + layer_suraface.output.arrangeLayers(); + layer_suraface.allowKeyboard(); } fn handleUnmap(listener: *wl.Listener(void)) void { - const layer_surface: *LayerSurface = @fieldParentPtr("unmap", listener); + const layer_surface: *LayerSurface = @fieldParentPtr("unmap", listener); - if (server.seat.focused_surface) |fs| { - if (fs == .layer_surface and fs.layer_surface == layer_surface) { - server.seat.focusSurface(null); + if (server.seat.focused_surface) |fs| { + if (fs == .layer_surface and fs.layer_surface == layer_surface) { + server.seat.focusSurface(null); + } } - } - // FIXME: this crashes mez when killing mez - layer_surface.output.arrangeLayers(); + // FIXME: this crashes mez when killing mez + layer_surface.output.arrangeLayers(); - // TODO: Idk if this should be deiniting the layer surface entirely - layer_surface.deinit(); + // TODO: Idk if this should be deiniting the layer surface entirely + layer_surface.deinit(); } -fn handleCommit( - listener: *wl.Listener(*wlr.Surface), - _: *wlr.Surface -) void { - const layer_surface: *LayerSurface = @fieldParentPtr("commit", listener); +fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void { + const layer_surface: *LayerSurface = @fieldParentPtr("commit", listener); - if (!layer_surface.wlr_layer_surface.initial_commit) return; - layer_surface.output.arrangeLayers(); + if (!layer_surface.wlr_layer_surface.initial_commit) return; + layer_surface.output.arrangeLayers(); } diff --git a/src/Output.zig b/src/Output.zig index 166d6e7..95a9a40 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -5,10 +5,10 @@ const zwlr = @import("wayland").server.zwlr; const wlr = @import("wlroots"); const std = @import("std"); -const Utils = @import("Utils.zig"); +const Utils = @import("Utils.zig"); const Server = @import("Server.zig"); -const View = @import("View.zig"); +const View = @import("View.zig"); const LayerSurface = @import("LayerSurface.zig"); const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData; @@ -28,168 +28,167 @@ scene_node_data: SceneNodeData, scene_output: *wlr.SceneOutput, layers: struct { - background: *wlr.SceneTree, - bottom: *wlr.SceneTree, - content: *wlr.SceneTree, - top: *wlr.SceneTree, - fullscreen: *wlr.SceneTree, - overlay: *wlr.SceneTree + background: *wlr.SceneTree, + bottom: *wlr.SceneTree, + content: *wlr.SceneTree, + top: *wlr.SceneTree, + fullscreen: *wlr.SceneTree, + overlay: *wlr.SceneTree, }, layer_scene_node_data: struct { - background: SceneNodeData, - bottom: SceneNodeData, - content: SceneNodeData, - top: SceneNodeData, - fullscreen: SceneNodeData, - overlay: SceneNodeData + background: SceneNodeData, + bottom: SceneNodeData, + content: SceneNodeData, + top: SceneNodeData, + fullscreen: SceneNodeData, + overlay: SceneNodeData, }, frame: wl.Listener(*wlr.Output) = .init(handleFrame), request_state: wl.Listener(*wlr.Output.event.RequestState) = .init(handleRequestState), destroy: wl.Listener(*wlr.Output) = .init(handleDestroy), - // The wlr.Output should be destroyed by the caller on failure to trigger cleanup. pub fn init(wlr_output: *wlr.Output) ?*Output { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const self = try gpa.create(Output); + const self = try gpa.create(Output); - self.* = .{ - .focused = false, - .id = @intFromPtr(wlr_output), - .wlr_output = wlr_output, - .tree = try server.root.scene.tree.createSceneTree(), - .fullscreen = null, - .layers = .{ - .background = try self.tree.createSceneTree(), - .bottom = try self.tree.createSceneTree(), - .content = try self.tree.createSceneTree(), - .top = try self.tree.createSceneTree(), - .fullscreen = try self.tree.createSceneTree(), - .overlay = try self.tree.createSceneTree(), - }, - .layer_scene_node_data = .{ - .background = .{ .output_layer = self.layers.background }, - .bottom = .{ .output_layer = self.layers.bottom }, - .content = .{ .output_layer = self.layers.content }, - .top = .{ .output_layer = self.layers.top }, - .fullscreen = .{ .output_layer = self.layers.fullscreen }, - .overlay = .{ .output_layer = self.layers.overlay } - }, - .scene_output = try server.root.scene.createSceneOutput(wlr_output), - .scene_node_data = SceneNodeData{ .output = self }, - .state = wlr.Output.State.init() - }; + self.* = .{ + .focused = false, + .id = @intFromPtr(wlr_output), + .wlr_output = wlr_output, + .tree = try server.root.scene.tree.createSceneTree(), + .fullscreen = null, - wlr_output.events.frame.add(&self.frame); - wlr_output.events.request_state.add(&self.request_state); - wlr_output.events.destroy.add(&self.destroy); + .layers = .{ + .background = try self.tree.createSceneTree(), + .bottom = try self.tree.createSceneTree(), + .content = try self.tree.createSceneTree(), + .top = try self.tree.createSceneTree(), + .fullscreen = try self.tree.createSceneTree(), + .overlay = try self.tree.createSceneTree(), + }, - errdefer deinit(self); + .layer_scene_node_data = .{ + .background = .{ .output_layer = self.layers.background }, + .bottom = .{ .output_layer = self.layers.bottom }, + .content = .{ .output_layer = self.layers.content }, + .top = .{ .output_layer = self.layers.top }, + .fullscreen = .{ .output_layer = self.layers.fullscreen }, + .overlay = .{ .output_layer = self.layers.overlay }, + }, - if(!wlr_output.initRender(server.allocator, server.renderer)) { - std.log.err("Unable to start output {s}", .{wlr_output.name}); - return null; - } + .scene_output = try server.root.scene.createSceneOutput(wlr_output), + .scene_node_data = SceneNodeData{ .output = self }, + .state = wlr.Output.State.init() + }; - self.state.setEnabled(true); + wlr_output.events.frame.add(&self.frame); + wlr_output.events.request_state.add(&self.request_state); + wlr_output.events.destroy.add(&self.destroy); - if (wlr_output.preferredMode()) |mode| { - self.state.setMode(mode); - } + errdefer deinit(self); - if(!wlr_output.commitState(&self.state)) { - std.log.err("Unable to commit state to output {s}", .{wlr_output.name}); - return null; - } + if (!wlr_output.initRender(server.allocator, server.renderer)) { + std.log.err("Unable to start output {s}", .{wlr_output.name}); + return null; + } - // TODO: Allow user to define output positions - const layout_output = try server.root.output_layout.addAuto(self.wlr_output); - server.root.scene_output_layout.addOutput(layout_output, self.scene_output); - self.setFocused(); + self.state.setEnabled(true); - self.wlr_output.data = self; - self.tree.node.data = &self.scene_node_data; + if (wlr_output.preferredMode()) |mode| { + self.state.setMode(mode); + } - self.layers.background.node.data = &self.layer_scene_node_data.background; - self.layers.bottom.node.data = &self.layer_scene_node_data.bottom; - self.layers.content.node.data = &self.layer_scene_node_data.content; - self.layers.top.node.data = &self.layer_scene_node_data.top; - self.layers.fullscreen.node.data = &self.layer_scene_node_data.fullscreen; - self.layers.overlay.node.data = &self.layer_scene_node_data.overlay; + if (!wlr_output.commitState(&self.state)) { + std.log.err("Unable to commit state to output {s}", .{wlr_output.name}); + return null; + } - server.events.exec("OutputInitPost", .{self.id}); + // TODO: Allow user to define output positions + const layout_output = try server.root.output_layout.addAuto(self.wlr_output); + server.root.scene_output_layout.addOutput(layout_output, self.scene_output); + self.setFocused(); - return self; + self.wlr_output.data = self; + self.tree.node.data = &self.scene_node_data; + + self.layers.background.node.data = &self.layer_scene_node_data.background; + self.layers.bottom.node.data = &self.layer_scene_node_data.bottom; + self.layers.content.node.data = &self.layer_scene_node_data.content; + self.layers.top.node.data = &self.layer_scene_node_data.top; + self.layers.fullscreen.node.data = &self.layer_scene_node_data.fullscreen; + self.layers.overlay.node.data = &self.layer_scene_node_data.overlay; + + server.events.exec("OutputInitPost", .{self.id}); + + return self; } pub fn deinit(self: *Output) void { - server.events.exec("OutputDeinitPre", .{self.id}); + server.events.exec("OutputDeinitPre", .{self.id}); - self.frame.link.remove(); - self.request_state.link.remove(); - self.destroy.link.remove(); + self.frame.link.remove(); + self.request_state.link.remove(); + self.destroy.link.remove(); - self.state.finish(); + self.state.finish(); - self.wlr_output.destroy(); + self.wlr_output.destroy(); - server.events.exec("OutputDeinitPost", .{}); + server.events.exec("OutputDeinitPost", .{}); - gpa.destroy(self); + gpa.destroy(self); } pub fn setFocused(self: *Output) void { - if(server.seat.focused_output) |prev_output| { - prev_output.focused = false; - } + if (server.seat.focused_output) |prev_output| { + prev_output.focused = false; + } - server.seat.focused_output = self; - self.focused = true; + server.seat.focused_output = self; + self.focused = true; } pub fn configureLayers(self: *Output) void { - var output_box: wlr.Box = .{ - .x = 0, - .y = 0, - .width = undefined, - .height = undefined, - }; - self.wlr_output.effectiveResolution(&output_box.width, &output_box.height); - - // Should calculate usable area here for LUA view positioning - for ([_]zwlr.LayerShellV1.Layer{ .background, .bottom, .top, .overlay }) |layer| { - const tree = blk: { - const trees = [_]*wlr.SceneTree{ - self.layers.background, - self.layers.bottom, - self.layers.top, - self.layers.overlay, - }; - break :blk trees[@intCast(@intFromEnum(layer))]; + var output_box: wlr.Box = .{ + .x = 0, + .y = 0, + .width = undefined, + .height = undefined, }; + self.wlr_output.effectiveResolution(&output_box.width, &output_box.height); - var it = tree.children.iterator(.forward); - while(it.next()) |node| { - if(node.data == null) continue; + // Should calculate usable area here for LUA view positioning + for ([_]zwlr.LayerShellV1.Layer{ .background, .bottom, .top, .overlay }) |layer| { + const tree = blk: { + const trees = [_]*wlr.SceneTree{ + self.layers.background, + self.layers.bottom, + self.layers.top, + self.layers.overlay, + }; + break :blk trees[@intCast(@intFromEnum(layer))]; + }; - const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); - switch (scene_node_data.*) { - .layer_surface => { - _ = scene_node_data.layer_surface.wlr_layer_surface.configured( - @intCast(output_box.width), - @intCast(output_box.height) - ); - }, - else => { - std.log.err("Something other than a layer surface found in layer surface scene trees", .{}); - unreachable; + var it = tree.children.iterator(.forward); + while (it.next()) |node| { + if (node.data == null) continue; + + const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); + switch (scene_node_data.*) { + .layer_surface => { + _ = scene_node_data.layer_surface.wlr_layer_surface.configured(@intCast(output_box.width), @intCast(output_box.height)); + }, + else => { + std.log.err("Something other than a layer surface found in layer surface scene trees", .{}); + unreachable; + }, + } } - } } - } } const SurfaceAtResult = struct { @@ -200,165 +199,152 @@ const SurfaceAtResult = struct { }; pub fn surfaceAt(self: *Output, lx: f64, ly: f64) ?SurfaceAtResult { - var sx: f64 = undefined; - var sy: f64 = undefined; + var sx: f64 = undefined; + var sy: f64 = undefined; - const layers = [_]*wlr.SceneTree{ - self.layers.top, - self.layers.overlay, - self.layers.fullscreen, - self.layers.content, - self.layers.bottom, - self.layers.background - }; + const layers = [_]*wlr.SceneTree{ self.layers.top, self.layers.overlay, self.layers.fullscreen, self.layers.content, self.layers.bottom, self.layers.background }; - for(layers) |layer| { - const node = layer.node.at(lx, ly, &sx, &sy); - if(node == null) continue; + for (layers) |layer| { + const node = layer.node.at(lx, ly, &sx, &sy); + if (node == null) continue; - const surface: ?*wlr.Surface = blk: { - if (node.?.type == .buffer) { - const scene_buffer = wlr.SceneBuffer.fromNode(node.?); - if (wlr.SceneSurface.tryFromBuffer(scene_buffer)) |scene_surface| { - break :blk scene_surface.surface; - } - } - break :blk null; - }; - if(surface == null) continue; - - const scene_node_data: *SceneNodeData = blk: { - var n = node.?; - while (true) { - if (@as(?*SceneNodeData, @ptrCast(@alignCast(n.data)))) |snd| { - break :blk snd; - } - if (n.parent) |parent_tree| { - n = &parent_tree.node; - } else { - continue; - } - } - }; - - switch (scene_node_data.*) { - .layer_surface, .view => { - return SurfaceAtResult{ - .scene_node_data = scene_node_data, - .surface = surface.?, - .sx = sx, - .sy = sy, + const surface: ?*wlr.Surface = blk: { + if (node.?.type == .buffer) { + const scene_buffer = wlr.SceneBuffer.fromNode(node.?); + if (wlr.SceneSurface.tryFromBuffer(scene_buffer)) |scene_surface| { + break :blk scene_surface.surface; + } + } + break :blk null; }; - }, - else => continue - } - } + if (surface == null) continue; - return null; + const scene_node_data: *SceneNodeData = blk: { + var n = node.?; + while (true) { + if (@as(?*SceneNodeData, @ptrCast(@alignCast(n.data)))) |snd| { + break :blk snd; + } + if (n.parent) |parent_tree| { + n = &parent_tree.node; + } else { + continue; + } + } + }; + + switch (scene_node_data.*) { + .layer_surface, .view => { + return SurfaceAtResult{ + .scene_node_data = scene_node_data, + .surface = surface.?, + .sx = sx, + .sy = sy, + }; + }, + else => continue, + } + } + + return null; } pub fn getFullscreenedView(self: *Output) ?*View { - if(self.layers.fullscreen.children.length() != 1) { - return null; - } - - var it = self.layers.fullscreen.children.iterator(.forward); - if(it.next().?.data) |data| { - const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(data)); - if(scene_node_data.* == .view) { - return scene_node_data.view; + if (self.layers.fullscreen.children.length() != 1) { + return null; } - } - return null; + + var it = self.layers.fullscreen.children.iterator(.forward); + if (it.next().?.data) |data| { + const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(data)); + if (scene_node_data.* == .view) { + return scene_node_data.view; + } + } + return null; } // --------- WlrOutput Event Handlers --------- fn handleRequestState( - listener: *wl.Listener(*wlr.Output.event.RequestState), - event: *wlr.Output.event.RequestState, + listener: *wl.Listener(*wlr.Output.event.RequestState), + event: *wlr.Output.event.RequestState, ) void { - const output: *Output = @fieldParentPtr("request_state", listener); + const output: *Output = @fieldParentPtr("request_state", listener); - if (!output.wlr_output.commitState(event.state)) { - std.log.warn("failed to set output state {}", .{event.state}); - } + if (!output.wlr_output.commitState(event.state)) { + std.log.warn("failed to set output state {}", .{event.state}); + } - server.events.exec("OutputStateChange", .{}); + server.events.exec("OutputStateChange", .{}); } -fn handleFrame( - _: *wl.Listener(*wlr.Output), - wlr_output: *wlr.Output -) void { - const scene_output = server.root.scene.getSceneOutput(wlr_output); +fn handleFrame(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { + const scene_output = server.root.scene.getSceneOutput(wlr_output); - if(scene_output == null) { - std.log.err("Unable to get scene output to render", .{}); - return; - } + if (scene_output == null) { + std.log.err("Unable to get scene output to render", .{}); + return; + } - // std.log.info("Rendering commited scene output\n", .{}); - _ = scene_output.?.commit(null); + // std.log.info("Rendering commited scene output\n", .{}); + _ = scene_output.?.commit(null); - var now = posix.clock_gettime(posix.CLOCK.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported"); - scene_output.?.sendFrameDone(&now); + var now = posix.clock_gettime(posix.CLOCK.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported"); + scene_output.?.sendFrameDone(&now); } -fn handleDestroy( - listener: *wl.Listener(*wlr.Output), - _: *wlr.Output -) void { - std.log.debug("Handling destroy", .{}); - const output: *Output = @fieldParentPtr("destroy", listener); +fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void { + std.log.debug("Handling destroy", .{}); + const output: *Output = @fieldParentPtr("destroy", listener); - std.log.debug("removing output: {s}", .{output.wlr_output.name}); + std.log.debug("removing output: {s}", .{output.wlr_output.name}); - output.frame.link.remove(); - output.request_state.link.remove(); - output.destroy.link.remove(); + output.frame.link.remove(); + output.request_state.link.remove(); + output.destroy.link.remove(); - server.root.output_layout.remove(output.wlr_output); + server.root.output_layout.remove(output.wlr_output); - gpa.destroy(output); + gpa.destroy(output); } pub fn arrangeLayers(self: *Output) void { - var full_box: wlr.Box = .{ - .x = 0, - .y = 0, - .width = undefined, - .height = undefined, - }; - self.wlr_output.effectiveResolution(&full_box.width, &full_box.height); + var full_box: wlr.Box = .{ + .x = 0, + .y = 0, + .width = undefined, + .height = undefined, + }; + self.wlr_output.effectiveResolution(&full_box.width, &full_box.height); - inline for (@typeInfo(zwlr.LayerShellV1.Layer).@"enum".fields) |comptime_layer| { - const layer: *wlr.SceneTree = @field(self.layers, comptime_layer.name); - var it = layer.children.safeIterator(.forward); + inline for (@typeInfo(zwlr.LayerShellV1.Layer).@"enum".fields) |comptime_layer| { + const layer: *wlr.SceneTree = @field(self.layers, comptime_layer.name); + var it = layer.children.safeIterator(.forward); - while (it.next()) |node| { - if(node.data == null) continue; + while (it.next()) |node| { + if (node.data == null) continue; - // if (@as(?*SceneNodeData, @alignCast(@ptrCast(node.data)))) |node_data| { - const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); + // if (@as(?*SceneNodeData, @alignCast(@ptrCast(node.data)))) |node_data| { + const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); - const layer_surface: *LayerSurface = switch(scene_node_data.*) { - .layer_surface => @fieldParentPtr("scene_node_data", scene_node_data), - else => continue - }; + const layer_surface: *LayerSurface = switch (scene_node_data.*) { + .layer_surface => @fieldParentPtr("scene_node_data", scene_node_data), + else => continue, + }; - if (!layer_surface.wlr_layer_surface.initialized) continue; + if (!layer_surface.wlr_layer_surface.initialized) continue; - // TEST: river seems to try and prevent clients from taking an - // exclusive size greater than half the screen by killing them. Do we - // need to? Clients can do quite a bit of nasty stuff and taking - // exclusive focus isn't even that bad. + // TEST: river seems to try and prevent clients from taking an + // exclusive size greater than half the screen by killing them. Do we + // need to? Clients can do quite a bit of nasty stuff and taking + // exclusive focus isn't even that bad. - layer_surface.scene_layer_surface.configure(&full_box, &full_box); + layer_surface.scene_layer_surface.configure(&full_box, &full_box); - // TEST: are these calls useless? - // const x = layer_surface.scene_layer_surface.tree.node.x; - // const y = layer_surface.scene_layer_surface.tree.node.y; - // layer_surface.scene_layer_surface.tree.node.setPosition(x, y); + // TEST: are these calls useless? + // const x = layer_surface.scene_layer_surface.tree.node.x; + // const y = layer_surface.scene_layer_surface.tree.node.y; + // layer_surface.scene_layer_surface.tree.node.setPosition(x, y); + } } - } } diff --git a/src/Popup.zig b/src/Popup.zig index 930a2b1..4430e36 100644 --- a/src/Popup.zig +++ b/src/Popup.zig @@ -23,75 +23,75 @@ new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNe reposition: wl.Listener(void) = wl.Listener(void).init(handleReposition), pub fn init( - xdg_popup: *wlr.XdgPopup, - parent: *wlr.SceneTree, + xdg_popup: *wlr.XdgPopup, + parent: *wlr.SceneTree, ) *Popup { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const self = try gpa.create(Popup); - errdefer gpa.destroy(self); + const self = try gpa.create(Popup); + errdefer gpa.destroy(self); - self.* = .{ - .id = @intFromPtr(xdg_popup), - .xdg_popup = xdg_popup, - .tree = try parent.createSceneXdgSurface(xdg_popup.base), - }; + self.* = .{ + .id = @intFromPtr(xdg_popup), + .xdg_popup = xdg_popup, + .tree = try parent.createSceneXdgSurface(xdg_popup.base), + }; - xdg_popup.events.destroy.add(&self.destroy); - xdg_popup.base.surface.events.commit.add(&self.commit); - xdg_popup.base.events.new_popup.add(&self.new_popup); - xdg_popup.events.reposition.add(&self.reposition); + xdg_popup.events.destroy.add(&self.destroy); + xdg_popup.base.surface.events.commit.add(&self.commit); + xdg_popup.base.events.new_popup.add(&self.new_popup); + xdg_popup.events.reposition.add(&self.reposition); - return self; + return self; } fn handleDestroy(listener: *wl.Listener(void)) void { - const popup: *Popup = @fieldParentPtr("destroy", listener); + const popup: *Popup = @fieldParentPtr("destroy", listener); - popup.destroy.link.remove(); - popup.commit.link.remove(); - popup.new_popup.link.remove(); - popup.reposition.link.remove(); + popup.destroy.link.remove(); + popup.commit.link.remove(); + popup.new_popup.link.remove(); + popup.reposition.link.remove(); - gpa.destroy(popup); + gpa.destroy(popup); } fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void { - const popup: *Popup = @fieldParentPtr("commit", listener); - if (popup.xdg_popup.base.initial_commit) { - handleReposition(&popup.reposition); - } + const popup: *Popup = @fieldParentPtr("commit", listener); + if (popup.xdg_popup.base.initial_commit) { + handleReposition(&popup.reposition); + } } fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), xdg_popup: *wlr.XdgPopup) void { - const popup: *Popup = @fieldParentPtr("new_popup", listener); + const popup: *Popup = @fieldParentPtr("new_popup", listener); - _ = Popup.init(xdg_popup, popup.tree); + _ = Popup.init(xdg_popup, popup.tree); } fn handleReposition(listener: *wl.Listener(void)) void { - const popup: *Popup = @fieldParentPtr("reposition", listener); + const popup: *Popup = @fieldParentPtr("reposition", listener); - var box: wlr.Box = undefined; + var box: wlr.Box = undefined; - // TODO: figure this out to prevent popups from rendering outside of the - // current monitor - // - // if (SceneNodeData.getFromNode(&popup.tree.node)) |node| { - // const output = switch (node.data) { - // .view => |view| view.output orelse return, - // .layer_surface => |layer_surface| layer_surface.output, - // }; - // - // server.root.output_layout.getBox(output.wlr_output, &box); - // } + // TODO: figure this out to prevent popups from rendering outside of the + // current monitor + // + // if (SceneNodeData.getFromNode(&popup.tree.node)) |node| { + // const output = switch (node.data) { + // .view => |view| view.output orelse return, + // .layer_surface => |layer_surface| layer_surface.output, + // }; + // + // server.root.output_layout.getBox(output.wlr_output, &box); + // } - var root_lx: c_int = undefined; - var root_ly: c_int = undefined; - _ = popup.tree.node.coords(&root_lx, &root_ly); + var root_lx: c_int = undefined; + var root_ly: c_int = undefined; + _ = popup.tree.node.coords(&root_lx, &root_ly); - box.x -= root_lx; - box.y -= root_ly; + box.x -= root_lx; + box.y -= root_ly; - popup.xdg_popup.unconstrainFromBox(&box); + popup.xdg_popup.unconstrainFromBox(&box); } diff --git a/src/RemoteLua.zig b/src/RemoteLua.zig index 93d0e04..772e5cb 100644 --- a/src/RemoteLua.zig +++ b/src/RemoteLua.zig @@ -17,90 +17,92 @@ remote_lua_v1: *mez.RemoteLuaV1, L: *zlua.Lua, pub fn sendNewLogEntry(str: [*:0]const u8) void { - var node = server.remote_lua_clients.first; - while (node) |n| { - const data: ?*RemoteLua = @fieldParentPtr("node", n); - if (data) |d| d.remote_lua_v1.sendNewLogEntry(str); - node = n.next; - } + var node = server.remote_lua_clients.first; + while (node) |n| { + const data: ?*RemoteLua = @fieldParentPtr("node", n); + if (data) |d| d.remote_lua_v1.sendNewLogEntry(str); + node = n.next; + } } pub fn create(client: *wl.Client, version: u32, id: u32) !void { - const remote_lua_v1 = try mez.RemoteLuaV1.create(client, version, id); + const remote_lua_v1 = try mez.RemoteLuaV1.create(client, version, id); - const node = try gpa.create(RemoteLua); - errdefer gpa.destroy(node); - node.* = .{ - .remote_lua_v1 = remote_lua_v1, - .node = .{}, - .L = try zlua.Lua.init(gpa), - }; - errdefer node.L.deinit(); - node.L.openLibs(); - Lua.openLibs(node.L); - Lua.loadRuntimeDir(node.L) catch |err| if (err == error.LuaRuntime) { - std.log.warn("{s}", .{try node.L.toString(-1)}); - }; - // TODO: replace stdout and stderr with buffers we can send to the clients + const node = try gpa.create(RemoteLua); + errdefer gpa.destroy(node); + node.* = .{ + .remote_lua_v1 = remote_lua_v1, + .node = .{}, + .L = try zlua.Lua.init(gpa), + }; + errdefer node.L.deinit(); + node.L.openLibs(); + Lua.openLibs(node.L); + Lua.loadRuntimeDir(node.L) catch |err| if (err == error.LuaRuntime) { + std.log.warn("{s}", .{try node.L.toString(-1)}); + }; + // TODO: replace stdout and stderr with buffers we can send to the clients - server.remote_lua_clients.prepend(&node.node); + server.remote_lua_clients.prepend(&node.node); - remote_lua_v1.setHandler(*RemoteLua, handleRequest, handleDestroy, node); + remote_lua_v1.setHandler(*RemoteLua, handleRequest, handleDestroy, node); } fn handleRequest( -remote_lua_v1: *mez.RemoteLuaV1, -request: mez.RemoteLuaV1.Request, -remote: *RemoteLua, + remote_lua_v1: *mez.RemoteLuaV1, + request: mez.RemoteLuaV1.Request, + remote: *RemoteLua, ) void { - const L = remote.L; - switch (request) { - .destroy => remote_lua_v1.destroy(), - .push_lua => |req| { - const chunk: [:0]const u8 = std.mem.sliceTo(req.lua_chunk, 0); + const L = remote.L; + switch (request) { + .destroy => remote_lua_v1.destroy(), + .push_lua => |req| { + const chunk: [:0]const u8 = std.mem.sliceTo(req.lua_chunk, 0); - const str = std.mem.concatWithSentinel(gpa, u8, &[_][]const u8{ - "return ", - chunk, - ";", - }, 0) catch return catchLuaFail(remote); - defer gpa.free(str); + const str = std.mem.concatWithSentinel(gpa, u8, &[_][]const u8{ + "return ", + chunk, + ";", + }, 0) catch return catchLuaFail(remote); + defer gpa.free(str); - zlua.Lua.loadBuffer(L, str, "=repl") catch { - L.pop(L.getTop()); - L.loadString(chunk) catch { - catchLuaFail(remote); - L.pop(-1); - }; - return; - }; + zlua.Lua.loadBuffer(L, str, "=repl") catch { + L.pop(L.getTop()); + L.loadString(chunk) catch { + catchLuaFail(remote); + L.pop(-1); + }; + return; + }; - L.protectedCall(.{ .results = zlua.mult_return, }) catch { - catchLuaFail(remote); - L.pop(1); - }; + L.protectedCall(.{ + .results = zlua.mult_return, + }) catch { + catchLuaFail(remote); + L.pop(1); + }; - var i: i32 = 1; - const nresults = L.getTop(); - while (i <= nresults) : (i += 1) { - sendNewLogEntry(LuaUtils.toStringEx(L)); - L.pop(-1); - } - }, - } + var i: i32 = 1; + const nresults = L.getTop(); + while (i <= nresults) : (i += 1) { + sendNewLogEntry(LuaUtils.toStringEx(L)); + L.pop(-1); + } + }, + } } fn handleDestroy(_: *mez.RemoteLuaV1, remote_lua: *RemoteLua) void { - if (remote_lua.node.prev) |p| { - if (remote_lua.node.next) |n| n.prev.? = p; - p.next = remote_lua.node.next; - } else server.remote_lua_clients.first = remote_lua.node.next; + if (remote_lua.node.prev) |p| { + if (remote_lua.node.next) |n| n.prev.? = p; + p.next = remote_lua.node.next; + } else server.remote_lua_clients.first = remote_lua.node.next; - remote_lua.L.deinit(); - gpa.destroy(remote_lua); + remote_lua.L.deinit(); + gpa.destroy(remote_lua); } fn catchLuaFail(remote: *RemoteLua) void { - const err: [:0]const u8 = LuaUtils.toStringEx(remote.L); - sendNewLogEntry(std.mem.sliceTo(err, 0)); + const err: [:0]const u8 = LuaUtils.toStringEx(remote.L); + sendNewLogEntry(std.mem.sliceTo(err, 0)); } diff --git a/src/RemoteLuaManager.zig b/src/RemoteLuaManager.zig index b7f6198..2a748a0 100644 --- a/src/RemoteLuaManager.zig +++ b/src/RemoteLuaManager.zig @@ -13,37 +13,37 @@ const server = &@import("main.zig").server; global: *wl.Global, pub fn init() !?*RemoteLuaManager { - const self = try gpa.create(RemoteLuaManager); + const self = try gpa.create(RemoteLuaManager); - self.global = try wl.Global.create(server.wl_server, mez.RemoteLuaManagerV1, 1, ?*anyopaque, null, bind); + self.global = try wl.Global.create(server.wl_server, mez.RemoteLuaManagerV1, 1, ?*anyopaque, null, bind); - return self; + return self; } fn bind(client: *wl.Client, _: ?*anyopaque, version: u32, id: u32) void { - const remote_lua_manager_v1 = mez.RemoteLuaManagerV1.create(client, version, id) catch { - client.postNoMemory(); - Utils.oomPanic(); - }; - remote_lua_manager_v1.setHandler(?*anyopaque, handleRequest, null, null); + const remote_lua_manager_v1 = mez.RemoteLuaManagerV1.create(client, version, id) catch { + client.postNoMemory(); + Utils.oomPanic(); + }; + remote_lua_manager_v1.setHandler(?*anyopaque, handleRequest, null, null); } fn handleRequest( -remote_lua_manager_v1: *mez.RemoteLuaManagerV1, -request: mez.RemoteLuaManagerV1.Request, -_: ?*anyopaque, + remote_lua_manager_v1: *mez.RemoteLuaManagerV1, + request: mez.RemoteLuaManagerV1.Request, + _: ?*anyopaque, ) void { - switch (request) { - .destroy => remote_lua_manager_v1.destroy(), - .get_remote => |req| { - RemoteLua.create( - remote_lua_manager_v1.getClient(), - remote_lua_manager_v1.getVersion(), - req.id, - ) catch { - remote_lua_manager_v1.getClient().postNoMemory(); - Utils.oomPanic(); - }; - }, - } + switch (request) { + .destroy => remote_lua_manager_v1.destroy(), + .get_remote => |req| { + RemoteLua.create( + remote_lua_manager_v1.getClient(), + remote_lua_manager_v1.getVersion(), + req.id, + ) catch { + remote_lua_manager_v1.getClient().postNoMemory(); + Utils.oomPanic(); + }; + }, + } } diff --git a/src/Root.zig b/src/Root.zig index 65894cb..3582c15 100644 --- a/src/Root.zig +++ b/src/Root.zig @@ -1,5 +1,4 @@ /// The root of Mezzaluna is, you guessed it, the root of many of the systems mez needs: - const Root = @This(); const std = @import("std"); @@ -26,92 +25,92 @@ scene_output_layout: *wlr.SceneOutputLayout, output_layout: *wlr.OutputLayout, pub fn init(self: *Root) void { - std.log.info("Creating root of mezzaluna\n", .{}); + std.log.info("Creating root of mezzaluna\n", .{}); - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const output_layout = try wlr.OutputLayout.create(server.wl_server); - errdefer output_layout.destroy(); + const output_layout = try wlr.OutputLayout.create(server.wl_server); + errdefer output_layout.destroy(); - const scene = try wlr.Scene.create(); - errdefer scene.tree.node.destroy(); + const scene = try wlr.Scene.create(); + errdefer scene.tree.node.destroy(); - self.* = .{ - .scene = scene, - .scene_node_data = .{ .root = self }, - .output_layout = output_layout, - .xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(server.wl_server), - .scene_output_layout = try scene.attachOutputLayout(output_layout), - }; + self.* = .{ + .scene = scene, + .scene_node_data = .{ .root = self }, + .output_layout = output_layout, + .xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(server.wl_server), + .scene_output_layout = try scene.attachOutputLayout(output_layout), + }; - self.scene.tree.node.data = &self.scene_node_data; + self.scene.tree.node.data = &self.scene_node_data; } pub fn deinit(self: *Root) void { - var it = self.scene.tree.children.iterator(.forward); + var it = self.scene.tree.children.iterator(.forward); - while(it.next()) |node| { - if(node.data == null) continue; + while (it.next()) |node| { + if (node.data == null) continue; - const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); - switch(scene_node_data.*) { - .output => { - scene_node_data.output.deinit(); - }, - else => { - std.log.debug("The root has a child that is not an output", .{}); - unreachable; - } + const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); + switch (scene_node_data.*) { + .output => { + scene_node_data.output.deinit(); + }, + else => { + std.log.debug("The root has a child that is not an output", .{}); + unreachable; + }, + } } - } - self.output_layout.destroy(); - self.scene.tree.node.destroy(); + self.output_layout.destroy(); + self.scene.tree.node.destroy(); } // Search output_layout's ouputs, and each outputs views pub fn viewById(self: *Root, id: u64) ?*View { - var output_it = self.output_layout.outputs.iterator(.forward); + var output_it = self.output_layout.outputs.iterator(.forward); - while(output_it.next()) |o| { - if(o.output.data == null) { - std.log.err("Wlr_output arbitrary data not assigned", .{}); - unreachable; + while (output_it.next()) |o| { + if (o.output.data == null) { + std.log.err("Wlr_output arbitrary data not assigned", .{}); + unreachable; + } + + const output: *Output = @ptrCast(@alignCast(o.output.data.?)); + var node_it = output.layers.content.children.iterator(.forward); + + while (node_it.next()) |node| { + if (node.data == null) continue; + + const view_snd: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); + + // TODO: Should we assert that we want only views to be here + // -- Basically should we use switch statements for snd interactions + // -- Or if statements, for simplicity + if (view_snd.* == .view and view_snd.view.id == id) { + return view_snd.view; + } + } + + if (output.fullscreen) |fullscreen| { + if (fullscreen.id == id) return fullscreen; + } } - const output: *Output = @ptrCast(@alignCast(o.output.data.?)); - var node_it = output.layers.content.children.iterator(.forward); - - while(node_it.next()) |node| { - if(node.data == null) continue; - - const view_snd: *SceneNodeData = @ptrCast(@alignCast(node.data.?)); - - // TODO: Should we assert that we want only views to be here - // -- Basically should we use switch statements for snd interactions - // -- Or if statements, for simplicity - if(view_snd.* == .view and view_snd.view.id == id) { - return view_snd.view; - } - } - - if(output.fullscreen) |fullscreen| { - if(fullscreen.id == id) return fullscreen; - } - } - - return null; + return null; } pub fn outputById(self: *Root, id: u64) ?*Output { - var it = self.scene.outputs.iterator(.forward); + var it = self.scene.outputs.iterator(.forward); - while(it.next()) |scene_output| { - if(scene_output.output.data == null) continue; + while (it.next()) |scene_output| { + if (scene_output.output.data == null) continue; - const output: *Output = @as(*Output, @ptrCast(@alignCast(scene_output.output.data.?))); - if(output.id == id) return output; - } + const output: *Output = @as(*Output, @ptrCast(@alignCast(scene_output.output.data.?))); + if (output.id == id) return output; + } - return null; + return null; } diff --git a/src/SceneNodeData.zig b/src/SceneNodeData.zig index d63607e..9067bfb 100644 --- a/src/SceneNodeData.zig +++ b/src/SceneNodeData.zig @@ -5,10 +5,4 @@ const LayerSurface = @import("LayerSurface.zig"); const Output = @import("Output.zig"); const Root = @import("Root.zig"); -pub const SceneNodeData = union(enum) { - view: *View, - layer_surface: *LayerSurface, - output: *Output, - output_layer: *wlr.SceneTree, - root: *Root -}; +pub const SceneNodeData = union(enum) { view: *View, layer_surface: *LayerSurface, output: *Output, output_layer: *wlr.SceneTree, root: *Root }; diff --git a/src/Seat.zig b/src/Seat.zig index 99bb1a8..1e62bfd 100644 --- a/src/Seat.zig +++ b/src/Seat.zig @@ -6,24 +6,24 @@ const wl = @import("wayland").server.wl; const xkb = @import("xkbcommon"); const KeyboardGroup = @import("KeyboardGroup.zig"); -const Utils = @import("Utils.zig"); +const Utils = @import("Utils.zig"); const Popup = @import("Popup.zig"); -const View = @import("View.zig"); +const View = @import("View.zig"); const LayerSurface = @import("LayerSurface.zig"); const Output = @import("Output.zig"); const server = &@import("main.zig").server; pub const FocusData = union(enum) { - view: *View, - layer_surface: *LayerSurface, + view: *View, + layer_surface: *LayerSurface, - pub fn getSurface(self: FocusData) *wlr.Surface { - return switch (self) { - .view => |*v| v.*.xdg_toplevel.base.surface, - .layer_surface => |*ls| ls.*.wlr_layer_surface.surface, - }; - } + pub fn getSurface(self: FocusData) *wlr.Surface { + return switch (self) { + .view => |*v| v.*.xdg_toplevel.base.surface, + .layer_surface => |*ls| ls.*.wlr_layer_surface.surface, + }; + } }; wlr_seat: *wlr.Seat, @@ -40,144 +40,139 @@ request_set_primary_selection: wl.Listener(*wlr.Seat.event.RequestSetPrimarySele // request_start_drage pub fn init(self: *Seat) void { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const xkb_context = xkb.Context.new(.no_flags) orelse { - std.log.err("Unable to create a xkb context, exiting", .{}); - std.process.exit(7); - }; - defer xkb_context.unref(); + const xkb_context = xkb.Context.new(.no_flags) orelse { + std.log.err("Unable to create a xkb context, exiting", .{}); + std.process.exit(7); + }; + defer xkb_context.unref(); - const keymap = xkb.Keymap.newFromNames(xkb_context, null, .no_flags) orelse { - std.log.err("Unable to create a xkb keymap, exiting", .{}); - std.process.exit(8); - }; - defer keymap.unref(); + const keymap = xkb.Keymap.newFromNames(xkb_context, null, .no_flags) orelse { + std.log.err("Unable to create a xkb keymap, exiting", .{}); + std.process.exit(8); + }; + defer keymap.unref(); - self.* = .{ - .wlr_seat = try wlr.Seat.create(server.wl_server, "default"), - .focused_surface = null, - .focused_output = null, - .keyboard_group = .init(), - .keymap = keymap.ref(), - }; - errdefer { - self.keyboard_group.deinit(); - self.wlr_seat.destroy(); - } + self.* = .{ + .wlr_seat = try wlr.Seat.create(server.wl_server, "default"), + .focused_surface = null, + .focused_output = null, + .keyboard_group = .init(), + .keymap = keymap.ref(), + }; + errdefer { + self.keyboard_group.deinit(); + self.wlr_seat.destroy(); + } - _ = self.keyboard_group.wlr_group.keyboard.setKeymap(self.keymap); - self.wlr_seat.setKeyboard(&self.keyboard_group.wlr_group.keyboard); + _ = self.keyboard_group.wlr_group.keyboard.setKeymap(self.keymap); + self.wlr_seat.setKeyboard(&self.keyboard_group.wlr_group.keyboard); - self.wlr_seat.events.request_set_cursor.add(&self.request_set_cursor); - self.wlr_seat.events.request_set_selection.add(&self.request_set_selection); - self.wlr_seat.events.request_set_primary_selection.add(&self.request_set_primary_selection); + self.wlr_seat.events.request_set_cursor.add(&self.request_set_cursor); + self.wlr_seat.events.request_set_selection.add(&self.request_set_selection); + self.wlr_seat.events.request_set_primary_selection.add(&self.request_set_primary_selection); } pub fn deinit(self: *Seat) void { - self.request_set_cursor.link.remove(); - self.request_set_selection.link.remove(); - self.request_set_primary_selection.link.remove(); + self.request_set_cursor.link.remove(); + self.request_set_selection.link.remove(); + self.request_set_primary_selection.link.remove(); - self.keyboard_group.deinit(); - self.wlr_seat.destroy(); + self.keyboard_group.deinit(); + self.wlr_seat.destroy(); } pub fn focusSurface(self: *Seat, to_focus: ?FocusData) void { - const surface: ?*wlr.Surface = blk: { - if (to_focus != null) { - break :blk to_focus.?.getSurface(); - } else { - break :blk null; - } - }; + const surface: ?*wlr.Surface = blk: { + if (to_focus != null) { + break :blk to_focus.?.getSurface(); + } else { + break :blk null; + } + }; - // Remove focus from the current surface unless: - // - current and to focus are the same surface - // - current layer has exclusive keyboard interactivity - // - current is fullscreen and to focus is content - // - current is fullscreen and layer is bottom or background - if (self.focused_surface) |current_focus| { - const current_surface = current_focus.getSurface(); - if (current_surface == surface) return; // Same surface + // Remove focus from the current surface unless: + // - current and to focus are the same surface + // - current layer has exclusive keyboard interactivity + // - current is fullscreen and to focus is content + // - current is fullscreen and layer is bottom or background + if (self.focused_surface) |current_focus| { + const current_surface = current_focus.getSurface(); + if (current_surface == surface) return; // Same surface - if(to_focus != null) { - switch (current_focus) { - .layer_surface => |*current_layer_surface| { - if(current_layer_surface.*.wlr_layer_surface.current.keyboard_interactive == .exclusive) return; - }, - .view => |*current_view| { - if(current_view.*.fullscreen) { - switch (to_focus.?) { - .layer_surface => |*layer_surface| { - const layer = layer_surface.*.wlr_layer_surface.current.layer; - if(layer == .background or layer == .bottom) return; - }, - .view => |*view| { - if(!view.*.fullscreen) return; - } + if (to_focus != null) { + switch (current_focus) { + .layer_surface => |*current_layer_surface| { + if (current_layer_surface.*.wlr_layer_surface.current.keyboard_interactive == .exclusive) return; + }, + .view => |*current_view| { + if (current_view.*.fullscreen) { + switch (to_focus.?) { + .layer_surface => |*layer_surface| { + const layer = layer_surface.*.wlr_layer_surface.current.layer; + if (layer == .background or layer == .bottom) return; + }, + .view => |*view| { + if (!view.*.fullscreen) return; + }, + } + } + }, } - } + } else if (current_focus == .view and current_focus.view.fullscreen) { + return; } - } - } else if(current_focus == .view and current_focus.view.fullscreen){ - return; - } - // Clear the focus if applicable - switch (current_focus) { - .layer_surface => {}, // IDK if we actually have to clear any focus here - else => { - if(wlr.XdgSurface.tryFromWlrSurface(current_surface)) |xdg_surface| { - _ = xdg_surface.role_data.toplevel.?.setActivated(false); + // Clear the focus if applicable + switch (current_focus) { + .layer_surface => {}, // IDK if we actually have to clear any focus here + else => { + if (wlr.XdgSurface.tryFromWlrSurface(current_surface)) |xdg_surface| { + _ = xdg_surface.role_data.toplevel.?.setActivated(false); + } + }, } - } } - } - - if(to_focus != null) { - server.seat.wlr_seat.keyboardNotifyEnter( - surface.?, - &server.seat.keyboard_group.wlr_group.keyboard.keycodes, - &server.seat.keyboard_group.wlr_group.keyboard.modifiers - ); - if(to_focus.? != .layer_surface) { - if(to_focus.? == .view) to_focus.?.view.focused = true; - if(wlr.XdgSurface.tryFromWlrSurface(surface.?)) |xdg_surface| { - _ = xdg_surface.role_data.toplevel.?.setActivated(true); - } + if (to_focus != null) { + server.seat.wlr_seat.keyboardNotifyEnter(surface.?, &server.seat.keyboard_group.wlr_group.keyboard.keycodes, &server.seat.keyboard_group.wlr_group.keyboard.modifiers); + if (to_focus.? != .layer_surface) { + if (to_focus.? == .view) to_focus.?.view.focused = true; + if (wlr.XdgSurface.tryFromWlrSurface(surface.?)) |xdg_surface| { + _ = xdg_surface.role_data.toplevel.?.setActivated(true); + } + } } - } - self.focused_surface = to_focus; + self.focused_surface = to_focus; } pub fn focusOutput(self: *Seat, output: *Output) void { - if(server.seat.focused_output) |prev_output| { - prev_output.focused = false; - } + if (server.seat.focused_output) |prev_output| { + prev_output.focused = false; + } - self.focused_output = output; + self.focused_output = output; } fn handleRequestSetCursor( - _: *wl.Listener(*wlr.Seat.event.RequestSetCursor), - event: *wlr.Seat.event.RequestSetCursor, + _: *wl.Listener(*wlr.Seat.event.RequestSetCursor), + event: *wlr.Seat.event.RequestSetCursor, ) void { - if (event.seat_client == server.seat.wlr_seat.pointer_state.focused_client) - server.cursor.wlr_cursor.setSurface(event.surface, event.hotspot_x, event.hotspot_y); + if (event.seat_client == server.seat.wlr_seat.pointer_state.focused_client) + server.cursor.wlr_cursor.setSurface(event.surface, event.hotspot_x, event.hotspot_y); } fn handleRequestSetSelection( - _: *wl.Listener(*wlr.Seat.event.RequestSetSelection), - event: *wlr.Seat.event.RequestSetSelection, + _: *wl.Listener(*wlr.Seat.event.RequestSetSelection), + event: *wlr.Seat.event.RequestSetSelection, ) void { - server.seat.wlr_seat.setSelection(event.source, event.serial); + server.seat.wlr_seat.setSelection(event.source, event.serial); } fn handleRequestSetPrimarySelection( - _: *wl.Listener(*wlr.Seat.event.RequestSetPrimarySelection), - event: *wlr.Seat.event.RequestSetPrimarySelection, + _: *wl.Listener(*wlr.Seat.event.RequestSetPrimarySelection), + event: *wlr.Seat.event.RequestSetPrimarySelection, ) void { - server.seat.wlr_seat.setPrimarySelection(event.source, event.serial); + server.seat.wlr_seat.setPrimarySelection(event.source, event.serial); } diff --git a/src/Server.zig b/src/Server.zig index 2009561..b9e944e 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -4,22 +4,22 @@ const std = @import("std"); const wl = @import("wayland").server.wl; const wlr = @import("wlroots"); -const Root = @import("Root.zig"); -const Seat = @import("Seat.zig"); -const Cursor = @import("Cursor.zig"); -const Keyboard = @import("Keyboard.zig"); -const LayerSurface = @import("LayerSurface.zig"); -const Output = @import("Output.zig"); -const View = @import("View.zig"); -const Keymap = @import("types/Keymap.zig"); -const Mousemap = @import("types/Mousemap.zig"); -const Hook = @import("types/Hook.zig"); -const Events = @import("types/Events.zig"); -const Popup = @import("Popup.zig"); -const RemoteLua = @import("RemoteLua.zig"); +const Root = @import("Root.zig"); +const Seat = @import("Seat.zig"); +const Cursor = @import("Cursor.zig"); +const Keyboard = @import("Keyboard.zig"); +const LayerSurface = @import("LayerSurface.zig"); +const Output = @import("Output.zig"); +const View = @import("View.zig"); +const Keymap = @import("types/Keymap.zig"); +const Mousemap = @import("types/Mousemap.zig"); +const Hook = @import("types/Hook.zig"); +const Events = @import("types/Events.zig"); +const Popup = @import("Popup.zig"); +const RemoteLua = @import("RemoteLua.zig"); const RemoteLuaManager = @import("RemoteLuaManager.zig"); -const Utils = @import("Utils.zig"); -const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData; +const Utils = @import("Utils.zig"); +const SceneNodeData = @import("SceneNodeData.zig").SceneNodeData; const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; @@ -62,195 +62,177 @@ new_layer_surface: wl.Listener(*wlr.LayerSurfaceV1) = .init(handleNewLayerSurfac request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) = .init(handleRequestActivate), pub fn init(self: *Server) void { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const wl_server = wl.Server.create() catch { - std.log.err("Server create failed, exiting with 2", .{}); - std.process.exit(2); - }; + const wl_server = wl.Server.create() catch { + std.log.err("Server create failed, exiting with 2", .{}); + std.process.exit(2); + }; - const event_loop = wl_server.getEventLoop(); + const event_loop = wl_server.getEventLoop(); - var session: ?*wlr.Session = undefined; - const backend = wlr.Backend.autocreate(event_loop, &session) catch { - std.log.err("Backend create failed, exiting with 3", .{}); - std.process.exit(3); - }; + var session: ?*wlr.Session = undefined; + const backend = wlr.Backend.autocreate(event_loop, &session) catch { + std.log.err("Backend create failed, exiting with 3", .{}); + std.process.exit(3); + }; - const renderer = wlr.Renderer.autocreate(backend) catch { - std.log.err("Renderer create failed, exiting with 4", .{}); - std.process.exit(4); - }; + const renderer = wlr.Renderer.autocreate(backend) catch { + std.log.err("Renderer create failed, exiting with 4", .{}); + std.process.exit(4); + }; - self.* = .{ - .wl_server = wl_server, - .backend = backend, - .renderer = renderer, - .allocator = wlr.Allocator.autocreate(backend, renderer) catch { - std.log.err("Allocator create failed, exiting with 5", .{}); - std.process.exit(5); - }, - .xdg_shell = try wlr.XdgShell.create(wl_server, 2), - .layer_shell = try wlr.LayerShellV1.create(wl_server, 4), - .xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(self.wl_server), - .xdg_activation = try wlr.XdgActivationV1.create(self.wl_server), - .event_loop = event_loop, - .session = session, - .compositor = try wlr.Compositor.create(wl_server, 6, renderer), - .shm = try wlr.Shm.createWithRenderer(wl_server, 1, renderer), - // TODO: let the user configure a cursor theme and side lua - .root = undefined, - .seat = undefined, - .cursor = undefined, - .remote_lua_manager = RemoteLuaManager.init() catch Utils.oomPanic(), - .keymaps = .init(gpa), - .mousemaps = .init(gpa), - .hooks = .init(gpa), - .events = try .init(gpa), - .remote_lua_clients = .{}, - }; + self.* = .{ + .wl_server = wl_server, + .backend = backend, + .renderer = renderer, + .allocator = wlr.Allocator.autocreate(backend, renderer) catch { + std.log.err("Allocator create failed, exiting with 5", .{}); + std.process.exit(5); + }, + .xdg_shell = try wlr.XdgShell.create(wl_server, 2), + .layer_shell = try wlr.LayerShellV1.create(wl_server, 4), + .xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(self.wl_server), + .xdg_activation = try wlr.XdgActivationV1.create(self.wl_server), + .event_loop = event_loop, + .session = session, + .compositor = try wlr.Compositor.create(wl_server, 6, renderer), + .shm = try wlr.Shm.createWithRenderer(wl_server, 1, renderer), + // TODO: let the user configure a cursor theme and side lua + .root = undefined, + .seat = undefined, + .cursor = undefined, + .remote_lua_manager = RemoteLuaManager.init() catch Utils.oomPanic(), + .keymaps = .init(gpa), + .mousemaps = .init(gpa), + .hooks = .init(gpa), + .events = try .init(gpa), + .remote_lua_clients = .{}, + }; - self.renderer.initServer(wl_server) catch { - std.log.err("Renderer init failed, exiting with 6", .{}); - std.process.exit(6); - }; + self.renderer.initServer(wl_server) catch { + std.log.err("Renderer init failed, exiting with 6", .{}); + std.process.exit(6); + }; - self.root.init(); - self.seat.init(); - self.cursor.init(); + self.root.init(); + self.seat.init(); + self.cursor.init(); - _ = try wlr.Subcompositor.create(self.wl_server); - _ = try wlr.DataDeviceManager.create(self.wl_server); - _ = try wlr.ExportDmabufManagerV1.create(self.wl_server); - _ = try wlr.Viewporter.create(self.wl_server); - _ = try wlr.Presentation.create(self.wl_server, self.backend, 2); - _ = try wlr.ScreencopyManagerV1.create(self.wl_server); - _ = try wlr.AlphaModifierV1.create(self.wl_server); - _ = try wlr.DataControlManagerV1.create(self.wl_server); - _ = try wlr.PrimarySelectionDeviceManagerV1.create(self.wl_server); - _ = try wlr.SinglePixelBufferManagerV1.create(self.wl_server); - _ = try wlr.FractionalScaleManagerV1.create(self.wl_server, 1); - _ = try wlr.XdgOutputManagerV1.create(self.wl_server, self.root.output_layout); - self.root.scene.setGammaControlManagerV1(try wlr.GammaControlManagerV1.create(self.wl_server)); + _ = try wlr.Subcompositor.create(self.wl_server); + _ = try wlr.DataDeviceManager.create(self.wl_server); + _ = try wlr.ExportDmabufManagerV1.create(self.wl_server); + _ = try wlr.Viewporter.create(self.wl_server); + _ = try wlr.Presentation.create(self.wl_server, self.backend, 2); + _ = try wlr.ScreencopyManagerV1.create(self.wl_server); + _ = try wlr.AlphaModifierV1.create(self.wl_server); + _ = try wlr.DataControlManagerV1.create(self.wl_server); + _ = try wlr.PrimarySelectionDeviceManagerV1.create(self.wl_server); + _ = try wlr.SinglePixelBufferManagerV1.create(self.wl_server); + _ = try wlr.FractionalScaleManagerV1.create(self.wl_server, 1); + _ = try wlr.XdgOutputManagerV1.create(self.wl_server, self.root.output_layout); + self.root.scene.setGammaControlManagerV1(try wlr.GammaControlManagerV1.create(self.wl_server)); - // Add event listeners to events - self.backend.events.new_input.add(&self.new_input); - self.backend.events.new_output.add(&self.new_output); - self.xdg_shell.events.new_toplevel.add(&self.new_xdg_toplevel); - self.xdg_shell.events.new_popup.add(&self.new_xdg_popup); - self.xdg_toplevel_decoration_manager.events.new_toplevel_decoration.add(&self.new_xdg_toplevel_decoration); - self.layer_shell.events.new_surface.add(&self.new_layer_surface); - self.xdg_activation.events.request_activate.add(&self.request_activate); + // Add event listeners to events + self.backend.events.new_input.add(&self.new_input); + self.backend.events.new_output.add(&self.new_output); + self.xdg_shell.events.new_toplevel.add(&self.new_xdg_toplevel); + self.xdg_shell.events.new_popup.add(&self.new_xdg_popup); + self.xdg_toplevel_decoration_manager.events.new_toplevel_decoration.add(&self.new_xdg_toplevel_decoration); + self.layer_shell.events.new_surface.add(&self.new_layer_surface); + self.xdg_activation.events.request_activate.add(&self.request_activate); - self.events.exec("ServerStartPost", .{}); + self.events.exec("ServerStartPost", .{}); } pub fn deinit(self: *Server) noreturn { - self.new_input.link.remove(); - self.new_output.link.remove(); - self.new_xdg_toplevel.link.remove(); - self.new_xdg_popup.link.remove(); - self.new_xdg_toplevel_decoration.link.remove(); - self.new_layer_surface.link.remove(); + self.new_input.link.remove(); + self.new_output.link.remove(); + self.new_xdg_toplevel.link.remove(); + self.new_xdg_popup.link.remove(); + self.new_xdg_toplevel_decoration.link.remove(); + self.new_layer_surface.link.remove(); - self.seat.deinit(); - self.root.deinit(); - self.cursor.deinit(); + self.seat.deinit(); + self.root.deinit(); + self.cursor.deinit(); - self.backend.destroy(); + self.backend.destroy(); - self.wl_server.destroyClients(); - self.wl_server.destroy(); + self.wl_server.destroyClients(); + self.wl_server.destroy(); - std.log.debug("Exiting mez succesfully", .{}); - std.process.exit(0); + std.log.debug("Exiting mez succesfully", .{}); + std.process.exit(0); } // --------- Backend event handlers --------- -fn handleNewInput( - _: *wl.Listener(*wlr.InputDevice), - device: *wlr.InputDevice -) void { - switch (device.type) { - .keyboard => _ = Keyboard.init(device), - .pointer => server.cursor.wlr_cursor.attachInputDevice(device), - else => { - std.log.err( - "New input request for input that is not a keyboard or pointer: {s}", - .{device.name orelse "(null)"} - ); - }, - } +fn handleNewInput(_: *wl.Listener(*wlr.InputDevice), device: *wlr.InputDevice) void { + switch (device.type) { + .keyboard => _ = Keyboard.init(device), + .pointer => server.cursor.wlr_cursor.attachInputDevice(device), + else => { + std.log.err("New input request for input that is not a keyboard or pointer: {s}", .{device.name orelse "(null)"}); + }, + } - // We should really only set true capabilities - server.seat.wlr_seat.setCapabilities(.{ - .pointer = true, - .keyboard = true, - }); + // We should really only set true capabilities + server.seat.wlr_seat.setCapabilities(.{ + .pointer = true, + .keyboard = true, + }); } -fn handleNewOutput( - _: *wl.Listener(*wlr.Output), - wlr_output: *wlr.Output -) void { - _ = Output.init(wlr_output); +fn handleNewOutput(_: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { + _ = Output.init(wlr_output); } -fn handleNewXdgToplevel( - _: *wl.Listener(*wlr.XdgToplevel), - xdg_toplevel: *wlr.XdgToplevel -) void { - _ = View.init(xdg_toplevel); +fn handleNewXdgToplevel(_: *wl.Listener(*wlr.XdgToplevel), xdg_toplevel: *wlr.XdgToplevel) void { + _ = View.init(xdg_toplevel); } -fn handleNewXdgToplevelDecoration( - _: *wl.Listener(*wlr.XdgToplevelDecorationV1), - decoration: *wlr.XdgToplevelDecorationV1 -) void { - if(server.root.viewById(@intFromPtr(decoration.toplevel))) |view| { - view.xdg_toplevel_decoration = decoration; - } +fn handleNewXdgToplevelDecoration(_: *wl.Listener(*wlr.XdgToplevelDecorationV1), decoration: *wlr.XdgToplevelDecorationV1) void { + if (server.root.viewById(@intFromPtr(decoration.toplevel))) |view| { + view.xdg_toplevel_decoration = decoration; + } } fn handleNewXdgPopup(_: *wl.Listener(*wlr.XdgPopup), _: *wlr.XdgPopup) void { - std.log.debug("Unimplemented Server.handleNewXdgPopup\n", .{}); + std.log.debug("Unimplemented Server.handleNewXdgPopup\n", .{}); } -fn handleNewLayerSurface( - _: *wl.Listener(*wlr.LayerSurfaceV1), - layer_surface: *wlr.LayerSurfaceV1 -) void { - std.log.debug("requested layer shell\n", .{}); - if (layer_surface.output == null) { - if (server.seat.focused_output == null) { - std.log.err("No output available for new layer surface", .{}); - layer_surface.destroy(); - return; +fn handleNewLayerSurface(_: *wl.Listener(*wlr.LayerSurfaceV1), layer_surface: *wlr.LayerSurfaceV1) void { + std.log.debug("requested layer shell\n", .{}); + if (layer_surface.output == null) { + if (server.seat.focused_output == null) { + std.log.err("No output available for new layer surface", .{}); + layer_surface.destroy(); + return; + } + + layer_surface.output = server.seat.focused_output.?.wlr_output; } - layer_surface.output = server.seat.focused_output.?.wlr_output; - } - - _ = LayerSurface.init(layer_surface); + _ = LayerSurface.init(layer_surface); } fn handleRequestActivate( _: *wl.Listener(*wlr.XdgActivationV1.event.RequestActivate), event: *wlr.XdgActivationV1.event.RequestActivate, ) void { - if(event.surface.data == null) return; + if (event.surface.data == null) return; - const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(event.surface.data.?)); + const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(event.surface.data.?)); - if(scene_node_data.* == .view) { - if(server.seat.focused_output) |output| { - if(output.fullscreen) |fullscreen| { - server.seat.focusSurface(.{ .view = fullscreen }); - return; - } + if (scene_node_data.* == .view) { + if (server.seat.focused_output) |output| { + if (output.fullscreen) |fullscreen| { + server.seat.focusSurface(.{ .view = fullscreen }); + return; + } + } + server.seat.focusSurface(Seat.FocusData{ .view = scene_node_data.view }); + } else { + std.log.warn("Ignoring request to activate non-view", .{}); } - server.seat.focusSurface(Seat.FocusData{ .view = scene_node_data.view }); - } else { - std.log.warn("Ignoring request to activate non-view", .{}); - } } diff --git a/src/Utils.zig b/src/Utils.zig index bd7d692..4a39faf 100644 --- a/src/Utils.zig +++ b/src/Utils.zig @@ -3,6 +3,6 @@ const Utils = @This(); const std = @import("std"); pub fn oomPanic() noreturn { - std.log.err("Out of memory error, exiting with 1", .{}); - std.process.exit(1); + std.log.err("Out of memory error, exiting with 1", .{}); + std.process.exit(1); } diff --git a/src/View.zig b/src/View.zig index 2a934ae..965f631 100644 --- a/src/View.zig +++ b/src/View.zig @@ -56,287 +56,273 @@ set_title: wl.Listener(void) = .init(handleSetTitle), // set_parent: wl.Listener(void) = .init(handleSetParent), pub fn init(xdg_toplevel: *wlr.XdgToplevel) *View { - errdefer Utils.oomPanic(); + errdefer Utils.oomPanic(); - const self = try gpa.create(View); - errdefer gpa.destroy(self); + const self = try gpa.create(View); + errdefer gpa.destroy(self); - self.* = .{ - .focused = false, - .mapped = false, - .fullscreen = false, - .id = @intFromPtr(xdg_toplevel), - .output = null, - .geometry = .{ .width = 0, .height = 0, .x = 0, .y = 0 }, + self.* = .{ + .focused = false, + .mapped = false, + .fullscreen = false, + .id = @intFromPtr(xdg_toplevel), + .output = null, + .geometry = .{ .width = 0, .height = 0, .x = 0, .y = 0 }, + .xdg_toplevel = xdg_toplevel, + .scene_tree = undefined, + .surface_tree = undefined, + .xdg_toplevel_decoration = null, + .borders = undefined, + .border_width = 0, + .scene_node_data = .{ .view = self }, + }; - .xdg_toplevel = xdg_toplevel, - .scene_tree = undefined, - .surface_tree = undefined, - .xdg_toplevel_decoration = null, - .borders = undefined, - .border_width = 0, + // Add new Toplevel to root of the tree + if (server.seat.focused_output) |output| { + self.scene_tree = try output.layers.content.createSceneTree(); + self.surface_tree = try self.scene_tree.createSceneXdgSurface(xdg_toplevel.base); + self.output = output; + } - .scene_node_data = .{ .view = self } - }; + self.scene_tree.node.data = &self.scene_node_data; + self.xdg_toplevel.base.data = &self.scene_node_data; - // Add new Toplevel to root of the tree - if(server.seat.focused_output) |output| { - self.scene_tree = try output.layers.content.createSceneTree(); - self.surface_tree = try self.scene_tree.createSceneXdgSurface(xdg_toplevel.base); - self.output = output; - } + self.xdg_toplevel.events.destroy.add(&self.destroy); + self.xdg_toplevel.base.surface.events.map.add(&self.map); + self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap); + self.xdg_toplevel.base.surface.events.commit.add(&self.commit); + self.xdg_toplevel.base.events.new_popup.add(&self.new_popup); + self.xdg_toplevel.base.events.ack_configure.add(&self.ack_configure); - self.scene_tree.node.data = &self.scene_node_data; - self.xdg_toplevel.base.data = &self.scene_node_data; + for (self.borders, 0..) |_, i| { + const color: [4]f32 = .{ 0, 0, 0, 1 }; + self.borders[i] = try wlr.SceneTree.createSceneRect(self.scene_tree, 0, 0, &color); + self.borders[i].node.data = self; + } - self.xdg_toplevel.events.destroy.add(&self.destroy); - self.xdg_toplevel.base.surface.events.map.add(&self.map); - self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap); - self.xdg_toplevel.base.surface.events.commit.add(&self.commit); - self.xdg_toplevel.base.events.new_popup.add(&self.new_popup); - self.xdg_toplevel.base.events.ack_configure.add(&self.ack_configure); - - for (self.borders, 0..) |_, i| { - const color: [4]f32 = .{ 0, 0, 0, 1 }; - self.borders[i] = try wlr.SceneTree.createSceneRect(self.scene_tree, 0, 0, &color); - self.borders[i].node.data = self; - } - - return self; + return self; } // Tell the client to close // It better behave! pub fn close(self: *View) void { - self.xdg_toplevel.sendClose(); + self.xdg_toplevel.sendClose(); } pub fn setBorderColor(self: *View, color: *const [4]f32) void { - for (self.borders) |border| border.setColor(color); + for (self.borders) |border| border.setColor(color); } pub fn toggleFullscreen(self: *View) void { - self.fullscreen = !self.fullscreen; - if(self.output) |output| { - if(self.fullscreen and output.fullscreen != self) { - // Check to see if another fullscreened view exists, if so replace it - if(output.getFullscreenedView()) |view| { - view.toggleFullscreen(); - } + self.fullscreen = !self.fullscreen; + if (self.output) |output| { + if (self.fullscreen and output.fullscreen != self) { + // Check to see if another fullscreened view exists, if so replace it + if (output.getFullscreenedView()) |view| { + view.toggleFullscreen(); + } - self.scene_tree.node.reparent(output.layers.fullscreen); - self.setPosition(0, 0); - self.setSize(output.wlr_output.width, output.wlr_output.height); - output.fullscreen = self; - } else { - self.scene_tree.node.reparent(output.layers.content); - output.fullscreen = null; + self.scene_tree.node.reparent(output.layers.fullscreen); + self.setPosition(0, 0); + self.setSize(output.wlr_output.width, output.wlr_output.height); + output.fullscreen = self; + } else { + self.scene_tree.node.reparent(output.layers.content); + output.fullscreen = null; + } } - } - _ = self.xdg_toplevel.setFullscreen(self.fullscreen); + _ = self.xdg_toplevel.setFullscreen(self.fullscreen); } pub fn setPosition(self: *View, x: i32, y: i32) void { - if (self.output == null or !self.xdg_toplevel.base.surface.mapped) return; + if (self.output == null or !self.xdg_toplevel.base.surface.mapped) return; - self.geometry.x = x; - self.geometry.y = y; + self.geometry.x = x; + self.geometry.y = y; - self.scene_tree.node.setPosition(self.geometry.x, self.geometry.y); + self.scene_tree.node.setPosition(self.geometry.x, self.geometry.y); - self.resizeBorders(); + self.resizeBorders(); } pub fn setSize(self: *View, width: i32, height: i32) void { - if (self.output == null or !self.xdg_toplevel.base.surface.mapped) return; + if (self.output == null or !self.xdg_toplevel.base.surface.mapped) return; - // at the very least the client must be big enough to have borders - self.geometry.width = @max(1 + 2 * self.border_width, width); - self.geometry.height = @max(1 + 2 * self.border_width, height); + // at the very least the client must be big enough to have borders + self.geometry.width = @max(1 + 2 * self.border_width, width); + self.geometry.height = @max(1 + 2 * self.border_width, height); - // This returns a configure serial for verifying the configure - _ = self.xdg_toplevel.setSize( - self.geometry.width - 2 * self.border_width, - self.geometry.height - 2 * self.border_width, - ); + // This returns a configure serial for verifying the configure + _ = self.xdg_toplevel.setSize( + self.geometry.width - 2 * self.border_width, + self.geometry.height - 2 * self.border_width, + ); - // clip the surface tree to the size of the view - self.surface_tree.node.subsurfaceTreeSetClip(&wlr.Box{ - .x = 0, - .y = 0, - .width = self.geometry.width, - .height = self.geometry.height, - }); + // clip the surface tree to the size of the view + self.surface_tree.node.subsurfaceTreeSetClip(&wlr.Box{ + .x = 0, + .y = 0, + .width = self.geometry.width, + .height = self.geometry.height, + }); - self.resizeBorders(); + self.resizeBorders(); } /// this function handles all things related to sizing and positioning and /// should be called after something in the size or position is changed pub fn resizeBorders(self: *View) void { - // set the position of the surface to not clip with the borders - self.surface_tree.node.setPosition(self.border_width, self.border_width); + // set the position of the surface to not clip with the borders + self.surface_tree.node.setPosition(self.border_width, self.border_width); - self.borders[0].setSize(self.geometry.width, self.border_width); - self.borders[1].setSize(self.geometry.width, self.border_width); - self.borders[2].setSize(self.border_width, self.geometry.height); - self.borders[3].setSize(self.border_width, self.geometry.height); - self.borders[1].node.setPosition(0, self.geometry.height - self.border_width); - self.borders[2].node.setPosition(self.geometry.width - self.border_width, 0); + self.borders[0].setSize(self.geometry.width, self.border_width); + self.borders[1].setSize(self.geometry.width, self.border_width); + self.borders[2].setSize(self.border_width, self.geometry.height); + self.borders[3].setSize(self.border_width, self.geometry.height); + self.borders[1].node.setPosition(0, self.geometry.height - self.border_width); + self.borders[2].node.setPosition(self.geometry.width - self.border_width, 0); } // --------- XdgTopLevel event handlers --------- fn handleMap(listener: *wl.Listener(void)) void { - const view: *View = @fieldParentPtr("map", listener); + const view: *View = @fieldParentPtr("map", listener); - server.events.exec("ViewMapPre", .{view.id}); + server.events.exec("ViewMapPre", .{view.id}); - // we're gonna tell the client that it's tiled so it doesn't try anything - // stupid - _ = view.xdg_toplevel.setTiled(.{ - .top = true, - .bottom = true, - .left = true, - .right = true, - }); + // we're gonna tell the client that it's tiled so it doesn't try anything + // stupid + _ = view.xdg_toplevel.setTiled(.{ + .top = true, + .bottom = true, + .left = true, + .right = true, + }); - view.xdg_toplevel.events.request_fullscreen.add(&view.request_fullscreen); - view.xdg_toplevel.events.request_move.add(&view.request_move); - view.xdg_toplevel.events.request_resize.add(&view.request_resize); - view.xdg_toplevel.events.set_app_id.add(&view.set_app_id); - view.xdg_toplevel.events.set_title.add(&view.set_title); - // view.xdg_toplevel.events.set_parent.add(&view.set_parent); + view.xdg_toplevel.events.request_fullscreen.add(&view.request_fullscreen); + view.xdg_toplevel.events.request_move.add(&view.request_move); + view.xdg_toplevel.events.request_resize.add(&view.request_resize); + view.xdg_toplevel.events.set_app_id.add(&view.set_app_id); + view.xdg_toplevel.events.set_title.add(&view.set_title); + // view.xdg_toplevel.events.set_parent.add(&view.set_parent); - view.mapped = true; - server.events.exec("ViewMapPost", .{view.id}); + view.mapped = true; + server.events.exec("ViewMapPost", .{view.id}); } fn handleUnmap(listener: *wl.Listener(void)) void { - const view: *View = @fieldParentPtr("unmap", listener); - std.log.debug("Unmapping view '{s}'", .{view.xdg_toplevel.title orelse "(unnamed)"}); + const view: *View = @fieldParentPtr("unmap", listener); + std.log.debug("Unmapping view '{s}'", .{view.xdg_toplevel.title orelse "(unnamed)"}); - server.events.exec("ViewUnmapPre", .{view.id}); - view.mapped = false; // we do this before any work is done so that nobody tries - // any funny business + server.events.exec("ViewUnmapPre", .{view.id}); + view.mapped = false; // we do this before any work is done so that nobody tries + // any funny business - if (server.seat.focused_surface) |fs| { - if (fs == .view and fs.view == view) { - server.seat.focusSurface(null); + if (server.seat.focused_surface) |fs| { + if (fs == .view and fs.view == view) { + server.seat.focusSurface(null); + } } - } - view.request_fullscreen.link.remove(); - view.request_move.link.remove(); - view.request_resize.link.remove(); - view.set_title.link.remove(); - view.set_app_id.link.remove(); - view.ack_configure.link.remove(); + view.request_fullscreen.link.remove(); + view.request_move.link.remove(); + view.request_resize.link.remove(); + view.set_title.link.remove(); + view.set_app_id.link.remove(); + view.ack_configure.link.remove(); - server.events.exec("ViewUnmapPost", .{view.id}); + server.events.exec("ViewUnmapPost", .{view.id}); } fn handleDestroy(listener: *wl.Listener(void)) void { - const view: *View = @fieldParentPtr("destroy", listener); + const view: *View = @fieldParentPtr("destroy", listener); - // Remove decorations + // Remove decorations - view.map.link.remove(); - view.unmap.link.remove(); - view.commit.link.remove(); - view.destroy.link.remove(); - view.new_popup.link.remove(); + view.map.link.remove(); + view.unmap.link.remove(); + view.commit.link.remove(); + view.destroy.link.remove(); + view.new_popup.link.remove(); - view.xdg_toplevel.base.surface.data = null; + view.xdg_toplevel.base.surface.data = null; - view.scene_tree.node.destroy(); - // Destroy popups + view.scene_tree.node.destroy(); + // Destroy popups - gpa.destroy(view); + gpa.destroy(view); } fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void { - const view: *View = @fieldParentPtr("commit", listener); + const view: *View = @fieldParentPtr("commit", listener); - // On the first commit, send a configure to tell the client it can proceed - if (view.xdg_toplevel.base.initial_commit) { + // On the first commit, send a configure to tell the client it can proceed + if (view.xdg_toplevel.base.initial_commit) { - // 5 is the XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION, I'm just not sure where it is in the bindings - if (view.xdg_toplevel.base.client.shell.version >= 5) { - // the client should know that it can only fullscreen, nothing else - _ = view.xdg_toplevel.setWmCapabilities(.{ .fullscreen = true, }); + // 5 is the XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION, I'm just not sure where it is in the bindings + if (view.xdg_toplevel.base.client.shell.version >= 5) { + // the client should know that it can only fullscreen, nothing else + _ = view.xdg_toplevel.setWmCapabilities(.{ + .fullscreen = true, + }); + } + + // before committing we tell the client that we'll handle the decorations + if (view.xdg_toplevel_decoration) |deco| _ = deco.setMode(.server_side); + + // this tells the client that it can start doing things we don't use our + // wrapper here cause we don't want to enforce any of our rules + _ = view.xdg_toplevel.setSize(0, 0); + return; } - // before committing we tell the client that we'll handle the decorations - if (view.xdg_toplevel_decoration) |deco| _ = deco.setMode(.server_side); - - // this tells the client that it can start doing things we don't use our - // wrapper here cause we don't want to enforce any of our rules - _ = view.xdg_toplevel.setSize(0, 0); - return; - } - - // resize on every commit - view.resizeBorders(); + // resize on every commit + view.resizeBorders(); } // --------- XdgToplevel Event Handlers --------- fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), xdg_popup: *wlr.XdgPopup) void { - const view: *View = @fieldParentPtr("new_popup", listener); - _ = Popup.init(xdg_popup, view.scene_tree); + const view: *View = @fieldParentPtr("new_popup", listener); + _ = Popup.init(xdg_popup, view.scene_tree); } -fn handleRequestMove( - listener: *wl.Listener(*wlr.XdgToplevel.event.Move), - _: *wlr.XdgToplevel.event.Move -) void { - const view: *View = @fieldParentPtr("request_move", listener); - server.events.exec("ViewRequestMove", .{view.id}); +fn handleRequestMove(listener: *wl.Listener(*wlr.XdgToplevel.event.Move), _: *wlr.XdgToplevel.event.Move) void { + const view: *View = @fieldParentPtr("request_move", listener); + server.events.exec("ViewRequestMove", .{view.id}); } -fn handleRequestResize( - listener: *wl.Listener(*wlr.XdgToplevel.event.Resize), - _: *wlr.XdgToplevel.event.Resize -) void { - const view: *View = @fieldParentPtr("request_resize", listener); - server.events.exec("ViewRequestResize", .{view.id}); +fn handleRequestResize(listener: *wl.Listener(*wlr.XdgToplevel.event.Resize), _: *wlr.XdgToplevel.event.Resize) void { + const view: *View = @fieldParentPtr("request_resize", listener); + server.events.exec("ViewRequestResize", .{view.id}); } fn handleAckConfigure( - listener: *wl.Listener(*wlr.XdgSurface.Configure), - _: *wlr.XdgSurface.Configure, + listener: *wl.Listener(*wlr.XdgSurface.Configure), + _: *wlr.XdgSurface.Configure, ) void { - const view: *View = @fieldParentPtr("ack_configure", listener); - _ = view; - std.log.err("Unimplemented ack configure", .{}); + const view: *View = @fieldParentPtr("ack_configure", listener); + _ = view; + std.log.err("Unimplemented ack configure", .{}); } -fn handleRequestFullscreen( - listener: *wl.Listener(void) -) void { - const view: *View = @fieldParentPtr("request_fullscreen", listener); - server.events.exec("ViewRequestFullscreen", .{view.id}); +fn handleRequestFullscreen(listener: *wl.Listener(void)) void { + const view: *View = @fieldParentPtr("request_fullscreen", listener); + server.events.exec("ViewRequestFullscreen", .{view.id}); } -fn handleRequestMinimize( - listener: *wl.Listener(void) -) void { - const view: *View = @fieldParentPtr("request_minimize", listener); - server.events.exec("ViewRequestMinimize", .{view.id}); - std.log.debug("request_minimize unimplemented", .{}); +fn handleRequestMinimize(listener: *wl.Listener(void)) void { + const view: *View = @fieldParentPtr("request_minimize", listener); + server.events.exec("ViewRequestMinimize", .{view.id}); + std.log.debug("request_minimize unimplemented", .{}); } -fn handleSetAppId( - listener: *wl.Listener(void) -) void { - const view: *View = @fieldParentPtr("set_app_id", listener); - server.events.exec("ViewAppIdUpdate", .{view.id}); - std.log.debug("request_set_app_id unimplemented", .{}); +fn handleSetAppId(listener: *wl.Listener(void)) void { + const view: *View = @fieldParentPtr("set_app_id", listener); + server.events.exec("ViewAppIdUpdate", .{view.id}); + std.log.debug("request_set_app_id unimplemented", .{}); } -fn handleSetTitle( - listener: *wl.Listener(void) -) void { - const view: *View = @fieldParentPtr("set_title", listener); - server.events.exec("ViewTitleUpdate", .{view.id}); - std.log.debug("request_set_title unimplemented", .{}); +fn handleSetTitle(listener: *wl.Listener(void)) void { + const view: *View = @fieldParentPtr("set_title", listener); + server.events.exec("ViewTitleUpdate", .{view.id}); + std.log.debug("request_set_title unimplemented", .{}); } diff --git a/src/lua/Api.zig b/src/lua/Api.zig index 7b49fa2..15c2bb7 100644 --- a/src/lua/Api.zig +++ b/src/lua/Api.zig @@ -2,7 +2,7 @@ const std = @import("std"); const zlua = @import("zlua"); const wlr = @import("wlroots"); -const Utils = @import("../Utils.zig"); +const Utils = @import("../Utils.zig"); const LuaUtils = @import("LuaUtils.zig"); const gpa = std.heap.c_allocator; @@ -13,53 +13,53 @@ const server = &@import("../main.zig").server; /// ---Spawn new application via the shell command /// ---@param cmd string Command to be run by a shell pub fn spawn(L: *zlua.Lua) i32 { - const cmd = L.checkString(1); + const cmd = L.checkString(1); - var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa); - child.env_map = env_map; - child.spawn() catch |err| switch (err) { - error.OutOfMemory => Utils.oomPanic(), - else => L.raiseErrorStr("Unable to spawn process child process", .{}), - }; + var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa); + child.env_map = env_map; + child.spawn() catch |err| switch (err) { + error.OutOfMemory => Utils.oomPanic(), + else => L.raiseErrorStr("Unable to spawn process child process", .{}), + }; - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Exit mezzaluna pub fn exit(L: *zlua.Lua) i32 { - server.wl_server.terminate(); + server.wl_server.terminate(); - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Change to a different virtual terminal /// ---@param vt_num integer virtual terminal number to switch to pub fn change_vt(L: *zlua.Lua) i32 { - const vt_num = num: { - const res = LuaUtils.coerceInteger(c_uint, L.checkInteger(1)) catch |err| break :num err; - if (res < 1) break :num error.InvalidInteger; - break :num res; - } catch L.raiseErrorStr("The vt number must be >= 1 and < inf", .{}); + const vt_num = num: { + const res = LuaUtils.coerceInteger(c_uint, L.checkInteger(1)) catch |err| break :num err; + if (res < 1) break :num error.InvalidInteger; + break :num res; + } catch L.raiseErrorStr("The vt number must be >= 1 and < inf", .{}); - if (server.session) |session| { - std.log.debug("Changing virtual terminal to {d}", .{vt_num}); - wlr.Session.changeVt(session, vt_num) catch { - L.raiseErrorStr("Failed to switch vt", .{}); - }; - } else { - L.raiseErrorStr("Mez has not been initialized yet", .{}); - } + if (server.session) |session| { + std.log.debug("Changing virtual terminal to {d}", .{vt_num}); + wlr.Session.changeVt(session, vt_num) catch { + L.raiseErrorStr("Failed to switch vt", .{}); + }; + } else { + L.raiseErrorStr("Mez has not been initialized yet", .{}); + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// --- Print the scene tree for debugging pub fn print_scene(L: *zlua.Lua) i32 { - @import("../Debug.zig").debugPrintSceneTree(); + @import("../Debug.zig").debugPrintSceneTree(); - L.pushNil(); - return 1; + L.pushNil(); + return 1; } diff --git a/src/lua/Bridge.zig b/src/lua/Bridge.zig index 8ba0c1d..fe8a68c 100644 --- a/src/lua/Bridge.zig +++ b/src/lua/Bridge.zig @@ -6,23 +6,23 @@ const zlua = @import("zlua"); const gpa = std.heap.c_allocator; pub fn getNestedField(L: *zlua.Lua, path: []u8) bool { - var tokens = std.mem.tokenizeScalar(u8, path, '.'); - var first = true; + var tokens = std.mem.tokenizeScalar(u8, path, '.'); + var first = true; - while (tokens.next()) |token| { - const tok = gpa.dupeZ(u8, token) catch return false; - if (first) { - _ = L.getGlobal(tok) catch return false; - first = false; - } else { - _ = L.getField(-1, tok); - L.remove(-2); + while (tokens.next()) |token| { + const tok = gpa.dupeZ(u8, token) catch return false; + if (first) { + _ = L.getGlobal(tok) catch return false; + first = false; + } else { + _ = L.getField(-1, tok); + L.remove(-2); + } + + if (L.isNil(-1)) { + return false; + } } - if (L.isNil(-1)) { - return false; - } - } - - return true; + return true; } diff --git a/src/lua/Fs.zig b/src/lua/Fs.zig index 498f41a..aa45ea9 100644 --- a/src/lua/Fs.zig +++ b/src/lua/Fs.zig @@ -4,7 +4,7 @@ const std = @import("std"); const zlua = @import("zlua"); const Lua = @import("Lua.zig"); -const Utils = @import("../Utils.zig"); +const Utils = @import("../Utils.zig"); const gpa = std.heap.c_allocator; @@ -12,29 +12,29 @@ const gpa = std.heap.c_allocator; /// ---@vararg string paths to join /// ---@return string? pub fn joinpath(L: *zlua.Lua) i32 { - const nargs: i32 = L.getTop(); - if (nargs < 2) { - L.raiseErrorStr("Expected at least two paths to join", .{}); - return 0; - } - - var paths = std.ArrayList([:0]const u8).initCapacity(gpa, @intCast(nargs)) catch Utils.oomPanic(); - defer paths.deinit(gpa); - - var i: u8 = 1; - while (i <= nargs) : (i += 1) { - if (!L.isString(i)) { - L.raiseErrorStr("Expected string at argument %d", .{i}); - return 0; + const nargs: i32 = L.getTop(); + if (nargs < 2) { + L.raiseErrorStr("Expected at least two paths to join", .{}); + return 0; } - const partial_path = L.toString(i) catch unreachable; - paths.append(gpa, partial_path) catch Utils.oomPanic(); - } + var paths = std.ArrayList([:0]const u8).initCapacity(gpa, @intCast(nargs)) catch Utils.oomPanic(); + defer paths.deinit(gpa); - const final_path: []const u8 = std.fs.path.join(gpa, paths.items) catch Utils.oomPanic(); - defer gpa.free(final_path); + var i: u8 = 1; + while (i <= nargs) : (i += 1) { + if (!L.isString(i)) { + L.raiseErrorStr("Expected string at argument %d", .{i}); + return 0; + } - _ = L.pushString(final_path); - return 1; + const partial_path = L.toString(i) catch unreachable; + paths.append(gpa, partial_path) catch Utils.oomPanic(); + } + + const final_path: []const u8 = std.fs.path.join(gpa, paths.items) catch Utils.oomPanic(); + defer gpa.free(final_path); + + _ = L.pushString(final_path); + return 1; } diff --git a/src/lua/Hook.zig b/src/lua/Hook.zig index 1969021..86be0f1 100644 --- a/src/lua/Hook.zig +++ b/src/lua/Hook.zig @@ -15,60 +15,60 @@ const server = &@import("../main.zig").server; /// ---@param options table /// ---@return number id pub fn add(L: *zlua.Lua) i32 { - L.checkType(2, .table); + L.checkType(2, .table); - var hook: *THook = gpa.create(THook) catch Utils.oomPanic(); + var hook: *THook = gpa.create(THook) catch Utils.oomPanic(); - // We support both a string and a table of strings as the first value of - // add. Regardless of which type is passed in we create an arraylist of - // []const u8's - if (L.isTable(1)) { - hook.events = gpa.alloc(comptime []const u8, L.objectLen(1)) catch Utils.oomPanic(); - var i: u32 = 0; - L.pushNil(); - while (L.next(1)) { - if (L.isString(-1)) { - const s = L.checkString(-1); - hook.events[i] = gpa.dupe(u8, s) catch Utils.oomPanic(); - i += 1; - } - L.pop(1); + // We support both a string and a table of strings as the first value of + // add. Regardless of which type is passed in we create an arraylist of + // []const u8's + if (L.isTable(1)) { + hook.events = gpa.alloc(comptime []const u8, L.objectLen(1)) catch Utils.oomPanic(); + var i: u32 = 0; + L.pushNil(); + while (L.next(1)) { + if (L.isString(-1)) { + const s = L.checkString(-1); + hook.events[i] = gpa.dupe(u8, s) catch Utils.oomPanic(); + i += 1; + } + L.pop(1); + } + } else if (L.isString(1)) { + hook.events = gpa.alloc(comptime []const u8, 1) catch Utils.oomPanic(); + const s = L.checkString(1); + hook.events[0] = gpa.dupe(u8, s) catch Utils.oomPanic(); } - } else if (L.isString(1)) { - hook.events = gpa.alloc(comptime []const u8, 1) catch Utils.oomPanic(); - const s = L.checkString(1); - hook.events[0] = gpa.dupe(u8, s) catch Utils.oomPanic(); - } - _ = L.pushString("callback"); - _ = L.getTable(2); - if (L.isFunction(-1)) { - hook.options.lua_cb_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); - } + _ = L.pushString("callback"); + _ = L.getTable(2); + if (L.isFunction(-1)) { + hook.options.lua_cb_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); + } - // TEST: this should be safe as the lua_cb_ref_idx's should never be the same - // but that all really depends on the implementation of the hashmap - server.hooks.put(hook.options.lua_cb_ref_idx, hook) catch Utils.oomPanic(); + // TEST: this should be safe as the lua_cb_ref_idx's should never be the same + // but that all really depends on the implementation of the hashmap + server.hooks.put(hook.options.lua_cb_ref_idx, hook) catch Utils.oomPanic(); - for (hook.events) |value| { - server.events.put(value, hook) catch Utils.oomPanic(); - } + for (hook.events) |value| { + server.events.put(value, hook) catch Utils.oomPanic(); + } - L.pushInteger(hook.options.lua_cb_ref_idx); - return 1; + L.pushInteger(hook.options.lua_cb_ref_idx); + return 1; } /// ---Create an existing hook /// ---@param id number /// ---@return boolean has it been deleted pub fn del(L: *zlua.Lua) i32 { - const hook_id = LuaUtils.coerceInteger(i32, L.checkInteger(1)) catch L.raiseErrorStr("hook id must be a valid number", .{}); - const hook = server.hooks.get(hook_id); - if (hook == null) L.raiseErrorStr("hook {} does not exist", .{hook_id}); + const hook_id = LuaUtils.coerceInteger(i32, L.checkInteger(1)) catch L.raiseErrorStr("hook id must be a valid number", .{}); + const hook = server.hooks.get(hook_id); + if (hook == null) L.raiseErrorStr("hook {} does not exist", .{hook_id}); - for (hook.?.events) |value| { - server.events.del(value, hook.?); - } - L.pushBoolean(server.hooks.remove(hook_id)); - return 1; + for (hook.?.events) |value| { + server.events.del(value, hook.?); + } + L.pushBoolean(server.hooks.remove(hook_id)); + return 1; } diff --git a/src/lua/Input.zig b/src/lua/Input.zig index ef3ce74..278beaa 100644 --- a/src/lua/Input.zig +++ b/src/lua/Input.zig @@ -14,17 +14,17 @@ const c = @import("../C.zig").c; const server = &@import("../main.zig").server; fn parse_modkeys(modStr: []const u8) wlr.Keyboard.ModifierMask { - var it = std.mem.splitScalar(u8, modStr, '|'); - var modifiers = wlr.Keyboard.ModifierMask{}; - while (it.next()) |m| { - inline for (std.meta.fields(@TypeOf(modifiers))) |f| { - if (f.type == bool and std.mem.eql(u8, m, f.name)) { - @field(modifiers, f.name) = true; - } + var it = std.mem.splitScalar(u8, modStr, '|'); + var modifiers = wlr.Keyboard.ModifierMask{}; + while (it.next()) |m| { + inline for (std.meta.fields(@TypeOf(modifiers))) |f| { + if (f.type == bool and std.mem.eql(u8, m, f.name)) { + @field(modifiers, f.name) = true; + } + } } - } - return modifiers; + return modifiers; } /// ---Create a new keymap @@ -32,36 +32,36 @@ fn parse_modkeys(modStr: []const u8) wlr.Keyboard.ModifierMask { /// ---@param string keys /// ---@param table options pub fn add_keymap(L: *zlua.Lua) i32 { - var keymap: Keymap = undefined; - keymap.options.repeat = true; + var keymap: Keymap = undefined; + keymap.options.repeat = true; - const mod = L.checkString(1); - keymap.modifier = parse_modkeys(mod); + const mod = L.checkString(1); + keymap.modifier = parse_modkeys(mod); - const key = L.checkString(2); - keymap.keycode = xkb.Keysym.fromName(key, .no_flags); + const key = L.checkString(2); + keymap.keycode = xkb.Keysym.fromName(key, .no_flags); - _ = L.pushString("press"); - _ = L.getTable(3); - if (L.isFunction(-1)) { - keymap.options.lua_press_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); - } + _ = L.pushString("press"); + _ = L.getTable(3); + if (L.isFunction(-1)) { + keymap.options.lua_press_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); + } - _ = L.pushString("release"); - _ = L.getTable(3); - if (L.isFunction(-1)) { - keymap.options.lua_release_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); - } + _ = L.pushString("release"); + _ = L.getTable(3); + if (L.isFunction(-1)) { + keymap.options.lua_release_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); + } - _ = L.pushString("repeat"); - _ = L.getTable(3); - keymap.options.repeat = L.isNil(-1) or L.toBoolean(-1); + _ = L.pushString("repeat"); + _ = L.getTable(3); + keymap.options.repeat = L.isNil(-1) or L.toBoolean(-1); - const hash = Keymap.hash(keymap.modifier, keymap.keycode); - server.keymaps.put(hash, keymap) catch Utils.oomPanic(); + const hash = Keymap.hash(keymap.modifier, keymap.keycode); + server.keymaps.put(hash, keymap) catch Utils.oomPanic(); - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Create a new mousemap @@ -69,113 +69,113 @@ pub fn add_keymap(L: *zlua.Lua) i32 { /// ---@param string libevdev button name (ex. "BTN_LEFT", "BTN_RIGHT") /// ---@param table options pub fn add_mousemap(L: *zlua.Lua) i32 { - var mousemap: Mousemap = undefined; + var mousemap: Mousemap = undefined; - const mod = L.checkString(1); - mousemap.modifier = parse_modkeys(mod); + const mod = L.checkString(1); + mousemap.modifier = parse_modkeys(mod); - const button = L.checkString(2); - mousemap.event_code = c.libevdev_event_code_from_name(c.EV_KEY, button); + const button = L.checkString(2); + mousemap.event_code = c.libevdev_event_code_from_name(c.EV_KEY, button); - _ = L.pushString("press"); - _ = L.getTable(3); - if (L.isFunction(-1)) { - mousemap.options.lua_press_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); - } + _ = L.pushString("press"); + _ = L.getTable(3); + if (L.isFunction(-1)) { + mousemap.options.lua_press_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); + } - _ = L.pushString("release"); - _ = L.getTable(3); - if (L.isFunction(-1)) { - mousemap.options.lua_release_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); - } + _ = L.pushString("release"); + _ = L.getTable(3); + if (L.isFunction(-1)) { + mousemap.options.lua_release_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); + } - _ = L.pushString("drag"); - _ = L.getTable(3); - if (L.isFunction(-1)) { - mousemap.options.lua_drag_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); - } + _ = L.pushString("drag"); + _ = L.getTable(3); + if (L.isFunction(-1)) { + mousemap.options.lua_drag_ref_idx = L.ref(zlua.registry_index) catch Utils.oomPanic(); + } - const hash = Mousemap.hash(mousemap.modifier, mousemap.event_code); - server.mousemaps.put(hash, mousemap) catch Utils.oomPanic(); + const hash = Mousemap.hash(mousemap.modifier, mousemap.event_code); + server.mousemaps.put(hash, mousemap) catch Utils.oomPanic(); - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Remove an existing keymap /// ---@param string modifiers /// ---@param string keys pub fn del_keymap(L: *zlua.Lua) i32 { - L.checkType(1, .string); - L.checkType(2, .string); + L.checkType(1, .string); + L.checkType(2, .string); - var keymap: Keymap = undefined; - const mod = L.checkString(1); + var keymap: Keymap = undefined; + const mod = L.checkString(1); - keymap.modifier = parse_modkeys(mod); + keymap.modifier = parse_modkeys(mod); - const key = L.checkString(2); + const key = L.checkString(2); - keymap.keycode = xkb.Keysym.fromName(key, .no_flags); - _ = server.keymaps.remove(Keymap.hash(keymap.modifier, keymap.keycode)); + keymap.keycode = xkb.Keysym.fromName(key, .no_flags); + _ = server.keymaps.remove(Keymap.hash(keymap.modifier, keymap.keycode)); - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Remove an existing mousemap /// ---@param string modifiers /// ---@param string button pub fn del_mousemap(L: *zlua.Lua) i32 { - L.checkType(1, .string); - L.checkType(2, .string); + L.checkType(1, .string); + L.checkType(2, .string); - var mousemap: Mousemap = undefined; - const mod = L.checkString(1); - mousemap.modifier = parse_modkeys(mod); + var mousemap: Mousemap = undefined; + const mod = L.checkString(1); + mousemap.modifier = parse_modkeys(mod); - const button = L.checkString(2); - mousemap.event_code = c.libevdev_event_code_from_name(c.EV_KEY, button); + const button = L.checkString(2); + mousemap.event_code = c.libevdev_event_code_from_name(c.EV_KEY, button); - _ = server.mousemaps.remove(Mousemap.hash(mousemap.modifier, mousemap.event_code)); + _ = server.mousemaps.remove(Mousemap.hash(mousemap.modifier, mousemap.event_code)); - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Get the repeat information /// ---@return integer[2] pub fn get_repeat_info(L: *zlua.Lua) i32 { - L.newTable(); + L.newTable(); - L.pushInteger(server.seat.keyboard_group.wlr_group.keyboard.repeat_info.rate); - L.setField(-2, "rate"); - L.pushInteger(server.seat.keyboard_group.wlr_group.keyboard.repeat_info.delay); - L.setField(-2, "delay"); + L.pushInteger(server.seat.keyboard_group.wlr_group.keyboard.repeat_info.rate); + L.setField(-2, "rate"); + L.pushInteger(server.seat.keyboard_group.wlr_group.keyboard.repeat_info.delay); + L.setField(-2, "delay"); - return 1; + return 1; } /// ---Set the repeat information /// ---@param integer rate /// ---@param integer delay pub fn set_repeat_info(L: *zlua.Lua) i32 { - const rate = LuaUtils.coerceInteger(i32, L.checkInteger(1)) catch { - L.raiseErrorStr("The rate must be a valid number", .{}); - }; - const delay = LuaUtils.coerceInteger(i32, L.checkInteger(2)) catch { - L.raiseErrorStr("The delay must be a valid number", .{}); - }; + const rate = LuaUtils.coerceInteger(i32, L.checkInteger(1)) catch { + L.raiseErrorStr("The rate must be a valid number", .{}); + }; + const delay = LuaUtils.coerceInteger(i32, L.checkInteger(2)) catch { + L.raiseErrorStr("The delay must be a valid number", .{}); + }; - server.seat.keyboard_group.wlr_group.keyboard.setRepeatInfo(rate, delay); - return 0; + server.seat.keyboard_group.wlr_group.keyboard.setRepeatInfo(rate, delay); + return 0; } /// ---Set the cursor type /// ---@param string cursor name pub fn set_cursor_type(L: *zlua.Lua) i32 { - const name = L.checkString(1); - server.cursor.wlr_cursor.setXcursor(server.cursor.x_cursor_manager, name); + const name = L.checkString(1); + server.cursor.wlr_cursor.setXcursor(server.cursor.x_cursor_manager, name); - return 0; + return 0; } diff --git a/src/lua/Lua.zig b/src/lua/Lua.zig index 3a8aa3e..90d5bd5 100644 --- a/src/lua/Lua.zig +++ b/src/lua/Lua.zig @@ -6,11 +6,11 @@ const zlua = @import("zlua"); const LuaUtils = @import("LuaUtils.zig"); const Bridge = @import("Bridge.zig"); -const Fs = @import("Fs.zig"); -const Input = @import("Input.zig"); -const Api = @import("Api.zig"); -const Hook = @import("Hook.zig"); -const View = @import("View.zig"); +const Fs = @import("Fs.zig"); +const Input = @import("Input.zig"); +const Api = @import("Api.zig"); +const Hook = @import("Hook.zig"); +const View = @import("View.zig"); const Output = @import("Output.zig"); const Remote = @import("Remote.zig"); @@ -19,165 +19,168 @@ const gpa = std.heap.c_allocator; state: *zlua.Lua, pub fn loadRuntimeDir(self: *zlua.Lua) !void { - const path_dir = try std.fs.path.joinZ(gpa, &[_][]const u8{ - config.runtime_path_prefix, - "share", - "mezzaluna", - }); - defer gpa.free(path_dir); + const path_dir = try std.fs.path.joinZ(gpa, &[_][]const u8{ + config.runtime_path_prefix, + "share", + "mezzaluna", + }); + defer gpa.free(path_dir); - { - _ = try self.getGlobal("mez"); - _ = self.getField(-1, "path"); - defer self.pop(2); - _ = self.pushString(path_dir); - self.setField(-2, "runtime"); - } + { + _ = try self.getGlobal("mez"); + _ = self.getField(-1, "path"); + defer self.pop(2); + _ = self.pushString(path_dir); + self.setField(-2, "runtime"); + } - const path_full = try std.fs.path.joinZ(gpa, &[_][]const u8{ - path_dir, - "init.lua", - }); - defer gpa.free(path_full); + const path_full = try std.fs.path.joinZ(gpa, &[_][]const u8{ + path_dir, + "init.lua", + }); + defer gpa.free(path_full); - self.doFile(path_full) catch { - const err = try self.toString(-1); - std.log.debug("Failed to run lua file: {s}", .{err}); - }; + self.doFile(path_full) catch { + const err = try self.toString(-1); + std.log.debug("Failed to run lua file: {s}", .{err}); + }; } pub fn setBaseConfig(self: *zlua.Lua, path: []const u8) !void { - { - _ = try self.getGlobal("mez"); - _ = self.getField(-1, "path"); - defer self.pop(2); - const new_path = try std.fs.path.join(gpa, &[_][]const u8{path, "init.lua"}); - defer gpa.free(new_path); - _ = self.pushString(new_path); - self.setField(-2, "config"); - } - { - _ = try self.getGlobal("mez"); - _ = self.getField(-1, "path"); - defer self.pop(2); - const cur_path = self.toString(-1) catch ""; + { + _ = try self.getGlobal("mez"); + _ = self.getField(-1, "path"); + defer self.pop(2); + const new_path = try std.fs.path.join(gpa, &[_][]const u8{ path, "init.lua" }); + defer gpa.free(new_path); + _ = self.pushString(new_path); + self.setField(-2, "config"); + } + { + _ = try self.getGlobal("mez"); + _ = self.getField(-1, "path"); + defer self.pop(2); + const cur_path = self.toString(-1) catch ""; - const unsentinel: []const u8 = std.mem.span(cur_path.ptr); - const new_path = try std.mem.concat(gpa, u8, &[_][]const u8{ - unsentinel, - ";", - path, - }); - defer gpa.free(new_path); - _ = self.pushString(new_path); - _ = self.setField(-2, "path"); - } + const unsentinel: []const u8 = std.mem.span(cur_path.ptr); + const new_path = try std.mem.concat(gpa, u8, &[_][]const u8{ + unsentinel, + ";", + path, + }); + defer gpa.free(new_path); + _ = self.pushString(new_path); + _ = self.setField(-2, "path"); + } } fn loadBaseConfig(self: *zlua.Lua) !void { - const lua_path = "mez.path.base_config"; - if (!Bridge.getNestedField(self, @constCast(lua_path[0..]))) { - std.log.err("Base config path not found. is your runtime dir setup?", .{}); - return; - } - const path = self.toString(-1) catch |err| { - std.log.err("Failed to pop the base config path from the lua stack. {}", .{err}); - return; - }; - self.pop(-1); - try self.doFile(path); + const lua_path = "mez.path.base_config"; + if (!Bridge.getNestedField(self, @constCast(lua_path[0..]))) { + std.log.err("Base config path not found. is your runtime dir setup?", .{}); + return; + } + const path = self.toString(-1) catch |err| { + std.log.err("Failed to pop the base config path from the lua stack. {}", .{err}); + return; + }; + self.pop(-1); + try self.doFile(path); } fn loadConfigDir(self: *zlua.Lua) !void { - const lua_path = "mez.path.config"; - if (!Bridge.getNestedField(self, @constCast(lua_path[0..]))) { - std.log.err("Config path not found. is your runtime dir setup?", .{}); - return; - } - const path = self.toString(-1) catch |err| { - std.log.err("Failed to pop the config path from the lua stack. {}", .{err}); - return; - }; - self.pop(-1); - try self.doFile(path); + const lua_path = "mez.path.config"; + if (!Bridge.getNestedField(self, @constCast(lua_path[0..]))) { + std.log.err("Config path not found. is your runtime dir setup?", .{}); + return; + } + const path = self.toString(-1) catch |err| { + std.log.err("Failed to pop the config path from the lua stack. {}", .{err}); + return; + }; + self.pop(-1); + try self.doFile(path); } pub fn openLibs(self: *zlua.Lua) void { - { - self.newTable(); - defer _ = self.setGlobal("mez"); { - self.newTable(); - defer _ = self.setField(-2, "path"); + self.newTable(); + defer _ = self.setGlobal("mez"); + { + self.newTable(); + defer _ = self.setField(-2, "path"); + } + { + const fs_funcs = zlua.fnRegsFromType(Fs); + LuaUtils.newLib(self, fs_funcs); + self.setField(-2, "fs"); + } + { + const input_funcs = zlua.fnRegsFromType(Input); + LuaUtils.newLib(self, input_funcs); + self.setField(-2, "input"); + } + { + const hook_funcs = zlua.fnRegsFromType(Hook); + LuaUtils.newLib(self, hook_funcs); + self.setField(-2, "hook"); + } + { + const api_funcs = zlua.fnRegsFromType(Api); + LuaUtils.newLib(self, api_funcs); + self.setField(-2, "api"); + } + { + const view_funcs = zlua.fnRegsFromType(View); + LuaUtils.newLib(self, view_funcs); + self.setField(-2, "view"); + } + { + const output_funcs = zlua.fnRegsFromType(Output); + LuaUtils.newLib(self, output_funcs); + self.setField(-2, "output"); + } + { + const remote_funcs = zlua.fnRegsFromType(Remote); + LuaUtils.newLib(self, remote_funcs); + self.setField(-2, "remote"); + } } - { - const fs_funcs = zlua.fnRegsFromType(Fs); - LuaUtils.newLib(self, fs_funcs); - self.setField(-2, "fs"); - } - { - const input_funcs = zlua.fnRegsFromType(Input); - LuaUtils.newLib(self, input_funcs); - self.setField(-2, "input"); - } - { - const hook_funcs = zlua.fnRegsFromType(Hook); - LuaUtils.newLib(self, hook_funcs); - self.setField(-2, "hook"); - } - { - const api_funcs = zlua.fnRegsFromType(Api); - LuaUtils.newLib(self, api_funcs); - self.setField(-2, "api"); - } - { - const view_funcs = zlua.fnRegsFromType(View); - LuaUtils.newLib(self, view_funcs); - self.setField(-2, "view"); - } - { - const output_funcs = zlua.fnRegsFromType(Output); - LuaUtils.newLib(self, output_funcs); - self.setField(-2, "output"); - } - { - const remote_funcs = zlua.fnRegsFromType(Remote); - LuaUtils.newLib(self, remote_funcs); - self.setField(-2, "remote"); - } - } } -pub const Config = struct { str: ?[]const u8, enabled: bool, }; +pub const Config = struct { + str: ?[]const u8, + enabled: bool, +}; pub fn init(self: *Lua, cfg: Config) !void { - self.state = try zlua.Lua.init(gpa); - errdefer self.state.deinit(); - self.state.openLibs(); + self.state = try zlua.Lua.init(gpa); + errdefer self.state.deinit(); + self.state.openLibs(); - openLibs(self.state); + openLibs(self.state); - if (!cfg.enabled) try setBaseConfig(self.state, ""); - loadRuntimeDir(self.state) catch |err| if (err == error.LuaRuntime) { - std.log.warn("{s}", .{try self.state.toString(-1)}); - }; - - loadBaseConfig(self.state) catch |err| if (err == error.LuaRuntime) { - std.log.warn("{s}", .{try self.state.toString(-1)}); - }; - - if (cfg.str) |path| { - defer gpa.free(path); - try setBaseConfig(self.state, path); - } - if (cfg.enabled) { - loadConfigDir(self.state) catch |err| if (err == error.LuaRuntime) { - std.log.warn("{s}", .{try self.state.toString(-1)}); + if (!cfg.enabled) try setBaseConfig(self.state, ""); + loadRuntimeDir(self.state) catch |err| if (err == error.LuaRuntime) { + std.log.warn("{s}", .{try self.state.toString(-1)}); }; - } - std.log.debug("Loaded lua", .{}); + loadBaseConfig(self.state) catch |err| if (err == error.LuaRuntime) { + std.log.warn("{s}", .{try self.state.toString(-1)}); + }; + + if (cfg.str) |path| { + defer gpa.free(path); + try setBaseConfig(self.state, path); + } + if (cfg.enabled) { + loadConfigDir(self.state) catch |err| if (err == error.LuaRuntime) { + std.log.warn("{s}", .{try self.state.toString(-1)}); + }; + } + + std.log.debug("Loaded lua", .{}); } pub fn deinit(self: *Lua) void { - self.state.deinit(); + self.state.deinit(); } diff --git a/src/lua/LuaUtils.zig b/src/lua/LuaUtils.zig index c924ec6..7c19c4e 100644 --- a/src/lua/LuaUtils.zig +++ b/src/lua/LuaUtils.zig @@ -8,53 +8,53 @@ const View = @import("../View.zig"); const server = &@import("../main.zig").server; pub fn coerceNumber(comptime x: type, number: zlua.Number) error{InvalidNumber}!x { - if (number < std.math.minInt(x) or number > std.math.maxInt(x) or std.math.isNan(number)) { - return error.InvalidNumber; - } - switch (@typeInfo(x)) { - .int => return @as(x, @intFromFloat(number)), - .float => return @floatCast(number), - else => @compileError("unsupported type"), - } + if (number < std.math.minInt(x) or number > std.math.maxInt(x) or std.math.isNan(number)) { + return error.InvalidNumber; + } + switch (@typeInfo(x)) { + .int => return @as(x, @intFromFloat(number)), + .float => return @floatCast(number), + else => @compileError("unsupported type"), + } } pub fn coerceInteger(comptime x: type, number: zlua.Integer) error{InvalidInteger}!x { - if (number < std.math.minInt(x) or number > std.math.maxInt(x) or std.math.isNan(number)) { - return error.InvalidInteger; - } - switch (@typeInfo(x)) { - .int => return @intCast(number), - .float => return @as(x, @floatFromInt(number)), - else => @compileError("unsupported type"), - } + if (number < std.math.minInt(x) or number > std.math.maxInt(x) or std.math.isNan(number)) { + return error.InvalidInteger; + } + switch (@typeInfo(x)) { + .int => return @intCast(number), + .float => return @as(x, @floatFromInt(number)), + else => @compileError("unsupported type"), + } } pub fn newLib(L: *zlua.Lua, f: []const zlua.FnReg) void { - L.newLibTable(f); // documented as being unavailable, but it is. - for (f) |value| { - if (value.func == null) continue; - L.pushClosure(value.func.?, 0); - L.setField(-2, value.name); - } + L.newLibTable(f); // documented as being unavailable, but it is. + for (f) |value| { + if (value.func == null) continue; + L.pushClosure(value.func.?, 0); + L.setField(-2, value.name); + } } /// makes a best effort to convert the value at the top of the stack to a string /// if we're unable to do so return "nil" pub fn toStringEx(L: *zlua.Lua) [:0]const u8 { - const errstr = "nil"; - _ = L.getGlobal("tostring") catch return errstr; - L.insert(1); - L.protectedCall(.{ .args = 1, .results = 1 }) catch return errstr; - return L.toString(-1) catch errstr; + const errstr = "nil"; + _ = L.getGlobal("tostring") catch return errstr; + L.insert(1); + L.protectedCall(.{ .args = 1, .results = 1 }) catch return errstr; + return L.toString(-1) catch errstr; } pub fn viewById(view_id: u64) ?*View { - if (view_id == 0) { - if(server.seat.focused_surface) |fs| { - if(fs == .view) return fs.view; + if (view_id == 0) { + if (server.seat.focused_surface) |fs| { + if (fs == .view) return fs.view; + } + } else { + return server.root.viewById(view_id); } - } else { - return server.root.viewById(view_id); - } - return null; + return null; } diff --git a/src/lua/Output.zig b/src/lua/Output.zig index 1c16dbe..b04818c 100644 --- a/src/lua/Output.zig +++ b/src/lua/Output.zig @@ -7,181 +7,180 @@ const LuaUtils = @import("LuaUtils.zig"); const server = &@import("../main.zig").server; fn output_id_err(L: *zlua.Lua) noreturn { - L.raiseErrorStr("The output id must be >= 0 and < inf", .{}); + L.raiseErrorStr("The output id must be >= 0 and < inf", .{}); } /// ---@alias output_id integer - /// ---Get the ids for all available outputs /// ---@return output_id[]? pub fn get_all_ids(L: *zlua.Lua) i32 { - var it = server.root.scene.outputs.iterator(.forward); - var index: usize = 1; + var it = server.root.scene.outputs.iterator(.forward); + var index: usize = 1; - L.newTable(); + L.newTable(); - while(it.next()) |scene_output| : (index += 1) { - if(scene_output.output.data == null) continue; + while (it.next()) |scene_output| : (index += 1) { + if (scene_output.output.data == null) continue; - const output = @as(*Output, @ptrCast(@alignCast(scene_output.output.data.?))); + const output = @as(*Output, @ptrCast(@alignCast(scene_output.output.data.?))); - L.pushInteger(@intCast(index)); - L.pushInteger(@intCast(output.id)); - L.setTable(-3); - } + L.pushInteger(@intCast(index)); + L.pushInteger(@intCast(output.id)); + L.setTable(-3); + } - return 1; + return 1; } /// ---Get the id for the focused output /// ---@return output_id? pub fn get_focused_id(L: *zlua.Lua) i32 { - if(server.seat.focused_output) |output| { - L.pushInteger(@intCast(output.id)); - return 1; - } + if (server.seat.focused_output) |output| { + L.pushInteger(@intCast(output.id)); + return 1; + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } /// ---Get refresh rate for the output /// ---@param output_id output_id 0 maps to focused output /// ---@return integer? pub fn get_rate(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - L.pushInteger(@intCast(o.wlr_output.refresh)); + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + L.pushInteger(@intCast(o.wlr_output.refresh)); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } /// ---Get resolution in pixels of the output /// ---@param output_id output_id 0 maps to focused output /// ---@return { width: integer, height: integer }? pub fn get_resolution(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - L.newTable(); + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + L.newTable(); - _ = L.pushString("width"); - L.pushInteger(@intCast(o.wlr_output.width)); - L.setTable(-3); + _ = L.pushString("width"); + L.pushInteger(@intCast(o.wlr_output.width)); + L.setTable(-3); - _ = L.pushString("height"); - L.pushInteger(@intCast(o.wlr_output.height)); - L.setTable(-3); + _ = L.pushString("height"); + L.pushInteger(@intCast(o.wlr_output.height)); + L.setTable(-3); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } /// ---Get the serial for the output /// ---@param output_id output_id 0 maps to focused output /// ---@return string? pub fn get_serial(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - if(o.wlr_output.serial == null) { - L.pushNil(); - return 1; + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + if (o.wlr_output.serial == null) { + L.pushNil(); + return 1; + } + + _ = L.pushString(std.mem.span(o.wlr_output.serial.?)); + return 1; } - _ = L.pushString(std.mem.span(o.wlr_output.serial.?)); + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } /// ---Get the make for the output /// ---@param output_id output_id 0 maps to focused output /// ---@return string? pub fn get_make(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - if(o.wlr_output.make == null) { - L.pushNil(); - return 1; + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + if (o.wlr_output.make == null) { + L.pushNil(); + return 1; + } + + _ = L.pushString(std.mem.span(o.wlr_output.make.?)); + return 1; } - _ = L.pushString(std.mem.span(o.wlr_output.make.?)); + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } /// ---Get the model for the output /// ---@param output_id output_id 0 maps to focused output /// ---@return stirng? pub fn get_model(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - if(o.wlr_output.model == null) { - L.pushNil(); - return 1; + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + if (o.wlr_output.model == null) { + L.pushNil(); + return 1; + } + + _ = L.pushString(std.mem.span(o.wlr_output.model.?)); + return 1; } - _ = L.pushString(std.mem.span(o.wlr_output.model.?)); + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } /// ---Get the description for the output /// ---@param output_id output_id 0 maps to focused output /// ---@return stirng? pub fn get_description(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - if(o.wlr_output.description == null) { - L.pushNil(); - return 1; + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + if (o.wlr_output.description == null) { + L.pushNil(); + return 1; + } + + _ = L.pushString(std.mem.span(o.wlr_output.description.?)); + return 1; } - _ = L.pushString(std.mem.span(o.wlr_output.description.?)); + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } /// ---Get the name of the output /// ---@param output_id output_id 0 maps to focused output /// ---@return stirng pub fn get_name(L: *zlua.Lua) i32 { - const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); + const output_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch output_id_err(L); - const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); - if(output) |o| { - _ = L.pushString(std.mem.span(o.wlr_output.name)); + const output: ?*Output = if (output_id == 0) server.seat.focused_output else server.root.outputById(output_id); + if (output) |o| { + _ = L.pushString(std.mem.span(o.wlr_output.name)); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } diff --git a/src/lua/Remote.zig b/src/lua/Remote.zig index b39505d..3a4514a 100644 --- a/src/lua/Remote.zig +++ b/src/lua/Remote.zig @@ -7,6 +7,6 @@ const LuaUtils = @import("LuaUtils.zig"); const RemoteLua = @import("../RemoteLua.zig"); pub fn print(L: *zlua.Lua) i32 { - RemoteLua.sendNewLogEntry(L.checkString(1)); - return 0; + RemoteLua.sendNewLogEntry(L.checkString(1)); + return 0; } diff --git a/src/lua/View.zig b/src/lua/View.zig index 220a40f..b110855 100644 --- a/src/lua/View.zig +++ b/src/lua/View.zig @@ -11,7 +11,7 @@ const LuaUtils = @import("LuaUtils.zig"); const server = &@import("../main.zig").server; fn view_id_err(L: *zlua.Lua) noreturn { - L.raiseErrorStr("The view id must be >= 0 and < inf", .{}); + L.raiseErrorStr("The view id must be >= 0 and < inf", .{}); } // This allows us to differentiate random numbers from ids @@ -20,84 +20,83 @@ fn view_id_err(L: *zlua.Lua) noreturn { // ---Get the ids for all available views // ---@return view_id[]? pub fn get_all_ids(L: *zlua.Lua) i32 { - var output_it = server.root.output_layout.outputs.iterator(.forward); + var output_it = server.root.output_layout.outputs.iterator(.forward); - var index: i32 = 1; - L.newTable(); + var index: i32 = 1; + L.newTable(); - while(output_it.next()) |o| { - if(o.output.data == null) { - std.log.err("Output arbitrary data not assigned", .{}); - unreachable; - } - - const output: *Output = @ptrCast(@alignCast(o.output.data.?)); - if (!output.state.enabled) continue; - - // Only search the content and fullscreen layers for views - const layers = [_]*wlr.SceneTree{ - output.layers.content, - output.layers.fullscreen, - }; - - for(layers) |layer| { - if(layer.children.length() == 0) continue; // No children - - if(@intFromPtr(layer) == 0) { - std.log.err("ts is literally a null ptr", .{}); - unreachable; - } - - var view_it = layer.children.iterator(.forward); - - while(view_it.next()) |v| { - - if(v.data == null) { - std.log.err("Unassigned arbitrary data in scene graph", .{}); - unreachable; + while (output_it.next()) |o| { + if (o.output.data == null) { + std.log.err("Output arbitrary data not assigned", .{}); + unreachable; } - const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(v.data.?)); + const output: *Output = @ptrCast(@alignCast(o.output.data.?)); + if (!output.state.enabled) continue; - if(scene_node_data.* == .view) { - L.pushInteger(@intCast(index)); - L.pushInteger(@intCast(scene_node_data.view.id)); - L.setTable(-3); + // Only search the content and fullscreen layers for views + const layers = [_]*wlr.SceneTree{ + output.layers.content, + output.layers.fullscreen, + }; - index += 1; + for (layers) |layer| { + if (layer.children.length() == 0) continue; // No children + + if (@intFromPtr(layer) == 0) { + std.log.err("ts is literally a null ptr", .{}); + unreachable; + } + + var view_it = layer.children.iterator(.forward); + + while (view_it.next()) |v| { + if (v.data == null) { + std.log.err("Unassigned arbitrary data in scene graph", .{}); + unreachable; + } + + const scene_node_data: *SceneNodeData = @ptrCast(@alignCast(v.data.?)); + + if (scene_node_data.* == .view) { + L.pushInteger(@intCast(index)); + L.pushInteger(@intCast(scene_node_data.view.id)); + L.setTable(-3); + + index += 1; + } + } } - } } - } - return 1; + return 1; } // ---Get the id for the focused view // ---@return view_id? pub fn get_focused_id(L: *zlua.Lua) i32 { - if(server.seat.focused_surface) |fs| { - if(fs == .view) { - L.pushInteger(@intCast(fs.view.id)); - return 1; + if (server.seat.focused_surface) |fs| { + if (fs == .view) { + L.pushInteger(@intCast(fs.view.id)); + return 1; + } } - } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Close the view with view_id // ---@param view_id view_id 0 maps to focused view pub fn close(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if(LuaUtils.viewById(view_id)) |v| { - v.close(); - } + if (LuaUtils.viewById(view_id)) |v| { + v.close(); + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---position the view by it's top left corner @@ -105,39 +104,39 @@ pub fn close(L: *zlua.Lua) i32 { // ---@param x number x position for view // ---@param y number y position for view pub fn set_position(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - const x = LuaUtils.coerceNumber(i32, L.checkNumber(2)) catch L.raiseErrorStr("The x must be > -inf and < inf", .{}); - const y = LuaUtils.coerceNumber(i32, L.checkNumber(3)) catch L.raiseErrorStr("The y must be > -inf and < inf", .{}); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const x = LuaUtils.coerceNumber(i32, L.checkNumber(2)) catch L.raiseErrorStr("The x must be > -inf and < inf", .{}); + const y = LuaUtils.coerceNumber(i32, L.checkNumber(3)) catch L.raiseErrorStr("The y must be > -inf and < inf", .{}); - if(LuaUtils.viewById(view_id)) |v| { - v.setPosition(x, y); - } + if (LuaUtils.viewById(view_id)) |v| { + v.setPosition(x, y); + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Get the position of the view // ---@param view_id view_id 0 maps to focused view // ---@return { x: integer, y: integer }? Position of the view pub fn get_position(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if (LuaUtils.viewById(view_id)) |v| { - L.newTable(); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + if (LuaUtils.viewById(view_id)) |v| { + L.newTable(); - _ = L.pushString("x"); - L.pushInteger(@intCast(v.scene_tree.node.x)); - L.setTable(-3); + _ = L.pushString("x"); + L.pushInteger(@intCast(v.scene_tree.node.x)); + L.setTable(-3); - _ = L.pushString("y"); - L.pushInteger(@intCast(v.scene_tree.node.y)); - L.setTable(-3); + _ = L.pushString("y"); + L.pushInteger(@intCast(v.scene_tree.node.y)); + L.setTable(-3); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } // ---Set the size of the spesified view. Will be resized relative to @@ -145,234 +144,234 @@ pub fn get_position(L: *zlua.Lua) i32 { // ---@param view_id view_id 0 maps to focused view // ---@return pub fn set_size(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - // We use u32s here to enforce a minimum size of zero. The call to resize a - // toplevel requires a i32, which doesn't make too much sense as there's an - // assertion in the code enforcing that both the width and height are greater - // than or equal to zero. - const width = LuaUtils.coerceNumber(u32, L.checkNumber(2)) catch L.raiseErrorStr("The width must be >= 0 and < inf", .{}); - const height = LuaUtils.coerceNumber(u32, L.checkNumber(3)) catch L.raiseErrorStr("The height must be >= 0 and < inf", .{}); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + // We use u32s here to enforce a minimum size of zero. The call to resize a + // toplevel requires a i32, which doesn't make too much sense as there's an + // assertion in the code enforcing that both the width and height are greater + // than or equal to zero. + const width = LuaUtils.coerceNumber(u32, L.checkNumber(2)) catch L.raiseErrorStr("The width must be >= 0 and < inf", .{}); + const height = LuaUtils.coerceNumber(u32, L.checkNumber(3)) catch L.raiseErrorStr("The height must be >= 0 and < inf", .{}); - if(LuaUtils.viewById(view_id)) |v| { - v.setSize(@intCast(width), @intCast(height)); - } + if (LuaUtils.viewById(view_id)) |v| { + v.setSize(@intCast(width), @intCast(height)); + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Get the size of the view // ---@param view_id view_id 0 maps to focused view // ---@return { width: integer, height: integer }? Size of the view pub fn get_size(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if (LuaUtils.viewById(view_id)) |v| { - L.newTable(); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + if (LuaUtils.viewById(view_id)) |v| { + L.newTable(); - _ = L.pushString("width"); - L.pushInteger(@intCast(v.xdg_toplevel.current.width)); - L.setTable(-3); + _ = L.pushString("width"); + L.pushInteger(@intCast(v.xdg_toplevel.current.width)); + L.setTable(-3); - _ = L.pushString("height"); - L.pushInteger(@intCast(v.xdg_toplevel.current.height)); - L.setTable(-3); + _ = L.pushString("height"); + L.pushInteger(@intCast(v.xdg_toplevel.current.height)); + L.setTable(-3); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } // ---Remove focus from current view, and set to given id // ---@param view_id view_id Id of the view to be focused, or nil to remove focus pub fn set_focused(L: *zlua.Lua) i32 { - const view_id: ?c_longlong = L.optInteger(1); + const view_id: ?c_longlong = L.optInteger(1); - if(view_id == null) { - server.seat.focusSurface(null); - } else if(server.root.viewById(@intCast(view_id.?))) |view| { - server.seat.focusSurface(.{ .view = view }); - } + if (view_id == null) { + server.seat.focusSurface(null); + } else if (server.root.viewById(@intCast(view_id.?))) |view| { + server.seat.focusSurface(.{ .view = view }); + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Toggle the view to enter fullscreen. Will enter the fullsreen // layer. // ---@param view_id view_id 0 maps to focused view pub fn toggle_fullscreen(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - std.log.debug("fullscreen view {d}", .{view_id}); - if(LuaUtils.viewById(view_id)) |v| { - std.log.debug("toggling fullscreen", .{}); - v.toggleFullscreen(); - } + std.log.debug("fullscreen view {d}", .{view_id}); + if (LuaUtils.viewById(view_id)) |v| { + std.log.debug("toggling fullscreen", .{}); + v.toggleFullscreen(); + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Get the title of the view // ---@param view_id view_id 0 maps to focused view // ---@return string? pub fn get_title(L: *zlua.Lua) i32 { - const view_id: u64 = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id: u64 = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if(LuaUtils.viewById(view_id)) |v| { - if(v.xdg_toplevel.title == null) { - L.pushNil(); - return 1; + if (LuaUtils.viewById(view_id)) |v| { + if (v.xdg_toplevel.title == null) { + L.pushNil(); + return 1; + } + + _ = L.pushString(std.mem.span(v.xdg_toplevel.title.?)); + return 1; } - _ = L.pushString(std.mem.span(v.xdg_toplevel.title.?)); + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } // ---Get the app_id of the view // ---@param view_id view_id 0 maps to focused view // ---@return string? pub fn get_app_id(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if(LuaUtils.viewById(view_id)) |v| { - if(v.xdg_toplevel.app_id == null) { - L.pushNil(); - return 1; + if (LuaUtils.viewById(view_id)) |v| { + if (v.xdg_toplevel.app_id == null) { + L.pushNil(); + return 1; + } + + _ = L.pushString(std.mem.span(v.xdg_toplevel.app_id.?)); + return 1; } - _ = L.pushString(std.mem.span(v.xdg_toplevel.app_id.?)); + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } // ---Enable or disable a view // ---@param view_id view_id 0 maps to focused view // ---@param enabled boolean pub fn set_enabled(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if (!L.isBoolean(2)) { - L.raiseErrorStr("argument 2 must be a boolean", .{}); - } - const activate = L.toBoolean(2); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + if (!L.isBoolean(2)) { + L.raiseErrorStr("argument 2 must be a boolean", .{}); + } + const activate = L.toBoolean(2); - if (LuaUtils.viewById(view_id)) |v| { - _ = v.xdg_toplevel.setActivated(activate); - return 0; - } + if (LuaUtils.viewById(view_id)) |v| { + _ = v.xdg_toplevel.setActivated(activate); + return 0; + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Check if a view is enabled // ---@param view_id view_id 0 maps to focused view // ---@return boolean? pub fn get_enabled(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if(LuaUtils.viewById(view_id)) |v| { - _ = L.pushBoolean(v.xdg_toplevel.current.activated); + if (LuaUtils.viewById(view_id)) |v| { + _ = L.pushBoolean(v.xdg_toplevel.current.activated); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } // ---Set a view you intend to resize // ---@param view_id view_id 0 maps to focused view // ---@param enable boolean pub fn set_resizing(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if (!L.isBoolean(2)) { - L.raiseErrorStr("argument 2 must be a boolean", .{}); - } - const resizing = L.toBoolean(2); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + if (!L.isBoolean(2)) { + L.raiseErrorStr("argument 2 must be a boolean", .{}); + } + const resizing = L.toBoolean(2); - if (LuaUtils.viewById(view_id)) |v| { - _ = v.xdg_toplevel.setResizing(resizing); - return 0; - } + if (LuaUtils.viewById(view_id)) |v| { + _ = v.xdg_toplevel.setResizing(resizing); + return 0; + } - L.pushNil(); - return 1; + L.pushNil(); + return 1; } // ---Check if a view is resizing // ---@param view_id view_id 0 maps to focused view // ---@return boolean? nil if view cannot be found pub fn get_resizing(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - if(LuaUtils.viewById(view_id)) |v| { - _ = L.pushBoolean(v.xdg_toplevel.current.resizing); + if (LuaUtils.viewById(view_id)) |v| { + _ = L.pushBoolean(v.xdg_toplevel.current.resizing); + return 1; + } + + L.pushNil(); return 1; - } - - L.pushNil(); - return 1; } // ---Set the borders of a view // ---@param view_id view_id 0 maps to focused view /// ---@param options table options for the view's borders pub fn set_border(L: *zlua.Lua) i32 { - const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); + const view_id = LuaUtils.coerceInteger(u64, L.checkInteger(1)) catch view_id_err(L); - _ = L.pushString("color"); - _ = L.getTable(2); - if (!L.isString(-1)) L.raiseErrorStr("The color must be a string", .{}); - const color = L.checkString(-1); - const border_color: [4]f32 = color: { - errdefer L.raiseErrorStr("The color must be a valid hex string", .{}); + _ = L.pushString("color"); + _ = L.getTable(2); + if (!L.isString(-1)) L.raiseErrorStr("The color must be a string", .{}); + const color = L.checkString(-1); + const border_color: [4]f32 = color: { + errdefer L.raiseErrorStr("The color must be a valid hex string", .{}); - var start_color_idx: u8 = 0; - if (color[0] == '#') start_color_idx = 1; - const color_fields = (color.len - start_color_idx) / 2; + var start_color_idx: u8 = 0; + if (color[0] == '#') start_color_idx = 1; + const color_fields = (color.len - start_color_idx) / 2; - var alpha: ?f32 = null; - if (color_fields != 4) { - if (color_fields != 3) L.raiseErrorStr("The color must be at least 6 characters long", .{}); - alpha = 1; - } + var alpha: ?f32 = null; + if (color_fields != 4) { + if (color_fields != 3) L.raiseErrorStr("The color must be at least 6 characters long", .{}); + alpha = 1; + } - const r = ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx..start_color_idx + 2], 16))) / 255.0) * 1000.0) / 1000.0; - const g = ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx + 2..start_color_idx + 4], 16))) / 255.0) * 1000.0) / 1000.0; - const b = ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx + 4..start_color_idx + 6], 16))) / 255.0) * 1000.0) / 1000.0; - const a = alpha orelse ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx + 6..start_color_idx + 8], 16))) / 255.0) * 1000.0) / 1000.0; + const r = ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx .. start_color_idx + 2], 16))) / 255.0) * 1000.0) / 1000.0; + const g = ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx + 2 .. start_color_idx + 4], 16))) / 255.0) * 1000.0) / 1000.0; + const b = ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx + 4 .. start_color_idx + 6], 16))) / 255.0) * 1000.0) / 1000.0; + const a = alpha orelse ((@as(f32, @floatFromInt(try std.fmt.parseInt(u8, color[start_color_idx + 6 .. start_color_idx + 8], 16))) / 255.0) * 1000.0) / 1000.0; - break :color .{ r, g, b, a }; - }; + break :color .{ r, g, b, a }; + }; - _ = L.pushString("width"); - _ = L.getTable(2); - const width = LuaUtils.coerceInteger(u32, L.checkInteger(-1)) catch { - L.raiseErrorStr("The border width must be >= 0 and < inf", .{}); - }; + _ = L.pushString("width"); + _ = L.getTable(2); + const width = LuaUtils.coerceInteger(u32, L.checkInteger(-1)) catch { + L.raiseErrorStr("The border width must be >= 0 and < inf", .{}); + }; - if (LuaUtils.viewById(view_id)) |v| { - v.setBorderColor(&border_color); + if (LuaUtils.viewById(view_id)) |v| { + v.setBorderColor(&border_color); - if (width != v.border_width) { - v.border_width = @intCast(width); - // the size has changed which means we need to update the borders - v.resizeBorders(); + if (width != v.border_width) { + v.border_width = @intCast(width); + // the size has changed which means we need to update the borders + v.resizeBorders(); + } + + return 0; } return 0; - } - - return 0; } /// TODO: impl @@ -383,6 +382,6 @@ pub fn set_border(L: *zlua.Lua) i32 { /// NOTE(squibid): this should be handled by the layout_manager to reduce the /// work required by the user pub fn setWmCapabilities(L: *zlua.Lua) i32 { - _ = L; - return 0; + _ = L; + return 0; } diff --git a/src/main.zig b/src/main.zig index 7793cdb..ceb9d78 100644 --- a/src/main.zig +++ b/src/main.zig @@ -27,66 +27,66 @@ const args = ; pub fn main() !void { - const params = comptime clap.parseParamsComptime(args); - var diag = clap.Diagnostic{}; - const parsers = comptime .{ - .path = clap.parsers.string, - .command = clap.parsers.string, - }; - var res = clap.parse(clap.Help, ¶ms, parsers, .{ - .diagnostic = &diag, - .allocator = gpa, - }) catch |err| { - try diag.reportToFile(.stderr(), err); - return err; - }; - defer res.deinit(); + const params = comptime clap.parseParamsComptime(args); + var diag = clap.Diagnostic{}; + const parsers = comptime .{ + .path = clap.parsers.string, + .command = clap.parsers.string, + }; + var res = clap.parse(clap.Help, ¶ms, parsers, .{ + .diagnostic = &diag, + .allocator = gpa, + }) catch |err| { + try diag.reportToFile(.stderr(), err); + return err; + }; + defer res.deinit(); - if (res.args.help == 1) { - try @constCast(&std.fs.File.stdout().writer(&[_]u8{}).interface).writeAll(usage); - std.process.exit(0); - } - if (res.args.version == 1) { - try @constCast(&std.fs.File.stdout().writer(&[_]u8{}).interface).writeAll(config.version); - std.process.exit(0); - } + if (res.args.help == 1) { + try @constCast(&std.fs.File.stdout().writer(&[_]u8{}).interface).writeAll(usage); + std.process.exit(0); + } + if (res.args.version == 1) { + try @constCast(&std.fs.File.stdout().writer(&[_]u8{}).interface).writeAll(config.version); + std.process.exit(0); + } - var lua_config: Lua.Config = .{ .enabled = true, .str = null }; - if (res.args.u != null and res.args.clean == 1) { - std.debug.panic("You cannot set both -u and --clean", .{}); - } else if (res.args.u != null) { - // this is freed in lua/lua.zig - const path = try std.fs.cwd().realpathAlloc(gpa, res.args.u.?); - lua_config.str = path; - } else if (res.args.clean == 1) { - lua_config.enabled = false; - } + var lua_config: Lua.Config = .{ .enabled = true, .str = null }; + if (res.args.u != null and res.args.clean == 1) { + std.debug.panic("You cannot set both -u and --clean", .{}); + } else if (res.args.u != null) { + // this is freed in lua/lua.zig + const path = try std.fs.cwd().realpathAlloc(gpa, res.args.u.?); + lua_config.str = path; + } else if (res.args.clean == 1) { + lua_config.enabled = false; + } - wlr.log.init(.err, null); - std.log.info("Starting mezzaluna", .{}); + wlr.log.init(.err, null); + std.log.info("Starting mezzaluna", .{}); - server.init(); - defer server.deinit(); - try lua.init(lua_config); + server.init(); + defer server.deinit(); + try lua.init(lua_config); - var buf: [11]u8 = undefined; - const socket = try server.wl_server.addSocketAuto(&buf); + 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); + env_map = try std.process.getEnvMap(gpa); + try env_map.put("WAYLAND_DISPLAY", socket); - if (res.args.c) |cmd| { - var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa); - child.env_map = &env_map; - try child.spawn(); - } - defer env_map.deinit(); + if (res.args.c) |cmd| { + var child = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, gpa); + child.env_map = &env_map; + try child.spawn(); + } + defer env_map.deinit(); - std.log.info("Starting backend", .{}); - server.backend.start() catch |err| { - std.debug.panic("Failed to start backend: {}", .{err}); - }; + std.log.info("Starting backend", .{}); + server.backend.start() catch |err| { + std.debug.panic("Failed to start backend: {}", .{err}); + }; - std.log.info("Starting server", .{}); - server.wl_server.run(); + std.log.info("Starting server", .{}); + server.wl_server.run(); } diff --git a/src/types/Events.zig b/src/types/Events.zig index f437856..b13355c 100644 --- a/src/types/Events.zig +++ b/src/types/Events.zig @@ -7,53 +7,53 @@ const Hook = @import("Hook.zig"); const server = &@import("../main.zig").server; const Node = struct { - hook: *const Hook, - node: std.SinglyLinkedList.Node, + hook: *const Hook, + node: std.SinglyLinkedList.Node, }; events: std.StringHashMap(*std.SinglyLinkedList), allocator: std.mem.Allocator, pub fn init(allocator: std.mem.Allocator) !Events { - return Events{ - .allocator = allocator, - .events = .init(allocator), - }; + return Events{ + .allocator = allocator, + .events = .init(allocator), + }; } pub fn put(self: *Events, key: []const u8, hook: *const Hook) !void { - var ll: *std.SinglyLinkedList = undefined; - if (self.events.get(key)) |sll| { - ll = sll; - } else { - ll = try self.allocator.create(std.SinglyLinkedList); - ll.* = .{}; - try self.events.put(key, ll); - } - const data = try self.allocator.create(Node); - data.* = .{ - .hook = hook, - .node = .{}, - }; - ll.prepend(&data.node); + var ll: *std.SinglyLinkedList = undefined; + if (self.events.get(key)) |sll| { + ll = sll; + } else { + ll = try self.allocator.create(std.SinglyLinkedList); + ll.* = .{}; + try self.events.put(key, ll); + } + const data = try self.allocator.create(Node); + data.* = .{ + .hook = hook, + .node = .{}, + }; + ll.prepend(&data.node); } pub fn del(self: *Events, key: []const u8, hook: *const Hook) void { - if (self.events.get(key)) |e| { - var node = e.first; - while (node) |n| : (node = n.next) { - const data: *Node = @fieldParentPtr("node", n); - if (data.hook.options.lua_cb_ref_idx == hook.options.lua_cb_ref_idx) e.remove(n); + if (self.events.get(key)) |e| { + var node = e.first; + while (node) |n| : (node = n.next) { + const data: *Node = @fieldParentPtr("node", n); + if (data.hook.options.lua_cb_ref_idx == hook.options.lua_cb_ref_idx) e.remove(n); + } } - } } pub fn exec(self: *Events, event: []const u8, args: anytype) void { - if (self.events.get(event)) |e| { - var node = e.first; - while (node) |n| : (node = n.next) { - const data: *Node = @fieldParentPtr("node", n); - data.hook.callback(args); + if (self.events.get(event)) |e| { + var node = e.first; + while (node) |n| : (node = n.next) { + const data: *Node = @fieldParentPtr("node", n); + data.hook.callback(args); + } } - } } diff --git a/src/types/Hook.zig b/src/types/Hook.zig index 6c6a155..c3c3aa4 100644 --- a/src/types/Hook.zig +++ b/src/types/Hook.zig @@ -13,34 +13,34 @@ const Lua = &@import("../main.zig").lua; events: [][]const u8, // a list of events options: struct { - // group: []const u8, // TODO: do we need groups? - /// This is the location of the callback lua function in the lua registry - lua_cb_ref_idx: i32, + // group: []const u8, // TODO: do we need groups? + /// This is the location of the callback lua function in the lua registry + lua_cb_ref_idx: i32, }, pub fn callback(self: *const Hook, args: anytype) void { - const ArgsType = @TypeOf(args); - const args_type_info = @typeInfo(ArgsType); - if (args_type_info != .@"struct") { - @compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType)); - } + const ArgsType = @TypeOf(args); + const args_type_info = @typeInfo(ArgsType); + if (args_type_info != .@"struct") { + @compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType)); + } - const t = Lua.state.rawGetIndex(zlua.registry_index, self.options.lua_cb_ref_idx); - if (t != zlua.LuaType.function) { - RemoteLua.sendNewLogEntry("Failed to call hook, it doesn't have a callback."); - Lua.state.pop(1); - return; - } + const t = Lua.state.rawGetIndex(zlua.registry_index, self.options.lua_cb_ref_idx); + if (t != zlua.LuaType.function) { + RemoteLua.sendNewLogEntry("Failed to call hook, it doesn't have a callback."); + Lua.state.pop(1); + return; + } - // allow passing any arguments to the lua hook - var i: u8 = 0; - inline for (args, 1..) |field, k| { - try Lua.state.pushAny(field); - i = k; - } + // allow passing any arguments to the lua hook + var i: u8 = 0; + inline for (args, 1..) |field, k| { + try Lua.state.pushAny(field); + i = k; + } - Lua.state.protectedCall(.{ .args = i }) catch { - RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); - }; - Lua.state.pop(-1); + Lua.state.protectedCall(.{ .args = i }) catch { + RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); + }; + Lua.state.pop(-1); } diff --git a/src/types/Keymap.zig b/src/types/Keymap.zig index 57f4c74..07923a7 100644 --- a/src/types/Keymap.zig +++ b/src/types/Keymap.zig @@ -14,31 +14,31 @@ const Lua = &@import("../main.zig").lua; modifier: wlr.Keyboard.ModifierMask, keycode: xkb.Keysym, options: struct { - repeat: bool, - /// This is the location of the on press lua function in the lua registry - lua_press_ref_idx: i32, - /// This is the location of the on release lua function in the lua registry - lua_release_ref_idx: i32, + repeat: bool, + /// This is the location of the on press lua function in the lua registry + lua_press_ref_idx: i32, + /// This is the location of the on release lua function in the lua registry + lua_release_ref_idx: i32, }, pub fn callback(self: *const Keymap, release: bool) void { - const lua_ref_idx = if (release) self.options.lua_release_ref_idx else self.options.lua_press_ref_idx; + const lua_ref_idx = if (release) self.options.lua_release_ref_idx else self.options.lua_press_ref_idx; - const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx); - if (t != zlua.LuaType.function) { - RemoteLua.sendNewLogEntry("Failed to call keybind, it doesn't have a callback."); - Lua.state.pop(1); - return; - } + const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx); + if (t != zlua.LuaType.function) { + RemoteLua.sendNewLogEntry("Failed to call keybind, it doesn't have a callback."); + Lua.state.pop(1); + return; + } - Lua.state.protectedCall(.{ .args = 0, .results = 0 }) catch { - RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); - }; - Lua.state.pop(-1); + Lua.state.protectedCall(.{ .args = 0, .results = 0 }) catch { + RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); + }; + Lua.state.pop(-1); } pub fn hash(modifier: wlr.Keyboard.ModifierMask, keycode: xkb.Keysym) u64 { - const mod_val: u32 = @bitCast(modifier); - const key_val: u32 = @intFromEnum(keycode); - return (@as(u64, mod_val) << 32) | @as(u64, key_val); + const mod_val: u32 = @bitCast(modifier); + const key_val: u32 = @intFromEnum(keycode); + return (@as(u64, mod_val) << 32) | @as(u64, key_val); } diff --git a/src/types/Mousemap.zig b/src/types/Mousemap.zig index 0237e8d..7fd2fde 100644 --- a/src/types/Mousemap.zig +++ b/src/types/Mousemap.zig @@ -14,55 +14,55 @@ const Lua = &@import("../main.zig").lua; modifier: wlr.Keyboard.ModifierMask, event_code: i32, options: struct { - /// This is the location of the on press lua function in the lua registry - lua_press_ref_idx: i32, - /// This is the location of the on release lua function in the lua registry - lua_release_ref_idx: i32, - /// This is the location of the on drag lua function in the lua registry - lua_drag_ref_idx: i32, + /// This is the location of the on press lua function in the lua registry + lua_press_ref_idx: i32, + /// This is the location of the on release lua function in the lua registry + lua_release_ref_idx: i32, + /// This is the location of the on drag lua function in the lua registry + lua_drag_ref_idx: i32, }, pub const MousemapState = enum { press, drag, release }; // Returns true if mouse input should be passed through pub fn callback(self: *const Mousemap, state: MousemapState, args: anytype) bool { - const ArgsType = @TypeOf(args); - const args_type_info = @typeInfo(ArgsType); - if (args_type_info != .@"struct") { - @compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType)); - } + const ArgsType = @TypeOf(args); + const args_type_info = @typeInfo(ArgsType); + if (args_type_info != .@"struct") { + @compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType)); + } - const lua_ref_idx = switch(state) { - .press => self.options.lua_press_ref_idx, - .release => self.options.lua_release_ref_idx, - .drag => self.options.lua_drag_ref_idx - }; + const lua_ref_idx = switch (state) { + .press => self.options.lua_press_ref_idx, + .release => self.options.lua_release_ref_idx, + .drag => self.options.lua_drag_ref_idx, + }; - const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx); - if (t != zlua.LuaType.function) { - RemoteLua.sendNewLogEntry("Failed to call mousemap, it doesn't have a callback."); - Lua.state.pop(1); - return false; - } + const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx); + if (t != zlua.LuaType.function) { + RemoteLua.sendNewLogEntry("Failed to call mousemap, it doesn't have a callback."); + Lua.state.pop(1); + return false; + } - // allow passing any arguments to the lua hook - var i: u8 = 0; - inline for (args, 1..) |field, k| { - try Lua.state.pushAny(field); - i = k; - } + // allow passing any arguments to the lua hook + var i: u8 = 0; + inline for (args, 1..) |field, k| { + try Lua.state.pushAny(field); + i = k; + } - Lua.state.protectedCall(.{ .args = i, .results = 1 }) catch { - RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); - }; + Lua.state.protectedCall(.{ .args = i, .results = 1 }) catch { + RemoteLua.sendNewLogEntry(Lua.state.toString(-1) catch unreachable); + }; - const ret = if (Lua.state.isBoolean(-1)) Lua.state.toBoolean(-1) else false; - Lua.state.pop(-1); - return ret; + const ret = if (Lua.state.isBoolean(-1)) Lua.state.toBoolean(-1) else false; + Lua.state.pop(-1); + return ret; } pub fn hash(modifier: wlr.Keyboard.ModifierMask, event_code: i32) u64 { - const mod_val: u32 = @bitCast(modifier); - const button_val: u32 = @bitCast(event_code); - return (@as(u64, mod_val) << 32) | @as(u64, button_val); + const mod_val: u32 = @bitCast(modifier); + const button_val: u32 = @bitCast(event_code); + return (@as(u64, mod_val) << 32) | @as(u64, button_val); }