From ba4d403119a054e7c27b33016a0b78bf73eeed24 Mon Sep 17 00:00:00 2001 From: Squibid Date: Mon, 20 Oct 2025 18:28:40 -0400 Subject: [PATCH 1/5] omg lua in mez --- build.zig | 2 ++ build.zig.zon | 4 ++++ src/main.zig | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/build.zig b/build.zig index 2aa4bbe..753997c 100644 --- a/build.zig +++ b/build.zig @@ -31,6 +31,7 @@ pub fn build(b: *std.Build) void { 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", .{}).module("zlua"); wlroots.addImport("wayland", wayland); wlroots.addImport("xkbcommon", xkbcommon); @@ -53,6 +54,7 @@ pub fn build(b: *std.Build) void { 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.linkSystemLibrary("wayland-server"); mez.linkSystemLibrary("xkbcommon"); diff --git a/build.zig.zon b/build.zig.zon index 9715c07..6424066 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -20,6 +20,10 @@ .url = "https://codeberg.org/ifreund/zig-wlroots/archive/v0.19.3.tar.gz", .hash = "wlroots-0.19.3-jmOlcuL_AwBHhLCwpFsXbTizE3q9BugFmGX-XIxqcPMc", }, + .zlua = .{ + .url = "git+https://github.com/natecraddock/ziglua#39f8df588d0864070deffa308ef575bf492777a0", + .hash = "zlua-0.1.0-hGRpC6E9BQDBGKPqzmCRsI6Xd8jH9KohccmX69-L6HyS", + }, }, .paths = .{ "build.zig", diff --git a/src/main.zig b/src/main.zig index 03f816f..97c3abf 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,9 @@ const std = @import("std"); const wlr = @import("wlroots"); +const zlua = @import("zlua"); +const Lua = zlua.Lua; + const Server = @import("server.zig"); const gpa = std.heap.c_allocator; @@ -10,6 +13,11 @@ pub var server: Server = undefined; pub fn main() !void { wlr.log.init(.err, null); + var lua = try Lua.init(gpa); + defer lua.deinit(); + lua.openLibs(); + lua.doString("print('Hello from Lua embedded in Zig!')") catch {}; + std.log.info("Starting mezzaluna", .{}); try server.init(); From 86a01bbcf2a5bcc4a835b85f58776166eca477fb Mon Sep 17 00:00:00 2001 From: Squibid Date: Mon, 20 Oct 2025 22:53:17 -0400 Subject: [PATCH 2/5] load a runtime file where the prefix is determined at comptime --- build.zig | 12 +++++++++ runtime/share/mezzaluna/init.lua | 1 + src/lua.zig | 43 ++++++++++++++++++++++++++++++++ src/main.zig | 11 +++----- 4 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 runtime/share/mezzaluna/init.lua create mode 100644 src/lua.zig diff --git a/build.zig b/build.zig index 753997c..d12fdd0 100644 --- a/build.zig +++ b/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const Scanner = @import("wayland").Scanner; @@ -6,6 +7,13 @@ pub fn build(b: *std.Build) void { 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", + }; + // If instead your goal is to create an executable, consider if users might // be interested in also being able to embed the core functionality of your // program in their own executable in order to avoid the overhead involved in @@ -60,6 +68,10 @@ pub fn build(b: *std.Build) void { mez.linkSystemLibrary("xkbcommon"); mez.linkSystemLibrary("pixman-1"); + const options = b.addOptions(); + options.addOption([]const u8, "runtime_path_prefix", runtime_path_prefix); + mez.root_module.addOptions("config", options); + b.installArtifact(mez); const run_step = b.step("run", "Run the app"); diff --git a/runtime/share/mezzaluna/init.lua b/runtime/share/mezzaluna/init.lua new file mode 100644 index 0000000..33802c8 --- /dev/null +++ b/runtime/share/mezzaluna/init.lua @@ -0,0 +1 @@ +print("hello from our runtime file") diff --git a/src/lua.zig b/src/lua.zig new file mode 100644 index 0000000..357874c --- /dev/null +++ b/src/lua.zig @@ -0,0 +1,43 @@ +const Lua = @This(); + +const std = @import("std"); +const config = @import("config"); +const zlua = @import("zlua"); + +const gpa = std.heap.c_allocator; + +state: *zlua.Lua, + +fn loadRuntimeDir(self: *Lua) !void { + const tmppath = try std.fs.path.join(gpa, &[_][]const u8{ + config.runtime_path_prefix, + "share", + "mezzaluna", + "init.lua", + }); + var path_buffer = try gpa.alloc(u8, tmppath.len + 1); + std.mem.copyForwards(u8, path_buffer[0..tmppath.len], tmppath); + path_buffer[tmppath.len] = 0; + const path: [:0]u8 = path_buffer[0..tmppath.len :0]; + + try self.state.doFile(path); +} + +pub fn init(self: *Lua) !void { + self.state = try zlua.Lua.init(gpa); + errdefer self.state.deinit(); + self.state.openLibs(); + + { + self.state.newTable(); + defer _ = self.state.pushString("mez"); + } + + try loadRuntimeDir(self); + + std.log.debug("Loaded lua", .{}); +} + +pub fn deinit(self: *Lua) void { + self.state.deinit(); +} diff --git a/src/main.zig b/src/main.zig index 97c3abf..44fa4a7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,25 +1,20 @@ const std = @import("std"); const wlr = @import("wlroots"); -const zlua = @import("zlua"); -const Lua = zlua.Lua; - const Server = @import("server.zig"); +const Lua = @import("lua.zig"); const gpa = std.heap.c_allocator; pub var server: Server = undefined; +pub var lua: Lua = undefined; pub fn main() !void { wlr.log.init(.err, null); - var lua = try Lua.init(gpa); - defer lua.deinit(); - lua.openLibs(); - lua.doString("print('Hello from Lua embedded in Zig!')") catch {}; - std.log.info("Starting mezzaluna", .{}); + try lua.init(); try server.init(); defer server.deinit(); From 9e55195f8ded88664558394a6297d3e0f95627a2 Mon Sep 17 00:00:00 2001 From: Squibid Date: Wed, 22 Oct 2025 14:23:30 -0400 Subject: [PATCH 3/5] we're now loading a config file! --- runtime/share/mezzaluna/init.lua | 12 +++++- src/lua.zig | 43 ------------------- src/lua/bridge.zig | 28 +++++++++++++ src/lua/fs.zig | 0 src/lua/lua.zig | 72 ++++++++++++++++++++++++++++++++ src/main.zig | 2 +- 6 files changed, 112 insertions(+), 45 deletions(-) delete mode 100644 src/lua.zig create mode 100644 src/lua/bridge.zig create mode 100644 src/lua/fs.zig create mode 100644 src/lua/lua.zig diff --git a/runtime/share/mezzaluna/init.lua b/runtime/share/mezzaluna/init.lua index 33802c8..9976a90 100644 --- a/runtime/share/mezzaluna/init.lua +++ b/runtime/share/mezzaluna/init.lua @@ -1 +1,11 @@ -print("hello from our runtime file") +local env_conf = os.getenv("XDG_CONFIG_HOME") +if not env_conf then + env_conf = os.getenv("HOME") + if not env_conf then + error("Couldn't determine potential config directory is $HOME set?") + end + env_conf = env_conf.."/.config/" +end + +mez.path.config = env_conf.."/mez/init.lua" +package.path = package.path..";"..env_conf.."/mez/lua/?.lua" diff --git a/src/lua.zig b/src/lua.zig deleted file mode 100644 index 357874c..0000000 --- a/src/lua.zig +++ /dev/null @@ -1,43 +0,0 @@ -const Lua = @This(); - -const std = @import("std"); -const config = @import("config"); -const zlua = @import("zlua"); - -const gpa = std.heap.c_allocator; - -state: *zlua.Lua, - -fn loadRuntimeDir(self: *Lua) !void { - const tmppath = try std.fs.path.join(gpa, &[_][]const u8{ - config.runtime_path_prefix, - "share", - "mezzaluna", - "init.lua", - }); - var path_buffer = try gpa.alloc(u8, tmppath.len + 1); - std.mem.copyForwards(u8, path_buffer[0..tmppath.len], tmppath); - path_buffer[tmppath.len] = 0; - const path: [:0]u8 = path_buffer[0..tmppath.len :0]; - - try self.state.doFile(path); -} - -pub fn init(self: *Lua) !void { - self.state = try zlua.Lua.init(gpa); - errdefer self.state.deinit(); - self.state.openLibs(); - - { - self.state.newTable(); - defer _ = self.state.pushString("mez"); - } - - try loadRuntimeDir(self); - - std.log.debug("Loaded lua", .{}); -} - -pub fn deinit(self: *Lua) void { - self.state.deinit(); -} diff --git a/src/lua/bridge.zig b/src/lua/bridge.zig new file mode 100644 index 0000000..37868d3 --- /dev/null +++ b/src/lua/bridge.zig @@ -0,0 +1,28 @@ +const Bridge = @This(); + +const std = @import("std"); +const Lua = @import("lua.zig"); + +const gpa = std.heap.c_allocator; + +pub fn getNestedField(L: *Lua, path: []u8) bool { + 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.state.getGlobal(tok) catch return false; + first = false; + } else { + _ = L.state.getField(-1, tok); + L.state.remove(-2); + } + + if (L.state.isNil(-1)) { + return false; + } + } + + return true; +} diff --git a/src/lua/fs.zig b/src/lua/fs.zig new file mode 100644 index 0000000..e69de29 diff --git a/src/lua/lua.zig b/src/lua/lua.zig new file mode 100644 index 0000000..ae5c23b --- /dev/null +++ b/src/lua/lua.zig @@ -0,0 +1,72 @@ +const Lua = @This(); + +const std = @import("std"); +const config = @import("config"); +const zlua = @import("zlua"); + +const Bridge = @import("bridge.zig"); + +const gpa = std.heap.c_allocator; + +state: *zlua.Lua, + +fn loadRuntimeDir(self: *Lua) !void { + const tmppath = try std.fs.path.join(gpa, &[_][]const u8{ + config.runtime_path_prefix, + "share", + "mezzaluna", + "init.lua", + }); + const path = try gpa.dupeZ(u8, tmppath); + + self.state.doFile(path) catch { + const err = try self.state.toString(-1); + std.log.debug("Failed to run lua file: {s}", .{err}); + }; +} + +fn loadConfigDir(self: *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.state.toString(-1) catch |err| { + std.log.err("Failed to pop the config path from the lua stack. {}", .{err}); + return; + }; + self.state.pop(-1); + try self.state.doFile(path); +} + +pub fn init(self: *Lua) !void { + self.state = try zlua.Lua.init(gpa); + errdefer self.state.deinit(); + self.state.openLibs(); + + { + self.state.newTable(); + defer _ = self.state.setGlobal("mez"); + { + self.state.newTable(); + defer _ = self.state.setField(-2, "path"); + } + } + + loadRuntimeDir(self) catch |err| { + if (err == error.LuaRuntime) { + std.log.warn("{s}", .{try self.state.toString(-1)}); + } + }; + loadConfigDir(self) 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(); +} diff --git a/src/main.zig b/src/main.zig index 44fa4a7..586fc6c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,7 +2,7 @@ const std = @import("std"); const wlr = @import("wlroots"); const Server = @import("server.zig"); -const Lua = @import("lua.zig"); +const Lua = @import("lua/lua.zig"); const gpa = std.heap.c_allocator; From 8e4f56d1477b33a9c1eb66a68f8dd8534d446c88 Mon Sep 17 00:00:00 2001 From: Squibid Date: Wed, 22 Oct 2025 22:40:19 -0400 Subject: [PATCH 4/5] add a basic filesystem library and use it for path concat --- runtime/share/mezzaluna/init.lua | 6 ++--- src/lua/fs.zig | 43 ++++++++++++++++++++++++++++++++ src/lua/lua.zig | 6 +++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/runtime/share/mezzaluna/init.lua b/runtime/share/mezzaluna/init.lua index 9976a90..cfef496 100644 --- a/runtime/share/mezzaluna/init.lua +++ b/runtime/share/mezzaluna/init.lua @@ -4,8 +4,8 @@ if not env_conf then if not env_conf then error("Couldn't determine potential config directory is $HOME set?") end - env_conf = env_conf.."/.config/" + env_conf = mez.fs.joinpath(env_conf, ".config") end -mez.path.config = env_conf.."/mez/init.lua" -package.path = package.path..";"..env_conf.."/mez/lua/?.lua" +mez.path.config = mez.fs.joinpath(env_conf, "mez", "init.lua") +package.path = package.path..";"..mez.fs.joinpath(env_conf, "mez", "lua", "?.lua") diff --git a/src/lua/fs.zig b/src/lua/fs.zig index e69de29..3e5ea2c 100644 --- a/src/lua/fs.zig +++ b/src/lua/fs.zig @@ -0,0 +1,43 @@ +const Fs = @This(); + +const std = @import("std"); +const zlua = @import("zlua"); + +const Lua = @import("lua.zig"); + +const gpa = std.heap.c_allocator; + +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 { + return 0; + }; + 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 partial_path = L.toString(i) catch unreachable; + paths.append(gpa, partial_path) catch { + // TODO: tell lua? + return 0; + }; + } + + const final_path: []const u8 = std.fs.path.join(gpa, paths.items) catch { + // TODO: tell lua? + return 0; + }; + _ = L.pushString(final_path); + + return 1; +} diff --git a/src/lua/lua.zig b/src/lua/lua.zig index ae5c23b..7a3e6cd 100644 --- a/src/lua/lua.zig +++ b/src/lua/lua.zig @@ -5,6 +5,7 @@ const config = @import("config"); const zlua = @import("zlua"); const Bridge = @import("bridge.zig"); +const Fs = @import("fs.zig"); const gpa = std.heap.c_allocator; @@ -51,6 +52,11 @@ pub fn init(self: *Lua) !void { self.state.newTable(); defer _ = self.state.setField(-2, "path"); } + { + const funcs = zlua.fnRegsFromType(Fs); + self.state.newLib(funcs); + self.state.setField(-2, "fs"); + } } loadRuntimeDir(self) catch |err| { From faa44dc4af94d1d5bf637745fcb97fb9a88f9a09 Mon Sep 17 00:00:00 2001 From: Squibid Date: Thu, 23 Oct 2025 23:24:49 -0400 Subject: [PATCH 5/5] implement keymaps! they still have quite a bit of work to be any good... but now our key do stuff when pressed (at the compositor level) --- api.lua | 7 +++ runtime/share/mezzaluna/init.lua | 5 ++ src/keyboard.zig | 21 ++++---- src/keymap.zig | 37 +++++++++++++ src/lua/api.zig | 91 ++++++++++++++++++++++++++++++++ src/lua/lua.zig | 10 +++- src/main.zig | 2 +- src/server.zig | 3 ++ 8 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 src/keymap.zig create mode 100644 src/lua/api.zig diff --git a/api.lua b/api.lua index 3b8d7fd..cb25ff9 100644 --- a/api.lua +++ b/api.lua @@ -80,4 +80,11 @@ mez.options = { } } +---------------- Keybinds ---------------- +mez.add_keybind("modifier", "keycode", function() + -- callback +end, { + -- additional options +}) + -- Virtual terminal switching diff --git a/runtime/share/mezzaluna/init.lua b/runtime/share/mezzaluna/init.lua index cfef496..f11c827 100644 --- a/runtime/share/mezzaluna/init.lua +++ b/runtime/share/mezzaluna/init.lua @@ -9,3 +9,8 @@ end mez.path.config = mez.fs.joinpath(env_conf, "mez", "init.lua") package.path = package.path..";"..mez.fs.joinpath(env_conf, "mez", "lua", "?.lua") + +-- this is an example +-- mez.api.add_keymap("ctrl", "a", function() +-- print("hello from my keymap") +-- end) diff --git a/src/keyboard.zig b/src/keyboard.zig index 081fefe..1c133bd 100644 --- a/src/keyboard.zig +++ b/src/keyboard.zig @@ -3,6 +3,7 @@ const Keyboard = @This(); const std = @import("std"); const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; +const Keymap = @import("keymap.zig"); const wl = @import("wayland").server.wl; const wlr = @import("wlroots"); @@ -65,17 +66,17 @@ fn handleModifiers(_: *wl.Listener(*wlr.Keyboard), wlr_keyboard: *wlr.Keyboard) fn handleKey(_: *wl.Listener(*wlr.Keyboard.event.Key), event: *wlr.Keyboard.event.Key) void { // Translate libinput keycode -> xkbcommon - // const keycode = event.keycode + 8; + const keycode = event.keycode + 8; - // TODO: lua handle keybinds here - const handled = false; - if (server.keyboard.wlr_keyboard.getModifiers().alt and event.state == .pressed) { - // for (wlr_keyboard.xkb_state.?.keyGetSyms(keycode)) |sym| { - // if (keyboard.server.handleKeybind(sym)) { - // handled = true; - // break; - // } - // } + var handled = false; + const modifiers = server.keyboard.wlr_keyboard.getModifiers(); + for (server.keyboard.wlr_keyboard.xkb_state.?.keyGetSyms(keycode)) |sym| { + if (server.keymaps.get(Keymap.hash(modifiers, sym))) |map| { + if (event.state == .pressed and !map.options.on_release) { + map.callback(); + handled = true; + } + } } if (!handled) { diff --git a/src/keymap.zig b/src/keymap.zig new file mode 100644 index 0000000..c6363d6 --- /dev/null +++ b/src/keymap.zig @@ -0,0 +1,37 @@ +//! This is a simple way to define a keymap. To keep hashing consistent the +//! hash is generated here. +const Keymap = @This(); + +const std = @import("std"); + +const xkb = @import("xkbcommon"); +const wlr = @import("wlroots"); +const zlua = @import("zlua"); + +const Lua = &@import("main.zig").lua; + +modifier: wlr.Keyboard.ModifierMask, +keycode: xkb.Keysym, +/// This is the location of the lua function in the lua registry +lua_ref_idx: i32, +options: struct { + /// if false the callback is called on press + on_release: bool, +}, + +pub fn callback(self: *const Keymap) void { + const t = Lua.state.rawGetIndex(zlua.registry_index, self.lua_ref_idx); + if (t != zlua.LuaType.function) { + std.log.err("Failed to call keybind, it doesn't have a callback.", .{}); + return; + } + Lua.state.pushValue(1); + Lua.state.call(.{ .args = 0, .results = 0 }); + 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); +} diff --git a/src/lua/api.zig b/src/lua/api.zig new file mode 100644 index 0000000..0f097c6 --- /dev/null +++ b/src/lua/api.zig @@ -0,0 +1,91 @@ +const Api = @This(); + +const std = @import("std"); +const server = &@import("../main.zig").server; +const Keymap = @import("../keymap.zig"); + +const zlua = @import("zlua"); +const xkb = @import("xkbcommon"); +const wlr = @import("wlroots"); + +const gpa = std.heap.c_allocator; + +pub fn add_keymap(L: *zlua.Lua) i32 { + const nargs: i32 = L.getTop(); + if (nargs < 3) { + L.raiseErrorStr("Expected at least three arguments", .{}); + return 0; + } + + // ensure the first three agrs of the correct types + L.checkType(1, .string); + L.checkType(2, .string); + L.checkType(3, .function); + + var keymap: Keymap = undefined; + + const mod = L.toString(1) catch { + L.raiseErrorStr("Lua error check your config", .{}); + return 0; + }; + var it = std.mem.splitScalar(u8, mod, '|'); + var modifiers = wlr.Keyboard.ModifierMask{}; + while (it.next()) |m| { + // TODO: can we generate this at comptime? + if (std.mem.eql(u8, m, "shift")) { + modifiers.shift = true; + } else if (std.mem.eql(u8, m, "caps")) { + modifiers.caps = true; + } else if (std.mem.eql(u8, m, "ctrl")) { + modifiers.ctrl = true; + } else if (std.mem.eql(u8, m, "alt")) { + modifiers.alt = true; + } else if (std.mem.eql(u8, m, "mod2")) { + modifiers.mod2 = true; + } else if (std.mem.eql(u8, m, "mod3")) { + modifiers.mod3 = true; + } else if (std.mem.eql(u8, m, "logo")) { + modifiers.logo = true; + } else if (std.mem.eql(u8, m, "mod5")) { + modifiers.mod5 = true; + } + } + keymap.modifier = modifiers; + + const key = L.toString(2) catch { + L.raiseErrorStr("Lua error check your config", .{}); + return 0; + }; + keymap.keycode = xkb.Keysym.fromName(key, .no_flags); + + L.checkType(3, .function); + keymap.lua_ref_idx = L.ref(zlua.registry_index) catch { + L.raiseErrorStr("Lua error check your config", .{}); + return 0; + }; + + // FIXME: for som reason I can't seem to get this to validate that the 4th + // argument exists unless there's a 5th argument. It doesn't seem to matter + // what type the 5th is just that it's there. + if (nargs == 4) { + // L.checkType(4, .table); + // _ = L.pushString("on_release"); + // _ = L.getTable(4); + // const b = L.toBoolean(-1); + // L.pop(-1); + // L.pop(-1); + } + + const hash = Keymap.hash(keymap.modifier, keymap.keycode); + server.keymaps.put(hash, keymap) catch |err| { + std.log.err("Failed to add keymap to keymaps: {}", .{err}); + return 0; + }; + + return 0; +} + +pub fn get_keybind(L: *zlua.Lua) i32 { + _ = L; + return 0; +} diff --git a/src/lua/lua.zig b/src/lua/lua.zig index 7a3e6cd..e63df2d 100644 --- a/src/lua/lua.zig +++ b/src/lua/lua.zig @@ -6,6 +6,7 @@ const zlua = @import("zlua"); const Bridge = @import("bridge.zig"); const Fs = @import("fs.zig"); +const Api = @import("api.zig"); const gpa = std.heap.c_allocator; @@ -53,10 +54,15 @@ pub fn init(self: *Lua) !void { defer _ = self.state.setField(-2, "path"); } { - const funcs = zlua.fnRegsFromType(Fs); - self.state.newLib(funcs); + const fs_funcs = zlua.fnRegsFromType(Fs); + self.state.newLib(fs_funcs); self.state.setField(-2, "fs"); } + { + const api_funcs = zlua.fnRegsFromType(Api); + self.state.newLib(api_funcs); + self.state.setField(-2, "api"); + } } loadRuntimeDir(self) catch |err| { diff --git a/src/main.zig b/src/main.zig index 586fc6c..e4e77d5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -14,9 +14,9 @@ pub fn main() !void { std.log.info("Starting mezzaluna", .{}); - try lua.init(); try server.init(); defer server.deinit(); + try lua.init(); var buf: [11]u8 = undefined; const socket = try server.wl_server.addSocketAuto(&buf); diff --git a/src/server.zig b/src/server.zig index bf51592..34bb39a 100644 --- a/src/server.zig +++ b/src/server.zig @@ -10,6 +10,7 @@ const Cursor = @import("cursor.zig"); const Keyboard = @import("keyboard.zig"); const Output = @import("output.zig"); const View = @import("view.zig"); +const Keymap = @import("keymap.zig"); const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; @@ -32,6 +33,7 @@ root: Root, seat: Seat, cursor: Cursor, keyboard: Keyboard, +keymaps: std.AutoHashMap(u64, Keymap), // Backend listeners new_input: wl.Listener(*wlr.InputDevice) = .init(handleNewInput), @@ -69,6 +71,7 @@ pub fn init(self: *Server) !void { .seat = undefined, .cursor = undefined, .keyboard = undefined, + .keymaps = .init(gpa), }; try self.renderer.initServer(wl_server);