mirror of
https://github.com/fairyglade/ly.git
synced 2025-12-20 19:24:53 +00:00
Implement custom session support (fixes #757)
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
@@ -8,6 +8,7 @@ pub const DesktopEntry = struct {
|
||||
Exec: []const u8 = "",
|
||||
Name: [:0]const u8 = "",
|
||||
DesktopNames: ?[:0]u8 = null,
|
||||
Terminal: ?bool = null,
|
||||
};
|
||||
|
||||
pub const Entry = struct { @"Desktop Entry": DesktopEntry = .{} };
|
||||
@@ -19,3 +20,4 @@ xdg_desktop_names: ?[:0]const u8 = null,
|
||||
cmd: []const u8 = "",
|
||||
specifier: []const u8 = "",
|
||||
display_server: DisplayServer = .wayland,
|
||||
is_terminal: bool = false,
|
||||
|
||||
18
src/auth.zig
18
src/auth.zig
@@ -180,6 +180,7 @@ fn startSession(
|
||||
const vt = try std.fmt.bufPrint(&vt_buf, "vt{d}", .{options.tty});
|
||||
try executeX11Cmd(pwd.pw_shell.?, pwd.pw_dir.?, options, current_environment.cmd, vt);
|
||||
},
|
||||
.custom => try executeCustomCmd(pwd.pw_shell.?, options, current_environment.is_terminal, current_environment.cmd),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,6 +202,7 @@ fn setXdgEnv(tty_str: [:0]u8, environment: Environment) !void {
|
||||
.wayland => "wayland",
|
||||
.shell => "tty",
|
||||
.xinitrc, .x11 => "x11",
|
||||
.custom => "unspecified",
|
||||
}, 0);
|
||||
|
||||
// The "/run/user/%d" directory is not available on FreeBSD. It is much
|
||||
@@ -462,6 +464,22 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, options: AuthOptio
|
||||
_ = std.c.waitpid(x_pid, &status, 0);
|
||||
}
|
||||
|
||||
fn executeCustomCmd(shell: [*:0]const u8, options: AuthOptions, is_terminal: bool, exec_cmd: []const u8) !void {
|
||||
var maybe_log_file: ?std.fs.File = null;
|
||||
if (!is_terminal) {
|
||||
// For custom desktop entries, the "Terminal" value here determines if
|
||||
// we redirect standard output & error or not. That is, we redirect only
|
||||
// if it's equal to false (so if it's not running in a TTY).
|
||||
maybe_log_file = try redirectStandardStreams(options.session_log, true);
|
||||
}
|
||||
defer if (maybe_log_file) |log_file| log_file.close();
|
||||
|
||||
var cmd_buffer: [1024]u8 = undefined;
|
||||
const cmd_str = try std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.setup_cmd, options.login_cmd orelse "", exec_cmd });
|
||||
const args = [_:null]?[*:0]const u8{ shell, "-c", cmd_str };
|
||||
return std.posix.execveZ(shell, &args, std.c.environ);
|
||||
}
|
||||
|
||||
fn redirectStandardStreams(session_log: []const u8, create: bool) !std.fs.File {
|
||||
const log_file = if (create) (try std.fs.cwd().createFile(session_log, .{ .mode = 0o666 })) else (try std.fs.cwd().openFile(session_log, .{ .mode = .read_write }));
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ cmatrix_max_codepoint: u16 = 0x7B,
|
||||
colormix_col1: u32 = 0x00FF0000,
|
||||
colormix_col2: u32 = 0x000000FF,
|
||||
colormix_col3: u32 = 0x20000000,
|
||||
custom_sessions: []const u8 = build_options.config_directory ++ "/ly/custom-sessions",
|
||||
default_input: Input = .login,
|
||||
doom_fire_height: u8 = 6,
|
||||
doom_fire_spread: u8 = 2,
|
||||
|
||||
@@ -7,6 +7,7 @@ authenticating: []const u8 = "authenticating...",
|
||||
brightness_down: []const u8 = "decrease brightness",
|
||||
brightness_up: []const u8 = "increase brightness",
|
||||
capslock: []const u8 = "capslock",
|
||||
custom: []const u8 = "custom",
|
||||
err_alloc: []const u8 = "failed memory allocation",
|
||||
err_bounds: []const u8 = "out-of-bounds index",
|
||||
err_brightness_change: []const u8 = "failed to change brightness",
|
||||
|
||||
@@ -11,6 +11,7 @@ pub const DisplayServer = enum {
|
||||
shell,
|
||||
xinitrc,
|
||||
x11,
|
||||
custom,
|
||||
};
|
||||
|
||||
pub const Input = enum {
|
||||
|
||||
38
src/main.zig
38
src/main.zig
@@ -290,10 +290,12 @@ pub fn main() !void {
|
||||
try info_line.addMessage(hostname, config.bg, config.fg);
|
||||
}
|
||||
|
||||
// Crawl session directories (Wayland, X11 and custom respectively)
|
||||
var wayland_session_dirs = std.mem.splitScalar(u8, config.waylandsessions, ':');
|
||||
while (wayland_session_dirs.next()) |dir| {
|
||||
try crawl(&session, lang, dir, .wayland);
|
||||
}
|
||||
|
||||
if (build_options.enable_x11_support) {
|
||||
var x_session_dirs = std.mem.splitScalar(u8, config.xsessions, ':');
|
||||
while (x_session_dirs.next()) |dir| {
|
||||
@@ -301,6 +303,11 @@ pub fn main() !void {
|
||||
}
|
||||
}
|
||||
|
||||
var custom_session_dirs = std.mem.splitScalar(u8, config.custom_sessions, ':');
|
||||
while (custom_session_dirs.next()) |dir| {
|
||||
try crawl(&session, lang, dir, .custom);
|
||||
}
|
||||
|
||||
var login = Text.init(allocator, &buffer, false, null);
|
||||
defer login.deinit();
|
||||
|
||||
@@ -864,11 +871,7 @@ fn addOtherEnvironment(session: *Session, lang: Lang, display_server: DisplaySer
|
||||
.xdg_session_desktop = null,
|
||||
.xdg_desktop_names = null,
|
||||
.cmd = exec orelse "",
|
||||
.specifier = switch (display_server) {
|
||||
.wayland => lang.wayland,
|
||||
.x11 => lang.x11,
|
||||
else => lang.other,
|
||||
},
|
||||
.specifier = lang.other,
|
||||
.display_server = display_server,
|
||||
});
|
||||
}
|
||||
@@ -890,40 +893,43 @@ fn crawl(session: *Session, lang: Lang, path: []const u8, display_server: Displa
|
||||
});
|
||||
errdefer entry_ini.deinit();
|
||||
|
||||
var xdg_session_desktop: []const u8 = undefined;
|
||||
var maybe_xdg_session_desktop: ?[]const u8 = null;
|
||||
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);
|
||||
maybe_xdg_session_desktop = std.mem.sliceTo(desktop_names, ';');
|
||||
} else if (display_server != .custom) {
|
||||
// If DesktopNames is empty, and this isn't a custom session entry,
|
||||
// we'll take the name of the session file
|
||||
maybe_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;
|
||||
var maybe_xdg_desktop_names: ?[:0]const u8 = null;
|
||||
if (entry.DesktopNames) |desktop_names| {
|
||||
for (desktop_names) |*c| {
|
||||
if (c.* == ';') c.* = ':';
|
||||
}
|
||||
xdg_desktop_names = desktop_names;
|
||||
maybe_xdg_desktop_names = desktop_names;
|
||||
}
|
||||
|
||||
const session_desktop = try session.label.allocator.dupeZ(u8, xdg_session_desktop);
|
||||
errdefer session.label.allocator.free(session_desktop);
|
||||
const maybe_session_desktop = if (maybe_xdg_session_desktop) |xdg_session_desktop| try session.label.allocator.dupeZ(u8, xdg_session_desktop) else null;
|
||||
errdefer if (maybe_session_desktop) |session_desktop| 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,
|
||||
.xdg_session_desktop = maybe_session_desktop,
|
||||
.xdg_desktop_names = maybe_xdg_desktop_names,
|
||||
.cmd = entry.Exec,
|
||||
.specifier = switch (display_server) {
|
||||
.wayland => lang.wayland,
|
||||
.x11 => lang.x11,
|
||||
.custom => lang.custom,
|
||||
else => lang.other,
|
||||
},
|
||||
.display_server = display_server,
|
||||
.is_terminal = entry.Terminal orelse false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user