diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 18:14:36 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | f41d0209f65237568c9f7d527d5989ac8921b74c (patch) | |
| tree | c313dc20fa0593ecff725de32d6ad191b01d82ac /src/config.zig | |
| parent | b4781b334a06d16aedb0b6a3d604cb249eb619de (diff) | |
| download | pardes-f41d0209f65237568c9f7d527d5989ac8921b74c.tar.gz pardes-f41d0209f65237568c9f7d527d5989ac8921b74c.zip | |
Lift takes a style: shadow, surface, rim, glow or auto
The user wants Lift to read on dark themes, where a shadow has nothing to
darken. `Lift shadow|surface|rim|glow|auto` (`on` is auto, bare flips
auto and off): surface lightens the lifted part's ground about 5.5%
(Material-dark), rim is a thin soft light off its top and left edges,
glow a faint halo in the theme's accent (Chrome.accent, the focused box
colour), auto a shadow on a light page and surface with half a rim on a
dark one (by the page's luminance). Rim and glow are the soft kernel in a
light colour (no pre-warp: coloured light is laid on as is, within §8.2's
budget); each style is capped per theme so text keeps min(its contrast,
4.5) (tests: darkening and lightening over the native themes). The style
travels in the palette (Chrome.lift_style, one byte on the wire). Config
reports and ctl reads `Lift <style>`.
Shared files touched: config.zig, builtins.zig, ninep/ctl.zig,
detached/wire.zig (palette byte), gui.zig. Not touched: pardes.zig,
Messages.zig, mouse.zig.
Diffstat (limited to 'src/config.zig')
| -rw-r--r-- | src/config.zig | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/src/config.zig b/src/config.zig index 0ed8726a..f7e83e91 100644 --- a/src/config.zig +++ b/src/config.zig @@ -619,10 +619,11 @@ pub const Runtime = struct { /// A font's programming ligatures (`->`, `!=`) draw across their cells. /// Only a shell that shapes text has the setting (`Capabilities.ligatures`). ligatures: bool = true, - /// The focused pane and the notices stand off the page on soft shadows - /// (G1, docs/render-pipeline.md §9.1). Opt-in until the focus lift's + /// How the focused pane and the notices stand off the page (G1, + /// docs/render-pipeline.md §9.1), or off. Opt-in until the focus lift's /// default is decided. Only a pixel shell draws it (`Capabilities.lift`). - lift: bool = false, + lift: LiftStyle = .off, + /// Builtins announce themselves on the message row. verbose: bool = true, /// A message falls into its row and dissolves out of it. @@ -669,6 +670,13 @@ pub const Runtime = struct { pub const ShaderAnimation = enum { off, on, always }; + /// shadow: a soft drop shadow. surface: the lifted pane's ground + /// lightens, as a raised surface does on a dark theme. rim: a soft light + /// along its top and left edges. glow: a faint halo in the theme's + /// accent. auto: shadow on a light page, surface and a faint rim on a + /// dark one. + pub const LiftStyle = enum(u8) { off, shadow, surface, rim, glow, auto }; + /// Each pass the bundled Crt or a Shadertoy file. pub const Post = struct { pub const max = 8; @@ -822,7 +830,7 @@ pub const Runtime = struct { /// The message timings a setting word sets, each in milliseconds. pub const MessageTime = enum { linger, fall, dissolve }; - pub const Toggle = enum { colors, wrap, tree_context_tag_style, tag_bottom, debug, focus_tint, column_tags, syntax_bold, verbose, message_animation, ligatures, lift }; + pub const Toggle = enum { colors, wrap, tree_context_tag_style, tag_bottom, debug, focus_tint, column_tags, syntax_bold, verbose, message_animation, ligatures }; /// The bundled post pass, a Shadertoy file in shaders/post/. pub const Scene = enum { crt }; @@ -836,6 +844,8 @@ pub const Runtime = struct { window_blur, message_ms: MessageTime, dump_dir, + /// A lift style, `on` (auto) or `off`; bare flips auto and off. + lift, transition: animation.Transition, scene: Scene, /// A Shadertoy file into the post chain or out of it; `off` empties @@ -870,7 +880,7 @@ pub const Runtime = struct { .{ .word = "Verbose", .action = .{ .toggle = .verbose } }, .{ .word = "MessageAnimation", .action = .{ .toggle = .message_animation } }, .{ .word = "Ligatures", .action = .{ .toggle = .ligatures }, .availability = .ligatures }, - .{ .word = "Lift", .action = .{ .toggle = .lift }, .availability = .lift }, + .{ .word = "Lift", .action = .lift, .availability = .lift }, .{ .word = "MessageLinger", .action = .{ .message_ms = .linger } }, .{ .word = "MessageFall", .action = .{ .message_ms = .fall } }, .{ .word = "MessageDissolve", .action = .{ .message_ms = .dissolve } }, @@ -932,9 +942,11 @@ pub const Runtime = struct { @compileError("scene effects must use the scene-shader capability"), // A toggle is plain state any shell can hold, except one for // what only some shells draw: that one exists where they do. - .toggle => |field| if (field == .ligatures or field == .lift) { - if (setting.availability == null or !std.mem.eql(u8, @tagName(setting.availability.?), @tagName(field))) - @compileError("a pixel shell's toggle must use its own capability: " ++ @tagName(field)); + .lift => if (setting.availability != .lift) + @compileError("Lift must use the lift capability"), + .toggle => |field| if (field == .ligatures) { + if (setting.availability != .ligatures) + @compileError("the ligatures toggle must use the ligatures capability"); } else if (setting.availability != null) @compileError("unconditional toggles cannot carry a backend capability"), else => if (setting.availability != null) @@ -1053,6 +1065,15 @@ pub const Runtime = struct { const text = std.mem.trim(u8, argument orelse return false, " \t\r\n"); state.shader_animation = std.meta.stringToEnum(ShaderAnimation, text) orelse return false; }, + .lift => { + const text = std.mem.trim(u8, argument orelse "", " \t\r\n"); + state.lift = if (text.len == 0) + (if (state.lift == .off) .auto else .off) + else if (std.mem.eql(u8, text, "on")) + .auto + else + std.meta.stringToEnum(LiftStyle, text) orelse return false; + }, .theme, .font => return false, } return true; @@ -1222,6 +1243,10 @@ pub const Runtime = struct { try out.print("{s} {s}\n", .{ setting.word, @tagName(state.shader_animation) }) else try out.print("{s} unsupported\n", .{setting.word}), + .lift => if (setting.enabled(context.capabilities)) + try out.print("{s} {s}\n", .{ setting.word, @tagName(state.lift) }) + else + try out.print("{s} unsupported\n", .{setting.word}), }; if (context.startup_config_path) |path| @@ -1353,6 +1378,21 @@ pub const Runtime = struct { try std.testing.expectEqual(@as(u8, 0), state.post.level(.crt)); } + test "Lift takes a style, on is auto, and bare flips it off and back to auto" { + var state: Runtime = .{}; + const lift = find("Lift").?; + try std.testing.expect(apply(&state, lift, null)); + try std.testing.expectEqual(LiftStyle.auto, state.lift); + try std.testing.expect(apply(&state, lift, "rim")); + try std.testing.expectEqual(LiftStyle.rim, state.lift); + try std.testing.expect(apply(&state, lift, null)); + try std.testing.expectEqual(LiftStyle.off, state.lift); + try std.testing.expect(apply(&state, lift, "on")); + try std.testing.expectEqual(LiftStyle.auto, state.lift); + try std.testing.expect(!apply(&state, lift, "sparkle")); + try std.testing.expectEqual(LiftStyle.auto, state.lift); + } + test "tagline size validates before mutating live state" { const setting = find("TaglineSize").?; var state: Runtime = .{}; @@ -1474,6 +1514,7 @@ pub const Runtime = struct { .dump_dir => "~/dumps", .shader => "~/crt.glsl", .shader_animation => "always", + .lift => "glow", else => null, }; try std.testing.expect(apply(&state, setting, argument)); @@ -1494,7 +1535,6 @@ pub const Runtime = struct { .verbose => "Verbose off\n", .message_animation => "MessageAnimation off\n", .ligatures => "Ligatures off\n", - .lift => "Lift on\n", }, .shell => "Shell requested (new panes) fish\n", .tagline_size => "TaglineSize 73\n", @@ -1525,6 +1565,7 @@ pub const Runtime = struct { }, .shader => "Shader ~/crt.glsl\n", .shader_animation => "ShaderAnimation always\n", + .lift => "Lift glow\n", .theme, .font => unreachable, }; try std.testing.expect(std.mem.indexOf(u8, report, expected) != null); |
