mirror of
https://codeberg.org/fairyglade/ly.git
synced 2026-08-20 20:44:19 +02:00
custom info: less buggy
This commit is contained in:
parent
2a31f19baa
commit
ecda6104ac
3 changed files with 146 additions and 24 deletions
|
|
@ -2,11 +2,25 @@ const std = @import("std");
|
|||
|
||||
const custom = @This();
|
||||
|
||||
pub const command = struct {
|
||||
pub const customCommandBind = struct {
|
||||
name: []const u8 = undefined,
|
||||
cmd: []const u8 = undefined,
|
||||
posX: u32 = 0,
|
||||
posY: u32 = 0,
|
||||
};
|
||||
|
||||
pub var mapping: std.StringHashMap(command) = undefined;
|
||||
pub const customCommandInfo = struct {
|
||||
cmd: []const u8 = undefined,
|
||||
/// SET TO LABELS WIDGET ID!!!
|
||||
id: u64 = 0,
|
||||
|
||||
/// In milliseconds, the refresh rate for the `cmd` to run again
|
||||
/// If 0, only run once.
|
||||
refresh: u32 = 0,
|
||||
counter: u32 = 0,
|
||||
posX: u32 = 0,
|
||||
posY: u32 = 0,
|
||||
};
|
||||
|
||||
pub var binds: std.StringHashMap(customCommandBind) = undefined;
|
||||
pub var labels: std.StringHashMap(customCommandInfo) = undefined;
|
||||
|
|
|
|||
|
|
@ -165,13 +165,13 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie
|
|||
if (std.mem.startsWith(u8, field.header, "cmd:")) {
|
||||
const key = field.header[4..];
|
||||
const keyZ = temporary_allocator.dupe(u8, key) catch @panic("FUCK");
|
||||
if (!CustomCommands.mapping.contains(key)) {
|
||||
CustomCommands.mapping.put(keyZ, .{}) catch |e| {
|
||||
std.log.err("CustomCommands: {} while putting for key {s}", .{e, key});
|
||||
@panic("CustomCommands failed");
|
||||
if (!CustomCommands.binds.contains(key)) {
|
||||
CustomCommands.binds.put(keyZ, .{}) catch |e| {
|
||||
std.log.err("CustomCommands.binds: {} while putting for key {s}", .{e, key});
|
||||
@panic("CustomCommands.binds failed");
|
||||
};
|
||||
}
|
||||
if (CustomCommands.mapping.getPtr(keyZ)) |command| {
|
||||
if (CustomCommands.binds.getPtr(keyZ)) |command| {
|
||||
if (std.mem.eql(u8, field.key, "name")) {
|
||||
command.name = temporary_allocator.dupe(u8, field.value) catch {
|
||||
@panic("FUCK");
|
||||
|
|
@ -191,6 +191,34 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie
|
|||
}
|
||||
}
|
||||
|
||||
if (std.mem.startsWith(u8, field.header, "lbl:")) {
|
||||
const key = field.header[4..];
|
||||
const keyZ = temporary_allocator.dupe(u8, key) catch @panic("FUCK");
|
||||
if (!CustomCommands.labels.contains(keyZ)) {
|
||||
CustomCommands.labels.put(keyZ, .{}) catch |e| {
|
||||
std.log.err("CustomCommands.labels: {} while putting for key {s}", .{e, key});
|
||||
@panic("CustomCommands.labels failed");
|
||||
};
|
||||
}
|
||||
if (CustomCommands.labels.getPtr(keyZ)) |label| {
|
||||
if (std.mem.eql(u8, field.key, "cmd")) {
|
||||
label.cmd = temporary_allocator.dupe(u8, field.value) catch {
|
||||
@panic("FUCK");
|
||||
};
|
||||
}
|
||||
if (std.mem.eql(u8, field.key, "posX")) {
|
||||
label.posX = std.fmt.parseInt(u32, field.value, 10) catch blk: { break :blk 0; };
|
||||
}
|
||||
if (std.mem.eql(u8, field.key, "posY")) {
|
||||
label.posY = std.fmt.parseInt(u32, field.value, 10) catch blk: { break :blk 0; };
|
||||
}
|
||||
if (std.mem.eql(u8, field.key, "refresh")) {
|
||||
label.refresh = std.fmt.parseInt(u32, field.value, 10) catch blk: { break :blk 0; };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
|
|
|
|||
114
src/main.zig
114
src/main.zig
|
|
@ -65,12 +65,17 @@ fn ttyControlTransferSignalHandler(_: c_int) callconv(.c) void {
|
|||
TerminalBuffer.shutdown();
|
||||
}
|
||||
|
||||
const CustomLabel = struct {
|
||||
cmd: CustomCommands.command,
|
||||
const CustomBindLabel = struct {
|
||||
cmd: CustomCommands.customCommandBind,
|
||||
key: []const u8,
|
||||
lbl: Label
|
||||
};
|
||||
|
||||
const CustomInfoLabel = struct {
|
||||
info: CustomCommands.customCommandInfo,
|
||||
lbl: Label
|
||||
};
|
||||
|
||||
const UiState = struct {
|
||||
allocator: Allocator,
|
||||
auth_fails: u64,
|
||||
|
|
@ -114,7 +119,8 @@ const UiState = struct {
|
|||
bigclock_format_buf: [16:0]u8,
|
||||
clock_buf: [64:0]u8,
|
||||
bigclock_buf: [32:0]u8,
|
||||
custom_commands: std.ArrayList(CustomLabel),
|
||||
custom_binds: std.ArrayList(CustomBindLabel),
|
||||
custom_info: std.ArrayList(CustomInfoLabel),
|
||||
};
|
||||
|
||||
var shutdown = false;
|
||||
|
|
@ -150,7 +156,9 @@ pub fn main() !void {
|
|||
}
|
||||
}
|
||||
|
||||
var gpa = std.heap.DebugAllocator(.{}).init;
|
||||
var gpa = std.heap.DebugAllocator(.{
|
||||
.retain_metadata = true,
|
||||
}).init;
|
||||
defer _ = gpa.deinit();
|
||||
|
||||
state.allocator = gpa.allocator();
|
||||
|
|
@ -214,19 +222,26 @@ pub fn main() !void {
|
|||
const config_path = try std.fs.path.join(state.allocator, &[_][]const u8{ config_parent_path, "config.ini" });
|
||||
defer state.allocator.free(config_path);
|
||||
|
||||
CustomCommands.mapping = .init(state.allocator);
|
||||
CustomCommands.binds = .init(state.allocator);
|
||||
CustomCommands.labels = .init(state.allocator);
|
||||
var config_parser = try IniParser(Config).init(state.allocator, config_path, migrator.configFieldHandler);
|
||||
defer config_parser.deinit();
|
||||
// mapping.deinit() has to be done here
|
||||
defer {
|
||||
if (!shutdown or !restart) {
|
||||
var iter = CustomCommands.mapping.iterator();
|
||||
var iter = CustomCommands.binds.iterator();
|
||||
while (iter.next()) |i| {
|
||||
temporary_allocator.free(i.key_ptr.*);
|
||||
temporary_allocator.free(i.value_ptr.*.cmd);
|
||||
temporary_allocator.free(i.value_ptr.*.name);
|
||||
}
|
||||
CustomCommands.mapping.deinit();
|
||||
CustomCommands.binds.deinit();
|
||||
var labelIter = CustomCommands.labels.iterator();
|
||||
while (labelIter.next()) |i| {
|
||||
temporary_allocator.free(i.key_ptr.*);
|
||||
temporary_allocator.free(i.value_ptr.*.cmd);
|
||||
}
|
||||
CustomCommands.labels.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1032,11 +1047,36 @@ pub fn main() !void {
|
|||
|
||||
// Layer 2
|
||||
var layer2: std.ArrayList(Widget) = .empty;
|
||||
state.custom_commands = .empty;
|
||||
defer state.custom_commands.deinit(state.allocator);
|
||||
state.custom_binds = .empty;
|
||||
state.custom_info = .empty;
|
||||
defer state.custom_binds.deinit(state.allocator);
|
||||
defer state.custom_info.deinit(state.allocator);
|
||||
defer layer2.deinit(state.allocator);
|
||||
|
||||
var lblIter = CustomCommands.labels.iterator();
|
||||
while (lblIter.next()) |i| {
|
||||
var w = Label.init("",
|
||||
null,
|
||||
state.buffer.fg,
|
||||
state.buffer.bg,
|
||||
&updateCustomInfo,
|
||||
null,
|
||||
);
|
||||
i.value_ptr.id = w.widget().id;
|
||||
i.value_ptr.counter = 2;
|
||||
try state.custom_info.append(state.allocator, .{
|
||||
.info = i.value_ptr.*,
|
||||
.lbl = w
|
||||
});
|
||||
}
|
||||
defer {
|
||||
for (state.custom_info.items) |*item| {
|
||||
state.allocator.free(item.lbl.text);
|
||||
item.lbl.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
var iter = CustomCommands.mapping.iterator();
|
||||
var iter = CustomCommands.binds.iterator();
|
||||
while (iter.next()) |i| {
|
||||
const concat = try std.mem.concat(state.allocator, u8,
|
||||
&[_][]u8{
|
||||
|
|
@ -1045,7 +1085,7 @@ pub fn main() !void {
|
|||
@constCast(i.value_ptr.name)
|
||||
}
|
||||
);
|
||||
try state.custom_commands.append(state.allocator, .{
|
||||
try state.custom_binds.append(state.allocator, .{
|
||||
.lbl = .init(
|
||||
concat,
|
||||
null,
|
||||
|
|
@ -1057,10 +1097,10 @@ pub fn main() !void {
|
|||
.cmd = i.value_ptr.*,
|
||||
.key = i.key_ptr.*,
|
||||
});
|
||||
state.custom_commands.items[state.custom_commands.items.len-1].lbl.allocator = state.allocator;
|
||||
state.custom_binds.items[state.custom_binds.items.len-1].lbl.allocator = state.allocator;
|
||||
}
|
||||
defer {
|
||||
for (state.custom_commands.items) |*i| {
|
||||
for (state.custom_binds.items) |*i| {
|
||||
i.lbl.deinit();
|
||||
}
|
||||
}
|
||||
|
|
@ -1104,7 +1144,10 @@ pub fn main() !void {
|
|||
try layer2.append(state.allocator, state.version_label.widget());
|
||||
}
|
||||
|
||||
for (state.custom_commands.items) |*item| {
|
||||
for (state.custom_binds.items) |*item| {
|
||||
try layer2.append(state.allocator, item.lbl.widget());
|
||||
}
|
||||
for (state.custom_info.items) |*item| {
|
||||
try layer2.append(state.allocator, item.lbl.widget());
|
||||
}
|
||||
|
||||
|
|
@ -1116,7 +1159,7 @@ pub fn main() !void {
|
|||
try widgets.append(state.allocator, &layer3);
|
||||
}
|
||||
|
||||
for (state.custom_commands.items) |*item| {
|
||||
for (state.custom_binds.items) |*item| {
|
||||
try state.buffer.registerKeybind(item.key, &customCommand, item);
|
||||
}
|
||||
|
||||
|
|
@ -1270,7 +1313,7 @@ fn quit(ptr: *anyopaque) !bool {
|
|||
}
|
||||
|
||||
fn customCommand(ptr: *anyopaque) !bool {
|
||||
const lbl: *CustomLabel = @ptrCast(@alignCast(ptr));
|
||||
const lbl: *CustomBindLabel = @ptrCast(@alignCast(ptr));
|
||||
var proc = std.process.Child.init(&[_][]const u8 {
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
|
|
@ -1669,6 +1712,38 @@ fn updateClock(self: *Label, ptr: *anyopaque) !void {
|
|||
}
|
||||
}
|
||||
|
||||
fn updateCustomInfo(lbl: *Label, ptr: *anyopaque) !void {
|
||||
const state: *UiState = @ptrCast(@alignCast(ptr));
|
||||
const wid = lbl.widget().id;
|
||||
var stdout = std.ArrayList(u8).empty;
|
||||
defer stdout.deinit(state.allocator);
|
||||
var stderr = std.ArrayList(u8).empty;
|
||||
defer stderr.deinit(state.allocator);
|
||||
for (state.custom_info.items) |*i| {
|
||||
if (i.info.id != wid) continue;
|
||||
if (i.info.counter == 1) {
|
||||
var c = std.process.Child.init(&[_][]const u8 {
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
i.info.cmd
|
||||
}, state.allocator);
|
||||
c.stderr_behavior = .Pipe;
|
||||
c.stdout_behavior = .Pipe;
|
||||
try c.spawn();
|
||||
try c.collectOutput(state.allocator, &stdout, &stderr, 128);
|
||||
_ = try c.wait();
|
||||
state.allocator.free(lbl.text);
|
||||
if (std.ascii.isAscii(stdout.items[stdout.items.len-1])) _ = stdout.pop();
|
||||
lbl.text = try state.allocator.dupe(u8, stdout.items);
|
||||
if (i.info.refresh != 0)
|
||||
i.info.counter = i.info.refresh;
|
||||
break;
|
||||
}
|
||||
i.info.counter -= 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn calculateClockTimeout(_: *Label, _: *anyopaque) !?usize {
|
||||
const time = try interop.getTimeOfDay();
|
||||
|
||||
|
|
@ -1747,11 +1822,16 @@ fn positionWidgets(ptr: *anyopaque) !void {
|
|||
state.brightness_up_label.positionXY(state.brightness_down_label
|
||||
.childrenPosition()
|
||||
.addX(1));
|
||||
for (state.custom_commands.items) |*item| {
|
||||
for (state.custom_binds.items) |*item| {
|
||||
item.lbl.positionXY(state.edge_margin
|
||||
.addX(@intCast(item.cmd.posX))
|
||||
.addY(@intCast(item.cmd.posY)));
|
||||
}
|
||||
for (state.custom_info.items) |*item| {
|
||||
item.lbl.positionXY(state.edge_margin
|
||||
.addX(@intCast(item.info.posX))
|
||||
.addY(@intCast(item.info.posY)));
|
||||
}
|
||||
}
|
||||
|
||||
state.battery_label.positionXY(state.edge_margin
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue