h
This commit is contained in:
parent
321105ecbd
commit
bfcd22b329
|
@ -110,6 +110,16 @@ pub const Bar = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn dispatch_click_event(self: *Bar, name: []const u8, event: MouseEvent) !void {
|
||||
std.log.debug(.bar, "Dispatch! {} {}\n", .{ name, event });
|
||||
|
||||
for (self.widgets) |w| {
|
||||
if (std.mem.eql(u8, w.name(), name)) {
|
||||
try w.mouse_event(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fn terminal_input_process(self: *Bar) !void {
|
||||
// TODO: make work on other OSes other than xterm compatable terminals.
|
||||
|
||||
|
@ -150,16 +160,17 @@ pub const Bar = struct {
|
|||
if (y == null) {
|
||||
continue;
|
||||
}
|
||||
const click_x_position = try std.fmt.parseInt(u64, x.?, 10);
|
||||
const click_x_position = try std.fmt.parseInt(u16, x.?, 10);
|
||||
// This makes it so it only works on the end of a click not the start
|
||||
// preventing a single click pressing the button twice.
|
||||
if (y.?[y.?.len - 1] == 'm') continue;
|
||||
|
||||
var current_info_line_length: u64 = 0;
|
||||
var current_info_line_length: u16 = 0;
|
||||
for (self.infos.items) |infoItem, index| {
|
||||
// Because the terminal output contains colour codes, we need to strip them.
|
||||
// To do this we only count the number of characters that are actually printed.
|
||||
var isEscape: bool = false;
|
||||
const previous_length = current_info_line_length;
|
||||
for (infoItem.full_text) |char| {
|
||||
// Skip all of the escape codes.
|
||||
if (char == 0x1b) {
|
||||
|
@ -177,12 +188,8 @@ pub const Bar = struct {
|
|||
current_info_line_length = current_info_line_length + 1;
|
||||
}
|
||||
// Get the first widget that the click is in.
|
||||
if (click_x_position <= current_info_line_length) {
|
||||
for (self.widgets) |w| {
|
||||
if (std.mem.eql(u8, w.name(), infoItem.name)) {
|
||||
w.mouse_event(.{ .button = .LeftClick }) catch {};
|
||||
}
|
||||
}
|
||||
if (click_x_position <= current_info_line_length) {
|
||||
self.dispatch_click_event(infoItem.name, .{ .button = .LeftClick, .x = click_x_position, .y=0,.scale=1, .height=1, .relative_x = click_x_position - previous_length}) catch {};
|
||||
break;
|
||||
}
|
||||
// Compensate for the | seporator on the terminal.
|
||||
|
@ -195,9 +202,6 @@ pub const Bar = struct {
|
|||
inline fn i3bar_input_process(self: *Bar) !void {
|
||||
var line_buffer: [512]u8 = undefined;
|
||||
while (self.running) {
|
||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||
defer arena.deinit();
|
||||
var allocator = &arena.allocator;
|
||||
const line_opt = try std.io.getStdIn().inStream().readUntilDelimiterOrEof(&line_buffer, '\n');
|
||||
if (line_opt) |l| {
|
||||
var line = l;
|
||||
|
@ -210,16 +214,11 @@ pub const Bar = struct {
|
|||
// instead of looping and getting it, maybe then it would make more sense?
|
||||
// Anyway this just strips off the prefix of ',' so I can parse the json.
|
||||
if (line[0] == ',') line = line[1..line.len];
|
||||
const parseOptions = std.json.ParseOptions{ .allocator = allocator };
|
||||
const parseOptions = std.json.ParseOptions{ .allocator = self.allocator };
|
||||
const data = try std.json.parse(MouseEvent, &std.json.TokenStream.init(line), parseOptions);
|
||||
defer std.json.parseFree(MouseEvent, data, parseOptions);
|
||||
// TODO: maybe make a function for getting the widget or widget index by name?
|
||||
// We do use this patern a lot in this code.
|
||||
for (self.widgets) |w| {
|
||||
if (std.mem.eql(u8, w.name(), data.name)) {
|
||||
try w.mouse_event(data);
|
||||
}
|
||||
}
|
||||
|
||||
self.dispatch_click_event(data.name, data) catch {};
|
||||
// If mouse_event needs to store the event for after the call is finished,
|
||||
// it should do it by itself, this just keeps the lifetime of the event to bare minimum.
|
||||
// Free the memory allocated by the MouseEvent struct.
|
||||
|
|
|
@ -66,8 +66,7 @@ pub fn main() !void {
|
|||
const widgets = [_]*Widget{
|
||||
//&Widget.init(&textWidget.New("owo", "potato")), // 4KiB
|
||||
//&Widget.init(&textWidget.New("uwu", "tomato")), // 4KiB
|
||||
&Widget.init(&networkWidget.New(allocator, &br)), // 4.08KiB
|
||||
|
||||
&Widget.init(&networkWidget.New(allocator, &br)), // 24.01KiB
|
||||
&Widget.init(&cpuWidget.New(&br)), // 4.08KiB
|
||||
&Widget.init(&memoryWidget.New(&br)), // 4.08KiB
|
||||
&Widget.init(&weatherWidget.New(allocator, &br, @import("build_options").weather_location)), // 16.16KiB
|
||||
|
|
|
@ -17,7 +17,6 @@ fn formatCPUPercent(allocator: *std.mem.Allocator, percent: f64) ![]const u8 {
|
|||
percentColour = "green";
|
||||
}
|
||||
const percentString = try std.fmt.allocPrint(allocator, "{d:0<2.2}" ++ comptimeColour("accentdark", "%"), .{percent});
|
||||
|
||||
return colour(allocator, percentColour, percentString);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ fn formatMemoryPercent(allocator: *std.mem.Allocator, percent: f64) ![]const u8
|
|||
percentColour = "green";
|
||||
}
|
||||
const percentString = try std.fmt.allocPrint(allocator, "{d:.2}" ++ comptimeColour("accentdark", "%"), .{percent});
|
||||
defer allocator.free(percentString);
|
||||
return colour(allocator, percentColour, percentString);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,17 @@ fn networkStatusToColour(s: NetworkStatus) []const u8 {
|
|||
pub const NetworkInfo = struct {
|
||||
network_type: NetworkType = .WiFi,
|
||||
network_status: NetworkStatus = .Connected,
|
||||
network_info: [32]u8 = [32]u8{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
|
||||
network_info_len: usize,
|
||||
network_info: []const u8,
|
||||
};
|
||||
|
||||
inline fn freeString(allocator: *std.mem.Allocator, string: []const u8) void {
|
||||
allocator.free(string);
|
||||
}
|
||||
|
||||
inline fn dupeString(allocator: *std.mem.Allocator, string: []const u8) ![]const u8 {
|
||||
return try allocator.dupe(u8, string);
|
||||
}
|
||||
|
||||
pub const NetworkWidget = struct {
|
||||
bar: *Bar,
|
||||
allocator: *std.mem.Allocator,
|
||||
|
@ -87,14 +94,15 @@ pub const NetworkWidget = struct {
|
|||
pub fn update_network_infos(self: *NetworkWidget) anyerror!void {
|
||||
const lock = self.update_mutex.acquire();
|
||||
defer lock.release();
|
||||
self.network_infos.shrink(0);
|
||||
for (self.network_infos.items) |info| {
|
||||
freeString(self.allocator, info.network_info);
|
||||
}
|
||||
self.num_interfaces = 0;
|
||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||
defer arena.deinit();
|
||||
var allocator = &arena.allocator;
|
||||
var proc = try std.ChildProcess.init(&[_][]const u8{ "nmcli", "-f", "common", "-c", "no", "d" }, allocator);
|
||||
var proc = try std.ChildProcess.init(&[_][]const u8{ "nmcli", "-f", "common", "-c", "no", "d" }, self.allocator);
|
||||
defer { _ = proc.kill() catch {}; proc.deinit(); }
|
||||
proc.stdout_behavior = .Pipe;
|
||||
try proc.spawn();
|
||||
var i: u8 = 0;
|
||||
if (proc.stdout) |stdout| {
|
||||
var line_buffer: [128]u8 = undefined;
|
||||
// Skip header.
|
||||
|
@ -107,45 +115,52 @@ pub const NetworkWidget = struct {
|
|||
const status = it.next();
|
||||
const description = it.next();
|
||||
if (connection_type) |t| if (!(eql(u8, t, "wifi") or eql(u8, t, "ethernet"))) continue;
|
||||
var net_info = NetworkInfo{
|
||||
try self.network_infos.resize(i+1);
|
||||
self.network_infos.items[i] = NetworkInfo{
|
||||
.network_type = toNetworkType(connection_type.?),
|
||||
.network_status = toNetworkStatus(status.?),
|
||||
.network_info_len = description.?.len,
|
||||
.network_info = try dupeString(self.allocator, description.?),
|
||||
};
|
||||
std.mem.copy(u8, net_info.network_info[0..description.?.len], description.?[0..description.?.len]);
|
||||
|
||||
try self.network_infos.append(net_info);
|
||||
//try self.network_infos.append(net_info);
|
||||
self.num_interfaces += 1;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_bar(self: *NetworkWidget) anyerror!void {
|
||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||
defer arena.deinit();
|
||||
var allocator = &arena.allocator;
|
||||
var buffer: [512]u8 = undefined;
|
||||
var fba = std.heap.FixedBufferAllocator.init(&buffer);
|
||||
var allocator = &fba.allocator;
|
||||
for (self.network_infos.items) |info, i| {
|
||||
if (i != self.current_interface) continue;
|
||||
//std.log.debug(.network, "item! {} {}\n", .{ info, i });
|
||||
const inner_text = try std.fmt.allocPrint(allocator, "{} {}", .{ @tagName(info.network_type), info.network_info });
|
||||
const full_text = try colour(allocator, networkStatusToColour(info.network_status), inner_text);
|
||||
defer allocator.free(full_text);
|
||||
allocator.free(inner_text);
|
||||
|
||||
try self.bar.add(Info{
|
||||
.name = "network",
|
||||
.full_text = try colour(allocator, networkStatusToColour(info.network_status), try std.fmt.allocPrint(allocator, "{} {}", .{ @tagName(info.network_type), info.network_info[0..info.network_info_len] })),
|
||||
.full_text = full_text,
|
||||
.markup = "pango",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(self: *NetworkWidget) anyerror!void {
|
||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||
defer arena.deinit();
|
||||
var allocator = &arena.allocator;
|
||||
self.network_infos = std.ArrayList(NetworkInfo).init(allocator);
|
||||
self.network_infos = std.ArrayList(NetworkInfo).init(self.allocator);
|
||||
defer self.network_infos.deinit();
|
||||
while (self.bar.keep_running()) {
|
||||
try self.update_network_infos();
|
||||
try self.update_bar();
|
||||
std.time.sleep(std.time.ns_per_s);
|
||||
}
|
||||
const lock = self.update_mutex.acquire();
|
||||
defer lock.release();
|
||||
for (self.network_infos.items) |info| {
|
||||
freeString(self.allocator, info.network_info);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@ pub const TimeWidget = struct {
|
|||
|
||||
pub fn start(self: *TimeWidget) anyerror!void {
|
||||
// TODO: find a god damn decent time library thats better than this bullshit.
|
||||
while (self.bar.keep_running()) {
|
||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||
defer arena.deinit();
|
||||
var allocator = &arena.allocator;
|
||||
var local = time.Location.getLocal(allocator);
|
||||
var now = time.now(&local);
|
||||
while (self.bar.keep_running()) {
|
||||
var now = time.now(&local);
|
||||
var date = now.date();
|
||||
var clock = now.clock();
|
||||
|
||||
|
|
Loading…
Reference in a new issue