reformatted with zig fmt

This commit is contained in:
Squibid 2026-03-01 22:23:31 -05:00
parent e6a45f91b6
commit 6be66b6a71
Signed by: squibid
GPG key ID: BECE5684D3C4005D
32 changed files with 2108 additions and 2237 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}