From 556c5b50bbfd4a6aaae192377d7810f610fc7d9e Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 16 Sep 2026 12:00:52 -0300 Subject: Let WindowOpacity through on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The builtin was gated on the SDL platform, so the macOS shell never registered it and the setting had nowhere to land. macOS already had transparency, but only the binary kind a theme decides — a theme with no background of its own drops the ground and the blur shows through. WindowOpacity is the graded, theme-independent version, and the window had no way to hear about it. pardes_window_opacity reports the percentage and acknowledges the request in one read, beside pardes_theme_bg: an SDL surface can arrive without an alpha channel and has to be able to refuse, while an AppKit window always composites per pixel, so there is nothing here to refuse and no rollback to perform. The view then paints the rule shaders/ui.frag.glsl states for the SDL shell: backgrounds — ground, cell and band fills, and the chrome rules over them — take the alpha, glyph ink never does, and the block cursor is exempt because it is foreground chrome that happens to be carried in a cell background. That exemption is why the cursor joins the colour in the background run key; it can no longer share a fill with the cells beside it. Two things the harness was missing fall out of testing it: it never adopted the theme background or the opacity, so a Theme or WindowOpacity in a script moved the core and never reached a pixel. draw-opacity records both ends of the alpha range, which is what makes the two-sided contract assertable — 60% reads 153..255, and 0% reads 0..255 with the ink still standing. Co-Authored-By: Claude Opus 5 (1M context) --- src/macos.zig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/macos.zig') diff --git a/src/macos.zig b/src/macos.zig index 3003fd46..67a5ec5b 100644 --- a/src/macos.zig +++ b/src/macos.zig @@ -875,6 +875,24 @@ export fn pardes_theme_bg() u32 { return @as(u32, bg[0]) << 16 | @as(u32, bg[1]) << 8 | bg[2]; } +/// The percentage the shell must paint window backgrounds at, read once per +/// pump beside pardes_theme_bg(). +/// +/// Reading it also ACKNOWLEDGES whatever `WindowOpacity` asked for. The SDL +/// shell has to answer that request because an SDL surface can arrive without +/// an alpha channel and the core must not claim a value the compositor +/// refused; an AppKit window always composites per pixel, so there is nothing +/// here to refuse and no rollback for the core to perform. +/// +/// The theme's own decision stays separate: a theme with no background of its +/// own (pardes_theme_bg == PARDES_COLOR_DEFAULT) drops the ground entirely, +/// whatever percentage is set here. +export fn pardes_window_opacity() u8 { + const st = &(state orelse return 100); + st.core.settings.window_opacity_pending = false; + return st.core.settings.window_opacity; +} + fn taglineFontPercent(core: ?*const pardes.Pardes) u8 { return if (core) |p| p.settings.font.tagline_percent else pardes.config.gui_tagline_font_percent; } @@ -2437,6 +2455,7 @@ test "pardes.h declares every export the way it is defined" { try expectSameAbi(@TypeOf(c.pardes_active_path), @TypeOf(pardes_active_path)); try expectSameAbi(@TypeOf(c.pardes_active_dirty), @TypeOf(pardes_active_dirty)); try expectSameAbi(@TypeOf(c.pardes_theme_bg), @TypeOf(pardes_theme_bg)); + try expectSameAbi(@TypeOf(c.pardes_window_opacity), @TypeOf(pardes_window_opacity)); } test "pardes.h matches the Zig boundary" { -- cgit v1.3