10 Commits

Author SHA1 Message Date
AnErrupTion
a9b6bfc62a Backport: Prevent Ly from zombifying when X.org is terminated
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-08-05 21:49:38 +02:00
AnErrupTion
32d0de3d2d Backport: Workaround for session process not exiting immediately
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-08-04 00:04:55 +02:00
AnErrupTion
a4dd5b3c44 Backport: Fix clock string length issues
Co-authored-by: Plash <plash@noreply.codeberg.org>
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-08-02 13:16:35 +02:00
AnErrupTion
b7d81a9b51 Backport: Fix possible overflow with 5-digit+ UIDs
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-08-02 01:00:56 +02:00
AnErrupTion
3359127a06 Backport: Reorder default PATH to prioritize /usr/local directories to solve
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-08-02 01:00:10 +02:00
AnErrupTion
faa2636c99 Start Ly v1.1.2 development cycle
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-07-08 16:37:48 +02:00
AnErrupTion
9d23209ca3 Backport: Fix character width calculation
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-07-08 16:36:02 +02:00
AnErrupTion
170e523823 Backport: Fix XDG_RUNTIME_DIR not being set properly
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-07-06 09:31:56 +02:00
AnErrupTion
f983c6b19b Backport: Fix big clock UB in ReleaseSafe
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-05-31 10:39:15 +02:00
AnErrupTion
d12850889c Start v1.1.1 development cycle
Signed-off-by: AnErrupTion <anerruption@disroot.org>
2025-05-31 10:39:03 +02:00
9 changed files with 53 additions and 42 deletions

View File

@@ -21,7 +21,7 @@ comptime {
}
}
const ly_version = std.SemanticVersion{ .major = 1, .minor = 1, .patch = 0 };
const ly_version = std.SemanticVersion{ .major = 1, .minor = 1, .patch = 2 };
var dest_directory: []const u8 = undefined;
var config_directory: []const u8 = undefined;

View File

