summaryrefslogtreecommitdiff
path: root/src/gui/gui.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/gui.zig')
-rw-r--r--src/gui/gui.zig45
1 files changed, 20 insertions, 25 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index 11e9f53b..8442c197 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -29,7 +29,6 @@ const std = @import("std");
const builtin = @import("builtin");
const posix = std.posix;
const libc = std.c;
-const linux = std.os.linux; // inotify constants; referenced only on linux
const vaxis = @import("vaxis"); // test modes only: the stdin escape-seq parser
const ghostty_vt = @import("ghostty-vt"); // 256-color palette for .index cells
const pardes = @import("../pardes.zig");
@@ -1160,6 +1159,12 @@ fn spawnReader(gpa: std.mem.Allocator, pt: Pty, pane: u8, gen: u32, q: *Queue) v
/// the pty readers, and ended the same way — teardown closes the fd, the read
/// fails, the thread returns.
fn watchThread(fd: c_int, q: *Queue) void {
+ // A kqueue cannot be read, so the macos arm parks in kevent(2) instead and
+ // is released by the teardown's `file_watch.stop`. See file_watch.wait.
+ if (comptime builtin.os.tag != .linux) {
+ while (file_watch.wait(fd)) q.push(.files_changed);
+ return;
+ }
var buf: [4096]u8 = undefined;
while (true) {
const n = libc.read(fd, &buf, buf.len);
@@ -2100,13 +2105,17 @@ fn localSession(
}
var pipe_tasks: PipeTasks = .{};
defer pipe_tasks.cancelAll(io);
- // One inotify instance for every watched pane, opened here — before any
- // thread exists — so the pre-loop drain below can already mark the file a
- // positional path argument opened. -1 off linux: watchPane goes quiet and
- // the core simply never gets a file_changed event.
- var inotify_fd: c_int = if (builtin.os.tag == .linux) libc.inotify_init1(linux.IN.CLOEXEC) else -1;
+ // One watcher for every watched pane, opened here — before any thread
+ // exists — so the pre-loop drain below can already mark the file a
+ // positional path argument opened. `false`: this host parks a thread in it
+ // rather than polling it. -1 where there is no watcher to make: watchPane
+ // goes quiet and the core simply never gets a file_changed event.
+ var inotify_fd: c_int = file_watch.init(false);
defer if (inotify_fd >= 0) {
- _ = libc.close(inotify_fd); // ends the detached watcher's read
+ // `stop` releases a kqueue wait (macos); the close ends the blocking
+ // read (linux). Both leave watchThread on its way out.
+ file_watch.stop(inotify_fd);
+ _ = libc.close(inotify_fd);
inotify_fd = -1;
};
var watches: file_watch.Table = @splat(null);
@@ -5345,24 +5354,10 @@ const ResolvedCell = struct {
clear_bg: bool = false,
};
-fn topbarPaneBorderPixels(cell_h: u32, tagline_h: u32) u32 {
- const spare = cell_h -| tagline_h;
- return @min(@as(u32, config.gui_topbar_pane_border_px), spare * 2);
-}
-
-/// Vertical offset of a tagline band inside its body-sized logical row. Row
-/// zero and the first pane-tag row face a shared rule instead of centering two
-/// independent bands. A Tagbottom band on the final grid row faces the window
-/// edge, eliminating the matching unused half-band at the bottom.
-fn taglineBandOffset(row: u16, canvas_h: f32, cell_h: u32, tagline_h: u32) u32 {
- const spare = cell_h -| tagline_h;
- const border = topbarPaneBorderPixels(cell_h, tagline_h);
- if (row == 0) return spare - border / 2;
- if (row == pardes.TOPBAR_H) return border - border / 2;
- const rows: u32 = @max(1, @as(u32, @intFromFloat(@floor(canvas_h / @as(f32, @floatFromInt(cell_h))))));
- if (@as(u32, row) + 1 >= rows) return spare;
- return spare / 2;
-}
+// Both moved to the core so the AppKit shell can call the SAME rule over the C
+// ABI instead of keeping a second copy of it — see pardes.taglineBandOffset.
+const topbarPaneBorderPixels = pardes.topbarPaneBorderPixels;
+const taglineBandOffset = pardes.taglineBandOffset;
fn topbarPaneBorderHeight(surface: *const pardes.Surface, cell_h: u32, tagline_h: u32) ?u32 {
if (surface.rows <= pardes.TOPBAR_H) return null;