Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions src/Loop.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub fn Loop(comptime T: type) type {
queue: Queue(T, 512),
thread: ?std.Io.Future(void) = null,
should_quit: bool = false,
resize_handler_installed: bool = false,

/// Initialize the event loop. This is an intrusive init so that we have
/// a stable pointer to register signal callbacks with posix TTYs
Expand All @@ -39,17 +40,33 @@ pub fn Loop(comptime T: type) type {
switch (builtin.os.tag) {
.windows => {},
else => {
if (!builtin.is_test) {
const handler: Tty.SignalHandler = .{
.context = self,
.callback = Self.winsizeCallback,
};
try Tty.notifyWinsize(handler);
if (!builtin.is_test and !self.resize_handler_installed) {
try Tty.notifyWinsize(self.resizeHandler());
self.resize_handler_installed = true;
}
},
}
}

pub fn uninstallResizeHandler(self: *Self) void {
switch (builtin.os.tag) {
.windows => {},
else => {
if (!builtin.is_test and self.resize_handler_installed) {
Tty.removeWinsize(self.resizeHandler());
self.resize_handler_installed = false;
}
},
}
}

fn resizeHandler(self: *Self) Tty.SignalHandler {
return .{
.context = self,
.callback = Self.winsizeCallback,
};
}

/// spawns the input thread to read input from the tty
pub fn start(self: *Self) !void {
if (self.thread) |_| return;
Expand Down
46 changes: 46 additions & 0 deletions src/tty.zig
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ pub const PosixTty = struct {

/// Resets the signal handler to it's default
pub fn resetSignalHandler() void {
if (!handler_installed) {
handler_idx = 0;
return;
}

handler_mutex.lock(handler_io) catch @panic("unable to lock SIGWINCH handlers");
defer handler_mutex.unlock(handler_io);
handler_idx = 0;
resetSignalHandlerLocked();
}

fn resetSignalHandlerLocked() void {
if (!handler_installed) return;
handler_installed = false;
var act = posix.Sigaction{
Expand Down Expand Up @@ -129,6 +141,25 @@ pub const PosixTty = struct {
handler_idx += 1;
}

/// Remove a previously installed winsize signal handler
pub fn removeWinsize(handler: SignalHandler) void {
handler_mutex.lock(handler_io) catch @panic("unable to lock SIGWINCH handlers");
defer handler_mutex.unlock(handler_io);

var i: usize = 0;
while (i < handler_idx) : (i += 1) {
if (handlers[i].context == handler.context and handlers[i].callback == handler.callback) {
handler_idx -= 1;
if (i < handler_idx) {
std.mem.copyForwards(SignalHandler, handlers[i..handler_idx], handlers[i + 1 .. handler_idx + 1]);
}
handlers[handler_idx] = undefined;
if (handler_idx == 0) resetSignalHandlerLocked();
return;
}
}
}

fn handleWinch(_: std.posix.SIG) callconv(.c) void {
handler_mutex.lock(handler_io) catch @panic("unable to lock SIGWINCH handlers");
defer handler_mutex.unlock(handler_io);
Expand Down Expand Up @@ -211,6 +242,11 @@ pub const WindowsTty = struct {

const utf8_codepage: c_uint = 65001;

pub const SignalHandler = struct {
context: *anyopaque,
callback: *const fn (context: *anyopaque) void,
};

/// The input mode set by init
pub const input_raw_mode: CONSOLE_MODE_INPUT = .{
.WINDOW_INPUT = 1, // resize events
Expand Down Expand Up @@ -757,6 +793,11 @@ pub const TestTty = switch (builtin.os.tag) {
pipe_write: posix.fd_t,
tty_writer: *std.Io.Writer.Allocating,

pub const SignalHandler = struct {
context: *anyopaque,
callback: *const fn (context: *anyopaque) void,
};

/// Initializes a TestTty.
pub fn init(_: std.Io, buffer: []u8) !@This() {
_ = buffer;
Expand Down Expand Up @@ -814,6 +855,11 @@ pub const TestTty = switch (builtin.os.tag) {
else => struct {
d: std.Io.Writer.Discarding,

pub const SignalHandler = struct {
context: *anyopaque,
callback: *const fn (context: *anyopaque) void,
};

pub fn init(_: std.Io, buf: []u8) !@This() {
return .{
.d = .init(buf),
Expand Down
14 changes: 7 additions & 7 deletions src/vxfw/App.zig
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ pub fn run(self: *App, widget: vxfw.Widget, opts: Options) anyerror!void {
try vx.setBracketedPaste(tty.writer(), true);
try vx.subscribeToColorSchemeUpdates(tty.writer());

{
// This part deserves a comment. loop.installResizeHandler installs
// a signal handler for the tty. We wait to installResizeHandler the
// loop until we know if we need this handler. We don't need it if the
// terminal supports in-band-resize.
if (!vx.state.in_band_resize) try loop.installResizeHandler();
}
// This part deserves a comment. loop.installResizeHandler installs
// a signal handler for the tty. We wait to installResizeHandler the
// loop until we know if we need this handler. We don't need it if the
// terminal supports in-band-resize.
const use_signal_resize = !vx.state.in_band_resize;
if (use_signal_resize) try loop.installResizeHandler();
defer if (use_signal_resize) loop.uninstallResizeHandler();

// NOTE: We don't use pixel mouse anywhere
vx.caps.sgr_pixels = false;
Expand Down
Loading