mirror of https://github.com/fairyglade/ly.git
Split session crawling from TUI component
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
parent
9efb734fd5
commit
86ea38f460
|
|
@ -0,0 +1,21 @@
|
||||||
|
const enums = @import("enums.zig");
|
||||||
|
const ini = @import("zigini");
|
||||||
|
|
||||||
|
const DisplayServer = enums.DisplayServer;
|
||||||
|
const Ini = ini.Ini;
|
||||||
|
|
||||||
|
pub const DesktopEntry = struct {
|
||||||
|
Exec: []const u8 = "",
|
||||||
|
Name: [:0]const u8 = "",
|
||||||
|
DesktopNames: ?[:0]u8 = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Entry = struct { @"Desktop Entry": DesktopEntry = .{} };
|
||||||
|
|
||||||
|
entry_ini: ?Ini(Entry) = null,
|
||||||
|
name: [:0]const u8 = "",
|
||||||
|
xdg_session_desktop: ?[:0]const u8 = null,
|
||||||
|
xdg_desktop_names: ?[:0]const u8 = null,
|
||||||
|
cmd: []const u8 = "",
|
||||||
|
specifier: []const u8 = "",
|
||||||
|
display_server: DisplayServer = .wayland,
|
||||||
|
|
@ -2,8 +2,8 @@ const std = @import("std");
|
||||||
const build_options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const enums = @import("enums.zig");
|
const enums = @import("enums.zig");
|
||||||
|
const Environment = @import("Environment.zig");
|
||||||
const interop = @import("interop.zig");
|
const interop = @import("interop.zig");
|
||||||
const Session = @import("tui/components/Session.zig");
|
|
||||||
const SharedError = @import("SharedError.zig");
|
const SharedError = @import("SharedError.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
@ -33,7 +33,7 @@ pub fn sessionSignalHandler(i: c_int) callconv(.C) void {
|
||||||
if (child_pid > 0) _ = std.c.kill(child_pid, i);
|
if (child_pid > 0) _ = std.c.kill(child_pid, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn authenticate(options: AuthOptions, current_environment: Session.Environment, login: [:0]const u8, password: [:0]const u8) !void {
|
pub fn authenticate(options: AuthOptions, current_environment: Environment, login: [:0]const u8, password: [:0]const u8) !void {
|
||||||
var tty_buffer: [3]u8 = undefined;
|
var tty_buffer: [3]u8 = undefined;
|
||||||
const tty_str = try std.fmt.bufPrintZ(&tty_buffer, "{d}", .{options.tty});
|
const tty_str = try std.fmt.bufPrintZ(&tty_buffer, "{d}", .{options.tty});
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ fn startSession(
|
||||||
options: AuthOptions,
|
options: AuthOptions,
|
||||||
pwd: *interop.pwd.passwd,
|
pwd: *interop.pwd.passwd,
|
||||||
handle: ?*interop.pam.pam_handle,
|
handle: ?*interop.pam.pam_handle,
|
||||||
current_environment: Session.Environment,
|
current_environment: Environment,
|
||||||
) !void {
|
) !void {
|
||||||
if (builtin.os.tag == .freebsd) {
|
if (builtin.os.tag == .freebsd) {
|
||||||
// FreeBSD has initgroups() in unistd
|
// FreeBSD has initgroups() in unistd
|
||||||
|
|
|
||||||
93
src/main.zig
93
src/main.zig
|
|
@ -5,6 +5,8 @@ const clap = @import("clap");
|
||||||
const ini = @import("zigini");
|
const ini = @import("zigini");
|
||||||
const auth = @import("auth.zig");
|
const auth = @import("auth.zig");
|
||||||
const bigclock = @import("bigclock.zig");
|
const bigclock = @import("bigclock.zig");
|
||||||
|
const enums = @import("enums.zig");
|
||||||
|
const Environment = @import("Environment.zig");
|
||||||
const interop = @import("interop.zig");
|
const interop = @import("interop.zig");
|
||||||
const Doom = @import("animations/Doom.zig");
|
const Doom = @import("animations/Doom.zig");
|
||||||
const Matrix = @import("animations/Matrix.zig");
|
const Matrix = @import("animations/Matrix.zig");
|
||||||
|
|
@ -21,6 +23,8 @@ const SharedError = @import("SharedError.zig");
|
||||||
const utils = @import("tui/utils.zig");
|
const utils = @import("tui/utils.zig");
|
||||||
|
|
||||||
const Ini = ini.Ini;
|
const Ini = ini.Ini;
|
||||||
|
const DisplayServer = enums.DisplayServer;
|
||||||
|
const Entry = Environment.Entry;
|
||||||
const termbox = interop.termbox;
|
const termbox = interop.termbox;
|
||||||
const unistd = interop.unistd;
|
const unistd = interop.unistd;
|
||||||
const temporary_allocator = std.heap.page_allocator;
|
const temporary_allocator = std.heap.page_allocator;
|
||||||
|
|
@ -254,16 +258,16 @@ pub fn main() !void {
|
||||||
try info_line.addMessage(lang.err_numlock, config.error_bg, config.error_fg);
|
try info_line.addMessage(lang.err_numlock, config.error_bg, config.error_fg);
|
||||||
};
|
};
|
||||||
|
|
||||||
var session = Session.init(allocator, &buffer, lang);
|
var session = Session.init(allocator, &buffer);
|
||||||
defer session.deinit();
|
defer session.deinit();
|
||||||
|
|
||||||
session.addEnvironment(.{ .Name = lang.shell }, null, .shell) catch {
|
addOtherEnvironment(&session, lang, .shell, null) catch {
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (build_options.enable_x11_support) {
|
if (build_options.enable_x11_support) {
|
||||||
if (config.xinitrc) |xinitrc| {
|
if (config.xinitrc) |xinitrc_cmd| {
|
||||||
session.addEnvironment(.{ .Name = lang.xinitrc, .Exec = xinitrc }, null, .xinitrc) catch {
|
addOtherEnvironment(&session, lang, .xinitrc, xinitrc_cmd) catch {
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -283,8 +287,8 @@ pub fn main() !void {
|
||||||
try info_line.addMessage(hostname, config.bg, config.fg);
|
try info_line.addMessage(hostname, config.bg, config.fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
try session.crawl(config.waylandsessions, .wayland);
|
try crawl(&session, lang, config.waylandsessions, .wayland);
|
||||||
if (build_options.enable_x11_support) try session.crawl(config.xsessions, .x11);
|
if (build_options.enable_x11_support) try crawl(&session, lang, config.xsessions, .x11);
|
||||||
|
|
||||||
var login = Text.init(allocator, &buffer, false, null);
|
var login = Text.init(allocator, &buffer, false, null);
|
||||||
defer login.deinit();
|
defer login.deinit();
|
||||||
|
|
@ -844,6 +848,83 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addOtherEnvironment(session: *Session, lang: Lang, display_server: DisplayServer, exec: ?[]const u8) !void {
|
||||||
|
const name = switch (display_server) {
|
||||||
|
.shell => lang.shell,
|
||||||
|
.xinitrc => lang.xinitrc,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
|
try session.addEnvironment(.{
|
||||||
|
.entry_ini = null,
|
||||||
|
.name = name,
|
||||||
|
.xdg_session_desktop = null,
|
||||||
|
.xdg_desktop_names = null,
|
||||||
|
.cmd = exec orelse "",
|
||||||
|
.specifier = switch (display_server) {
|
||||||
|
.wayland => lang.wayland,
|
||||||
|
.x11 => lang.x11,
|
||||||
|
else => lang.other,
|
||||||
|
},
|
||||||
|
.display_server = display_server,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn crawl(session: *Session, lang: Lang, path: []const u8, display_server: DisplayServer) !void {
|
||||||
|
var iterable_directory = std.fs.openDirAbsolute(path, .{ .iterate = true }) catch return;
|
||||||
|
defer iterable_directory.close();
|
||||||
|
|
||||||
|
var iterator = iterable_directory.iterate();
|
||||||
|
while (try iterator.next()) |item| {
|
||||||
|
if (!std.mem.eql(u8, std.fs.path.extension(item.name), ".desktop")) continue;
|
||||||
|
|
||||||
|
const entry_path = try std.fmt.allocPrint(session.label.allocator, "{s}/{s}", .{ path, item.name });
|
||||||
|
defer session.label.allocator.free(entry_path);
|
||||||
|
var entry_ini = Ini(Entry).init(session.label.allocator);
|
||||||
|
_ = try entry_ini.readFileToStruct(entry_path, .{
|
||||||
|
.fieldHandler = null,
|
||||||
|
.comment_characters = "#",
|
||||||
|
});
|
||||||
|
errdefer entry_ini.deinit();
|
||||||
|
|
||||||
|
var xdg_session_desktop: []const u8 = undefined;
|
||||||
|
const maybe_desktop_names = entry_ini.data.@"Desktop Entry".DesktopNames;
|
||||||
|
if (maybe_desktop_names) |desktop_names| {
|
||||||
|
xdg_session_desktop = std.mem.sliceTo(desktop_names, ';');
|
||||||
|
} else {
|
||||||
|
// if DesktopNames is empty, we'll take the name of the session file
|
||||||
|
xdg_session_desktop = std.fs.path.stem(item.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the XDG_CURRENT_DESKTOP environment variable here
|
||||||
|
const entry = entry_ini.data.@"Desktop Entry";
|
||||||
|
var xdg_desktop_names: ?[:0]const u8 = null;
|
||||||
|
if (entry.DesktopNames) |desktop_names| {
|
||||||
|
for (desktop_names) |*c| {
|
||||||
|
if (c.* == ';') c.* = ':';
|
||||||
|
}
|
||||||
|
xdg_desktop_names = desktop_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
const session_desktop = try session.label.allocator.dupeZ(u8, xdg_session_desktop);
|
||||||
|
errdefer session.label.allocator.free(session_desktop);
|
||||||
|
|
||||||
|
try session.addEnvironment(.{
|
||||||
|
.entry_ini = entry_ini,
|
||||||
|
.name = entry.Name,
|
||||||
|
.xdg_session_desktop = session_desktop,
|
||||||
|
.xdg_desktop_names = xdg_desktop_names,
|
||||||
|
.cmd = entry.Exec,
|
||||||
|
.specifier = switch (display_server) {
|
||||||
|
.wayland => lang.wayland,
|
||||||
|
.x11 => lang.x11,
|
||||||
|
else => lang.other,
|
||||||
|
},
|
||||||
|
.display_server = display_server,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
||||||
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
||||||
brightness.stdout_behavior = .Ignore;
|
brightness.stdout_behavior = .Ignore;
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,22 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const TerminalBuffer = @import("../TerminalBuffer.zig");
|
const TerminalBuffer = @import("../TerminalBuffer.zig");
|
||||||
const enums = @import("../../enums.zig");
|
const enums = @import("../../enums.zig");
|
||||||
|
const ini = @import("zigini");
|
||||||
|
const Environment = @import("../../Environment.zig");
|
||||||
const generic = @import("generic.zig");
|
const generic = @import("generic.zig");
|
||||||
const Ini = @import("zigini").Ini;
|
|
||||||
const Lang = @import("../../config/Lang.zig");
|
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const DisplayServer = enums.DisplayServer;
|
const DisplayServer = enums.DisplayServer;
|
||||||
|
const Ini = ini.Ini;
|
||||||
const EnvironmentLabel = generic.CyclableLabel(Environment);
|
const EnvironmentLabel = generic.CyclableLabel(Environment);
|
||||||
|
|
||||||
const Session = @This();
|
const Session = @This();
|
||||||
|
|
||||||
pub const Environment = struct {
|
|
||||||
entry_ini: ?Ini(Entry) = null,
|
|
||||||
name: [:0]const u8 = "",
|
|
||||||
xdg_session_desktop: ?[:0]const u8 = null,
|
|
||||||
xdg_desktop_names: ?[:0]const u8 = null,
|
|
||||||
cmd: []const u8 = "",
|
|
||||||
specifier: []const u8 = "",
|
|
||||||
display_server: DisplayServer = .wayland,
|
|
||||||
};
|
|
||||||
|
|
||||||
const DesktopEntry = struct {
|
|
||||||
Exec: []const u8 = "",
|
|
||||||
Name: [:0]const u8 = "",
|
|
||||||
DesktopNames: ?[:0]u8 = null,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Entry = struct { @"Desktop Entry": DesktopEntry = .{} };
|
|
||||||
|
|
||||||
label: EnvironmentLabel,
|
label: EnvironmentLabel,
|
||||||
lang: Lang,
|
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, buffer: *TerminalBuffer, lang: Lang) Session {
|
pub fn init(allocator: Allocator, buffer: *TerminalBuffer) Session {
|
||||||
return .{
|
return .{
|
||||||
.label = EnvironmentLabel.init(allocator, buffer, drawItem),
|
.label = EnvironmentLabel.init(allocator, buffer, drawItem),
|
||||||
.lang = lang,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,86 +29,8 @@ pub fn deinit(self: Session) void {
|
||||||
self.label.deinit();
|
self.label.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addEnvironment(self: *Session, entry: DesktopEntry, xdg_session_desktop: ?[:0]const u8, display_server: DisplayServer) !void {
|
pub fn addEnvironment(self: *Session, environment: Environment) !void {
|
||||||
var xdg_desktop_names: ?[:0]const u8 = null;
|
try self.label.addItem(environment);
|
||||||
if (entry.DesktopNames) |desktop_names| {
|
|
||||||
for (desktop_names) |*c| {
|
|
||||||
if (c.* == ';') c.* = ':';
|
|
||||||
}
|
|
||||||
xdg_desktop_names = desktop_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
try self.label.addItem(.{
|
|
||||||
.entry_ini = null,
|
|
||||||
.name = entry.Name,
|
|
||||||
.xdg_session_desktop = xdg_session_desktop,
|
|
||||||
.xdg_desktop_names = xdg_desktop_names,
|
|
||||||
.cmd = entry.Exec,
|
|
||||||
.specifier = switch (display_server) {
|
|
||||||
.wayland => self.lang.wayland,
|
|
||||||
.x11 => self.lang.x11,
|
|
||||||
else => self.lang.other,
|
|
||||||
},
|
|
||||||
.display_server = display_server,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn addEnvironmentWithIni(self: *Session, entry_ini: Ini(Entry), xdg_session_desktop: ?[:0]const u8, display_server: DisplayServer) !void {
|
|
||||||
const entry = entry_ini.data.@"Desktop Entry";
|
|
||||||
var xdg_desktop_names: ?[:0]const u8 = null;
|
|
||||||
if (entry.DesktopNames) |desktop_names| {
|
|
||||||
for (desktop_names) |*c| {
|
|
||||||
if (c.* == ';') c.* = ':';
|
|
||||||
}
|
|
||||||
xdg_desktop_names = desktop_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
try self.label.addItem(.{
|
|
||||||
.entry_ini = entry_ini,
|
|
||||||
.name = entry.Name,
|
|
||||||
.xdg_session_desktop = xdg_session_desktop,
|
|
||||||
.xdg_desktop_names = xdg_desktop_names,
|
|
||||||
.cmd = entry.Exec,
|
|
||||||
.specifier = switch (display_server) {
|
|
||||||
.wayland => self.lang.wayland,
|
|
||||||
.x11 => self.lang.x11,
|
|
||||||
else => self.lang.other,
|
|
||||||
},
|
|
||||||
.display_server = display_server,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn crawl(self: *Session, path: []const u8, display_server: DisplayServer) !void {
|
|
||||||
var iterable_directory = std.fs.openDirAbsolute(path, .{ .iterate = true }) catch return;
|
|
||||||
defer iterable_directory.close();
|
|
||||||
|
|
||||||
var iterator = iterable_directory.iterate();
|
|
||||||
while (try iterator.next()) |item| {
|
|
||||||
if (!std.mem.eql(u8, std.fs.path.extension(item.name), ".desktop")) continue;
|
|
||||||
|
|
||||||
const entry_path = try std.fmt.allocPrint(self.label.allocator, "{s}/{s}", .{ path, item.name });
|
|
||||||
defer self.label.allocator.free(entry_path);
|
|
||||||
var entry_ini = Ini(Entry).init(self.label.allocator);
|
|
||||||
_ = try entry_ini.readFileToStruct(entry_path, .{
|
|
||||||
.fieldHandler = null,
|
|
||||||
.comment_characters = "#",
|
|
||||||
});
|
|
||||||
errdefer entry_ini.deinit();
|
|
||||||
|
|
||||||
var xdg_session_desktop: []const u8 = undefined;
|
|
||||||
const maybe_desktop_names = entry_ini.data.@"Desktop Entry".DesktopNames;
|
|
||||||
if (maybe_desktop_names) |desktop_names| {
|
|
||||||
xdg_session_desktop = std.mem.sliceTo(desktop_names, ';');
|
|
||||||
} else {
|
|
||||||
// if DesktopNames is empty, we'll take the name of the session file
|
|
||||||
xdg_session_desktop = std.fs.path.stem(item.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
const session_desktop = try self.label.allocator.dupeZ(u8, xdg_session_desktop);
|
|
||||||
errdefer self.label.allocator.free(session_desktop);
|
|
||||||
|
|
||||||
try self.addEnvironmentWithIni(entry_ini, session_desktop, display_server);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drawItem(label: *EnvironmentLabel, environment: Environment, x: usize, y: usize) bool {
|
fn drawItem(label: *EnvironmentLabel, environment: Environment, x: usize, y: usize) bool {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue