diff --git a/src/auth.zig b/src/auth.zig index c9ff891..26de2cf 100644 --- a/src/auth.zig +++ b/src/auth.zig @@ -27,7 +27,7 @@ pub fn authenticate(config: Config, desktop: Desktop, login: [:0]const u8, passw // Set the XDG environment variables setXdgSessionEnv(current_environment.display_server); - try setXdgEnv(tty_str, current_environment.name, current_environment.xdg_name); + try setXdgEnv(tty_str, current_environment.xdg_session_desktop, current_environment.xdg_desktop_names orelse ""); // Open the PAM session var credentials = [_:null]?[*:0]const u8{ login, password }; diff --git a/src/main.zig b/src/main.zig index e713025..bff277b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -163,11 +163,11 @@ pub fn main() !void { var desktop = try Desktop.init(allocator, &buffer, config.max_desktop_len, lang); defer desktop.deinit(); - desktop.addEnvironment(.{ .Name = lang.shell }, .shell) catch { + desktop.addEnvironment(.{ .Name = lang.shell }, "", .shell) catch { try info_line.setText(lang.err_alloc); }; if (config.xinitrc) |xinitrc| { - desktop.addEnvironment(.{ .Name = lang.xinitrc, .Exec = xinitrc }, .xinitrc) catch { + desktop.addEnvironment(.{ .Name = lang.xinitrc, .Exec = xinitrc }, "", .xinitrc) catch { try info_line.setText(lang.err_alloc); }; } diff --git a/src/tui/components/Desktop.zig b/src/tui/components/Desktop.zig index 8811dbd..baaf976 100644 --- a/src/tui/components/Desktop.zig +++ b/src/tui/components/Desktop.zig @@ -17,7 +17,8 @@ const Desktop = @This(); pub const Environment = struct { entry_ini: ?Ini(Entry) = null, name: [:0]const u8 = "", - xdg_name: [:0]const u8 = "", + xdg_session_desktop: [:0]const u8 = "", + xdg_desktop_names: ?[:0]const u8 = "", cmd: []const u8 = "", specifier: []const u8 = "", display_server: DisplayServer = .wayland, @@ -26,7 +27,7 @@ pub const Environment = struct { const DesktopEntry = struct { Exec: []const u8 = "", Name: [:0]const u8 = "", - DesktopNames: [:0]const u8 = "", + DesktopNames: ?[]const u8 = null, }; pub const Entry = struct { @"Desktop Entry": DesktopEntry = DesktopEntry{} }; @@ -56,6 +57,8 @@ pub fn init(allocator: Allocator, buffer: *TerminalBuffer, max_length: u64, lang pub fn deinit(self: Desktop) void { for (self.environments.items) |*environment| { if (environment.entry_ini) |*entry_ini| entry_ini.deinit(); + if (environment.xdg_desktop_names) |desktop_name| self.allocator.free(desktop_name); + self.allocator.free(environment.xdg_session_desktop); } self.environments.deinit(); @@ -67,11 +70,27 @@ pub fn position(self: *Desktop, x: u64, y: u64, visible_length: u64) void { self.visible_length = visible_length; } -pub fn addEnvironment(self: *Desktop, entry: DesktopEntry, display_server: DisplayServer) !void { +pub fn addEnvironment(self: *Desktop, entry: DesktopEntry, xdg_session_desktop: []const u8, display_server: DisplayServer) !void { + var xdg_desktop_names: ?[:0]const u8 = null; + if (entry.DesktopNames) |desktop_names| { + const desktop_names_z = try self.allocator.dupeZ(u8, desktop_names); + for (desktop_names_z) |*c| { + if (c.* == ';') c.* = ':'; + } + xdg_desktop_names = desktop_names_z; + } + + errdefer { + if (xdg_desktop_names) |desktop_names| self.allocator.free(desktop_names); + } + + const session_desktop = try self.allocator.dupeZ(u8, xdg_session_desktop); + try self.environments.append(.{ .entry_ini = null, .name = entry.Name, - .xdg_name = entry.DesktopNames, + .xdg_session_desktop = session_desktop, + .xdg_desktop_names = xdg_desktop_names, .cmd = entry.Exec, .specifier = switch (display_server) { .wayland => self.lang.wayland, @@ -84,12 +103,28 @@ pub fn addEnvironment(self: *Desktop, entry: DesktopEntry, display_server: Displ self.current = self.environments.items.len - 1; } -pub fn addEnvironmentWithIni(self: *Desktop, entry_ini: Ini(Entry), display_server: DisplayServer) !void { +pub fn addEnvironmentWithIni(self: *Desktop, entry_ini: Ini(Entry), xdg_session_desktop: []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| { + const desktop_names_z = try self.allocator.dupeZ(u8, desktop_names); + for (desktop_names_z) |*c| { + if (c.* == ';') c.* = ':'; + } + xdg_desktop_names = desktop_names_z; + } + + errdefer { + if (xdg_desktop_names) |desktop_names| self.allocator.free(desktop_names); + } + + const session_desktop = try self.allocator.dupeZ(u8, xdg_session_desktop); + try self.environments.append(.{ .entry_ini = entry_ini, .name = entry.Name, - .xdg_name = entry.DesktopNames, + .xdg_session_desktop = session_desktop, + .xdg_desktop_names = xdg_desktop_names, .cmd = entry.Exec, .specifier = switch (display_server) { .wayland => self.lang.wayland, @@ -115,7 +150,16 @@ pub fn crawl(self: *Desktop, path: []const u8, display_server: DisplayServer) !v var entry_ini = Ini(Entry).init(self.allocator); _ = try entry_ini.readFileToStruct(entry_path); - try self.addEnvironmentWithIni(entry_ini, display_server); + 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); + } + + try self.addEnvironmentWithIni(entry_ini, xdg_session_desktop, display_server); } }