allow borders to be configured using lua

This commit is contained in:
Squibid 2026-03-01 21:28:53 -05:00
parent b24c16b34e
commit e6a45f91b6
Signed by: squibid
GPG key ID: BECE5684D3C4005D
3 changed files with 68 additions and 3 deletions

View file

@ -96,6 +96,15 @@ local master = function()
end end
}) })
mez.hook.add("ViewMapPre", {
callback = function(v)
mez.view.set_border(v, {
color = "#ff0000",
width = 4,
})
end
})
mez.hook.add("ViewUnmapPost", { mez.hook.add("ViewUnmapPost", {
callback = function(v) callback = function(v)
if v == ctx.tags[ctx.tag_id].master then if v == ctx.tags[ctx.tag_id].master then

View file

@ -74,7 +74,7 @@ pub fn init(xdg_toplevel: *wlr.XdgToplevel) *View {
.surface_tree = undefined, .surface_tree = undefined,
.xdg_toplevel_decoration = null, .xdg_toplevel_decoration = null,
.borders = undefined, .borders = undefined,
.border_width = 10, .border_width = 0,
.scene_node_data = .{ .view = self } .scene_node_data = .{ .view = self }
}; };
@ -97,7 +97,7 @@ pub fn init(xdg_toplevel: *wlr.XdgToplevel) *View {
self.xdg_toplevel.base.events.ack_configure.add(&self.ack_configure); self.xdg_toplevel.base.events.ack_configure.add(&self.ack_configure);
for (self.borders, 0..) |_, i| { for (self.borders, 0..) |_, i| {
const color: [4]f32 = .{ 1, 0, 0, 1 }; const color: [4]f32 = .{ 0, 0, 0, 1 };
self.borders[i] = try wlr.SceneTree.createSceneRect(self.scene_tree, 0, 0, &color); self.borders[i] = try wlr.SceneTree.createSceneRect(self.scene_tree, 0, 0, &color);
self.borders[i].node.data = self; self.borders[i].node.data = self;
} }
@ -111,6 +111,10 @@ 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);
}
pub fn toggleFullscreen(self: *View) void { pub fn toggleFullscreen(self: *View) void {
self.fullscreen = !self.fullscreen; self.fullscreen = !self.fullscreen;
if(self.output) |output| { if(self.output) |output| {
@ -169,7 +173,7 @@ pub fn setSize(self: *View, width: i32, height: i32) void {
/// this function handles all things related to sizing and positioning and /// this function handles all things related to sizing and positioning and
/// should be called after something in the size or position is changed /// should be called after something in the size or position is changed
fn resizeBorders(self: *View) void { pub fn resizeBorders(self: *View) void {
// set the position of the surface to not clip with the borders // set the position of the surface to not clip with the borders
self.surface_tree.node.setPosition(self.border_width, self.border_width); self.surface_tree.node.setPosition(self.border_width, self.border_width);

View file

@ -323,6 +323,58 @@ pub fn get_resizing(L: *zlua.Lua) i32 {
return 1; 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);
_ = 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 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;
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", .{});
};
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();
}
return 0;
}
return 0;
}
/// TODO: impl /// TODO: impl
/// Setting the wm capabilities is for telling the client what they can request. /// Setting the wm capabilities is for telling the client what they can request.
/// This is important to letting the user define whatever type of layout they /// This is important to letting the user define whatever type of layout they