From 04f1586e8ff129edfa09fed0efea2afec171fe4b Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Thu, 30 May 2024 09:34:12 -0500 Subject: [PATCH] vaxis: add panic handler function Applications may use this to handle panics gracefully --- src/main.zig | 20 ++++++++++++++++++++ src/tty.zig | 11 ++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main.zig b/src/main.zig index 718ed46..51ccb4b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,7 +1,10 @@ const std = @import("std"); +const builtin = @import("builtin"); pub const Vaxis = @import("Vaxis.zig"); + pub const Loop = @import("Loop.zig").Loop; +pub const xev = @import("xev.zig"); pub const Queue = @import("queue.zig").Queue; pub const Key = @import("Key.zig"); @@ -22,12 +25,29 @@ pub const Winsize = tty.Winsize; pub const widgets = @import("widgets.zig"); pub const gwidth = @import("gwidth.zig"); +pub const ctlseqs = @import("ctlseqs.zig"); /// Initialize a Vaxis application. pub fn init(alloc: std.mem.Allocator, opts: Vaxis.Options) !Vaxis { return Vaxis.init(alloc, opts); } +/// Resets terminal state on a panic, then calls the default zig panic handler +pub fn panic_handler(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn { + if (Tty.global_tty) |gty| { + const reset: []const u8 = ctlseqs.csi_u_pop ++ + ctlseqs.mouse_reset ++ + ctlseqs.bp_reset ++ + ctlseqs.rmcup; + + gty.anyWriter().writeAll(reset) catch {}; + + gty.deinit(); + } + + std.builtin.default_panic(msg, error_return_trace, ret_addr); +} + /// the vaxis logo. In PixelCode pub const logo = \\▄ ▄ ▄▄▄ ▄ ▄ ▄▄▄ ▄▄▄ diff --git a/src/tty.zig b/src/tty.zig index 10d2a16..f22b029 100644 --- a/src/tty.zig +++ b/src/tty.zig @@ -35,6 +35,11 @@ pub const PosixTty = struct { var handler_mutex: std.Thread.Mutex = .{}; var handler_idx: usize = 0; + /// global tty instance, used in case of a panic. Not guaranteed to work if + /// for some reason there are multiple TTYs open under a single vaxis + /// compilation unit - but this is better than nothing + pub var global_tty: ?PosixTty = null; + /// initializes a Tty instance by opening /dev/tty and "making it raw". A /// signal handler is installed for SIGWINCH. No callbacks are installed, be /// sure to register a callback when initializing the event loop @@ -56,10 +61,14 @@ pub const PosixTty = struct { }; try posix.sigaction(posix.SIG.WINCH, &act, null); - return .{ + const self: PosixTty = .{ .fd = fd, .termios = termios, }; + + global_tty = self; + + return self; } /// release resources associated with the Tty return it to its original state