diff options
Diffstat (limited to 'src/gui')
| -rw-r--r-- | src/gui/gui.zig | 45 |
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; |