@@ -1,6 +1,6 @@
.{
.name = .ly,
.version = "1.1.0",
.version = "1.1.2",
.fingerprint = 0xa148ffcc5dc2cb59,
.minimum_zig_version = "0.14.0",
.dependencies = .{

View File

@@ -171,7 +171,7 @@ numlock = false
# Default path
# If null, ly doesn't set a path
path = /sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Command executed when pressing restart_key
restart_cmd = /sbin/shutdown -r now

View File

@@ -96,7 +96,7 @@ pub fn authenticate(options: AuthOptions, current_environment: Environment, logi
child_pid = try std.posix.fork();
if (child_pid == 0) {
startSession(options, pwd, handle, current_environment) catch |e| {
startSession(options, tty_str, pwd, handle, current_environment) catch |e| {
shared_err.writeError(e);
std.process.exit(1);
};
@@ -132,6 +132,7 @@ pub fn authenticate(options: AuthOptions, current_environment: Environment, logi
fn startSession(
options: AuthOptions,
tty_str: [:0]u8,
pwd: *interop.pwd.passwd,
handle: ?*interop.pam.pam_handle,
current_environment: Environment,
@@ -155,6 +156,10 @@ fn startSession(
// Set up the environment
try initEnv(pwd, options.path);
// Reset the XDG environment variables
setXdgSessionEnv(current_environment.display_server);
try setXdgEnv(tty_str, current_environment.xdg_session_desktop, current_environment.xdg_desktop_names);
// Set the PAM variables
const pam_env_vars: ?[*:null]?[*:0]u8 = interop.pam.pam_getenvlist(handle);
if (pam_env_vars == null) return error.GetEnvListFailed;
@@ -208,7 +213,7 @@ fn setXdgEnv(tty_str: [:0]u8, maybe_desktop_name: ?[:0]const u8, maybe_xdg_deskt
// directory.
if (builtin.os.tag != .freebsd) {
const uid = interop.unistd.getuid();
var uid_buffer: [10 + @sizeOf(u32) + 1]u8 = undefined;
var uid_buffer: [32]u8 = undefined; // No UID can be larger than this
const uid_str = try std.fmt.bufPrintZ(&uid_buffer, "/run/user/{d}", .{uid});
_ = interop.stdlib.setenv("XDG_RUNTIME_DIR", uid_str, 0);
@@ -454,8 +459,9 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, options: AuthOptio
_ = std.posix.waitpid(xorg_pid, 0);
interop.xcb.xcb_disconnect(xcb);
std.posix.kill(x_pid, 0) catch return;
std.posix.kill(x_pid, std.posix.SIG.KILL) catch {};
std.posix.kill(x_pid, std.posix.SIG.TERM) catch {};
std.Thread.sleep(std.time.ns_per_s * 1); // Wait 1 second before sending SIGKILL
std.posix.kill(x_pid, std.posix.SIG.KILL) catch return;
var status: c_int = 0;
_ = std.c.waitpid(x_pid, &status, 0);

View File

@@ -34,24 +34,24 @@ pub fn alphaBlit(x: usize, y: usize, tb_width: usize, tb_height: usize, cells: [
}
}
fn toBigNumber(char: u8, bigclock: Bigclock) []const u21 {
fn toBigNumber(char: u8, bigclock: Bigclock) [SIZE]u21 {
const locale_chars = switch (bigclock) {
.fa => fa.locale_chars,
.en => en.locale_chars,
.none => unreachable,
};
return switch (char) {
'0' => &locale_chars.ZERO,
'1' => &locale_chars.ONE,
'2' => &locale_chars.TWO,
'3' => &locale_chars.THREE,
'4' => &locale_chars.FOUR,
'5' => &locale_chars.FIVE,
'6' => &locale_chars.SIX,
'7' => &locale_chars.SEVEN,
'8' => &locale_chars.EIGHT,
'9' => &locale_chars.NINE,
':' => &locale_chars.S,
else => &locale_chars.E,
'0' => locale_chars.ZERO,
'1' => locale_chars.ONE,
'2' => locale_chars.TWO,
'3' => locale_chars.THREE,
'4' => locale_chars.FOUR,
'5' => locale_chars.FIVE,
'6' => locale_chars.SIX,
'7' => locale_chars.SEVEN,
'8' => locale_chars.EIGHT,
'9' => locale_chars.NINE,
':' => locale_chars.S,
else => locale_chars.E,
};
}

View File

@@ -48,7 +48,7 @@ margin_box_h: u8 = 2,
margin_box_v: u8 = 1,
min_refresh_delta: u16 = 5,
numlock: bool = false,
path: ?[:0]const u8 = "/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
path: ?[:0]const u8 = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
restart_cmd: []const u8 = "/sbin/shutdown -r now",
restart_key: []const u8 = "F2",
save: bool = true,

View File

@@ -65,12 +65,10 @@ const set_led_state = if (builtin.os.tag.isBSD()) kbio.KDSETLED else kd.KDSKBLED
const numlock_led = if (builtin.os.tag.isBSD()) kbio.LED_NUM else kd.K_NUMLOCK;
const capslock_led = if (builtin.os.tag.isBSD()) kbio.LED_CAP else kd.K_CAPSLOCK;
pub fn timeAsString(buf: [:0]u8, format: [:0]const u8) ![]u8 {
pub fn timeAsString(buf: [:0]u8, format: [:0]const u8) []u8 {
const timer = std.time.timestamp();
const tm_info = time.localtime(&timer);
const len = time.strftime(buf, buf.len, format, tm_info);
if (len < 0) return error.CannotGetFormattedTime;
return buf[0..len];
}

View File

@@ -101,6 +101,7 @@ pub fn main() !void {
var lang: Lang = undefined;
var save: Save = undefined;
var config_load_failed = false;
var can_draw_clock = true;
if (res.args.help != 0) {
try clap.help(stderr, clap.Help, &params, .{});
@@ -426,15 +427,13 @@ pub fn main() !void {
buffer.drawLabel(ly_top_str, 0, 0);
if (config.bigclock != .none and buffer.box_height + (bigclock.HEIGHT + 2) * 2 < buffer.height) draw_big_clock: {
if (config.bigclock != .none and buffer.box_height + (bigclock.HEIGHT + 2) * 2 < buffer.height) {
const format = "%H:%M";
const xo = buffer.width / 2 - @min(buffer.width, (format.len * (bigclock.WIDTH + 1))) / 2;
const yo = (buffer.height - buffer.box_height) / 2 - bigclock.HEIGHT - 2;
var clock_buf: [format.len + 1:0]u8 = undefined;
const clock_str = interop.timeAsString(&clock_buf, format) catch {
break :draw_big_clock;
};
const clock_str = interop.timeAsString(&clock_buf, format);
for (clock_str, 0..) |c, i| {
const clock_cell = bigclock.clockCell(animate, c, buffer.fg, buffer.bg, config.bigclock);
@@ -466,12 +465,17 @@ pub fn main() !void {
}
if (config.clock) |clock| draw_clock: {
var clock_buf: [32:0]u8 = undefined;
const clock_str = interop.timeAsString(&clock_buf, clock) catch {
break :draw_clock;
};
if (!can_draw_clock) break :draw_clock;
if (clock_str.len == 0) return error.FormattedTimeEmpty;
var clock_buf: [64:0]u8 = undefined;
const clock_str = interop.timeAsString(&clock_buf, clock);
if (clock_str.len == 0) {
// Backport: I've decided not to localize the error message
try info_line.addMessage("clock string too long", config.error_bg, config.error_fg);
can_draw_clock = false;
break :draw_clock;
}
buffer.drawLabel(clock_str, buffer.width - @min(buffer.width, clock_str.len), 0);
}
@@ -760,6 +764,9 @@ pub fn main() !void {
}
_ = std.posix.waitpid(session_pid, 0);
// HACK: It seems like the session process is not exiting immediately after the waitpid call.
// This is a workaround to ensure the session process has exited before re-initializing the TTY.
std.Thread.sleep(std.time.ns_per_s * 1);
session_pid = -1;
}

View File

@@ -207,9 +207,9 @@ pub fn drawColorLabel(text: []const u8, x: usize, y: usize, fg: u32, bg: u32) vo
const utf8view = std.unicode.Utf8View.init(text) catch return;
var utf8 = utf8view.iterator();
var i = x;
while (utf8.nextCodepoint()) |codepoint| : (i += 1) {
_ = termbox.tb_set_cell(@intCast(i), yc, codepoint, fg, bg);
var i: c_int = @intCast(x);
while (utf8.nextCodepoint()) |codepoint| : (i += termbox.tb_wcwidth(codepoint)) {
_ = termbox.tb_set_cell(i, yc, codepoint, fg, bg);
}
}
@@ -218,10 +218,10 @@ pub fn drawConfinedLabel(self: TerminalBuffer, text: []const u8, x: usize, y: us
const utf8view = std.unicode.Utf8View.init(text) catch return;
var utf8 = utf8view.iterator();
var i: usize = 0;
while (utf8.nextCodepoint()) |codepoint| : (i += 1) {
var i: c_int = @intCast(x);
while (utf8.nextCodepoint()) |codepoint| : (i += termbox.tb_wcwidth(codepoint)) {
if (i >= max_length) break;
_ = termbox.tb_set_cell(@intCast(i + x), yc, codepoint, self.fg, self.bg);
_ = termbox.tb_set_cell(i, yc, codepoint, self.fg, self.bg);
}
}
@@ -235,7 +235,7 @@ pub fn drawCharMultiple(self: TerminalBuffer, char: u32, x: usize, y: usize, len
pub fn strWidth(str: []const u8) !u8 {
const utf8view = try std.unicode.Utf8View.init(str);
var utf8 = utf8view.iterator();
var i: u8 = 0;
while (utf8.nextCodepoint()) |_| i += 1;
return i;
var i: c_int = 0;
while (utf8.nextCodepoint()) |codepoint| i += termbox.tb_wcwidth(codepoint);
return @intCast(i);
}