summaryrefslogtreecommitdiff
path: root/src/config.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-14 13:55:41 -0300
committerGabriel Schneider <[email protected]>2026-09-15 17:24:42 -0300
commit95681ff7017b8a9e4c8f9fa6a7371d1233432f2f (patch)
tree34787d6bb62944cc778624685387db7376ccf71b /src/config.zig
parent682e237df7e8b22f820d14a4adee58e6e2f84268 (diff)
downloadpardes-95681ff7017b8a9e4c8f9fa6a7371d1233432f2f.tar.gz
pardes-95681ff7017b8a9e4c8f9fa6a7371d1233432f2f.zip
9p: use cloud9 protocol sessions and transports
Diffstat (limited to 'src/config.zig')
-rw-r--r--src/config.zig69
1 files changed, 65 insertions, 4 deletions
diff --git a/src/config.zig b/src/config.zig
index 282e63da..865e2474 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -98,6 +98,7 @@ pub const leader_path = paths: {
table.set(.TaglineSize, null);
}
if (pardes.platform == .gui) table.set(.Pet, null);
+ if (builtins.capabilities.window_opacity) table.set(.WindowOpacity, null);
if (builtins.capabilities.panel_transitions) {
table.set(.PanelSlide, "as");
table.set(.PanelZoom, "az");
@@ -537,6 +538,8 @@ pub const Runtime = struct {
focus_tint: bool = true,
column_tags: bool = true,
syntax_bold: bool = false,
+ window_opacity: u8 = 100,
+ window_opacity_pending: bool = true,
pet: enum { off, cat, frog } = .off,
// Effective values change only after a host acknowledges the request.
@@ -625,6 +628,7 @@ pub const Runtime = struct {
panel_transitions: bool,
scene_shaders: bool,
tagline_font_size: bool,
+ window_opacity: bool = false,
};
pub const Capability = std.meta.FieldEnum(Capabilities);
@@ -638,6 +642,7 @@ pub const Runtime = struct {
theme,
font,
tagline_size,
+ window_opacity,
transition: layout.Transition,
scene: Scene,
};
@@ -649,7 +654,7 @@ pub const Runtime = struct {
pub fn takesArg(setting: Setting) bool {
return switch (setting.action) {
- .shell, .theme, .font, .tagline_size => true,
+ .shell, .theme, .font, .tagline_size, .window_opacity => true,
else => false,
};
}
@@ -675,6 +680,7 @@ pub const Runtime = struct {
.{ .word = "Shell", .action = .shell },
.{ .word = "Font", .action = .font, .availability = .font_picker },
.{ .word = "TaglineSize", .action = .tagline_size, .availability = .font_picker },
+ .{ .word = "WindowOpacity", .action = .window_opacity, .availability = .window_opacity },
.{ .word = "PanelSlide", .action = .{ .transition = .slide }, .availability = .panel_transitions },
.{ .word = "PanelZoom", .action = .{ .transition = .zoom }, .availability = .panel_transitions },
.{ .word = "PanelDissolve", .action = .{ .transition = .dissolve }, .availability = .panel_transitions },
@@ -716,6 +722,8 @@ pub const Runtime = struct {
switch (setting.action) {
.font, .tagline_size => if (setting.availability != .font_picker)
@compileError("native font settings must use the font-picker capability"),
+ .window_opacity => if (setting.availability != .window_opacity)
+ @compileError("window opacity must use the window-opacity capability"),
.transition => if (setting.availability != .panel_transitions)
@compileError("panel effects must use the panel-transition capability"),
.scene => if (setting.availability != .scene_shaders)
@@ -727,8 +735,8 @@ pub const Runtime = struct {
for (std.enums.values(Toggle)) |field| if (actionCount(.{ .toggle = field }) != 1)
@compileError("runtime toggle must occur exactly once: " ++ @tagName(field));
if (actionCount(.shell) != 1 or actionCount(.theme) != 1 or actionCount(.font) != 1 or
- actionCount(.tagline_size) != 1)
- @compileError("Shell, Theme, Font, and TaglineSize actions must each occur exactly once");
+ actionCount(.tagline_size) != 1 or actionCount(.window_opacity) != 1)
+ @compileError("Shell, Theme, Font, TaglineSize, and WindowOpacity actions must each occur exactly once");
for (std.enums.values(layout.Transition)) |effect| {
const expected: comptime_int = @intFromBool(effect != .off);
if (actionCount(.{ .transition = effect }) != expected)
@@ -764,6 +772,14 @@ pub const Runtime = struct {
if (percent < tagline_percent_min or percent > tagline_percent_max) return false;
state.font.tagline_percent = @intCast(percent);
},
+ .window_opacity => {
+ const text = std.mem.trim(u8, argument orelse return false, " \t\r\n");
+ for (text) |byte| if (!std.ascii.isDigit(byte)) return false;
+ const percent = std.fmt.parseInt(u8, text, 10) catch return false;
+ if (percent > 100) return false;
+ state.window_opacity = percent;
+ state.window_opacity_pending = true;
+ },
.transition => |effect| state.toggleTransition(effect),
.scene => |effect| switch (effect) {
inline else => |field| {
@@ -819,6 +835,16 @@ pub const Runtime = struct {
try out.print("{s}: {s}\n", .{ setting.word, onOff(value) });
},
.theme => try out.print("{s}: {s}\n", .{ setting.word, context.theme_name }),
+ .window_opacity => {
+ if (setting.enabled(context.capabilities))
+ try out.print("{s}: {d}%{s}\n", .{
+ setting.word,
+ state.window_opacity,
+ if (state.window_opacity_pending) " (pending)" else "",
+ })
+ else
+ try out.print("{s}: unsupported\n", .{setting.word});
+ },
.shell => {
const chosen = state.shell.requested.get();
try out.print(
@@ -917,7 +943,7 @@ pub const Runtime = struct {
for (settings[i + 1 ..]) |later|
try std.testing.expect(!std.mem.eql(u8, setting.word, later.word));
try std.testing.expectEqual(switch (setting.action) {
- .shell, .theme, .font, .tagline_size => true,
+ .shell, .theme, .font, .tagline_size, .window_opacity => true,
else => false,
}, setting.takesArg());
}
@@ -954,6 +980,33 @@ pub const Runtime = struct {
}
}
+ test "window opacity defaults to opaque validates atomically and retries" {
+ const setting = find("WindowOpacity").?;
+ var state: Runtime = .{};
+ try std.testing.expectEqual(@as(u8, 100), state.window_opacity);
+ try std.testing.expect(state.window_opacity_pending);
+ try std.testing.expect(setting.takesArg());
+ try std.testing.expectEqual(Capability.window_opacity, setting.availability.?);
+
+ for ([_][]const u8{ "0", " 85\n", "100" }, [_]u8{ 0, 85, 100 }) |argument, expected| {
+ state.window_opacity_pending = false;
+ try std.testing.expect(apply(&state, setting, argument));
+ try std.testing.expectEqual(expected, state.window_opacity);
+ try std.testing.expect(state.window_opacity_pending);
+ }
+
+ state.window_opacity = 85;
+ state.window_opacity_pending = false;
+ for ([_]?[]const u8{ null, "", " \t\n", "101", "-1", "+85", "85%", "0.5", "85.0", "85 20", "8_5", "0x55", "999999999999999999999" }) |argument| {
+ try std.testing.expect(!apply(&state, setting, argument));
+ try std.testing.expectEqual(@as(u8, 85), state.window_opacity);
+ try std.testing.expect(!state.window_opacity_pending);
+ }
+ // Reissuing the same request still asks the host to apply it again.
+ try std.testing.expect(apply(&state, setting, "85"));
+ try std.testing.expect(state.window_opacity_pending);
+ }
+
test "font request tuple rejects atomically" {
var state: Runtime = .{};
try std.testing.expect(requestFont(&state, "/fonts/old.ttf", "Old", 1200));
@@ -994,6 +1047,7 @@ pub const Runtime = struct {
.panel_transitions = true,
.scene_shaders = true,
.tagline_font_size = true,
+ .window_opacity = true,
},
.state = &state,
};
@@ -1006,6 +1060,7 @@ pub const Runtime = struct {
const argument: ?[]const u8 = switch (setting.action) {
.shell => "fish",
.tagline_size => "73",
+ .window_opacity => "85",
else => null,
};
try std.testing.expect(apply(&state, setting, argument));
@@ -1025,6 +1080,7 @@ pub const Runtime = struct {
},
.shell => "Shell requested (new panes): fish\n",
.tagline_size => "TaglineSize: 73%\n",
+ .window_opacity => "WindowOpacity: 85% (pending)\n",
.transition => |transition| switch (transition) {
.off => unreachable,
.slide => "Panel transition: PanelSlide\n",
@@ -1059,10 +1115,12 @@ pub const Runtime = struct {
state.font.tagline_percent = 82;
var out: std.Io.Writer = .fixed(&storage);
+ state.window_opacity_pending = false;
try writeReport(&out, context);
const report = storage[0..out.end];
for ([_][]const u8{
"Theme: acme\n",
+ "WindowOpacity: 85%\n",
"Font requested size: 18.50\n",
"Font requested: Wanted Mono\n",
"Font requested path: /fonts/wanted.ttf\n",
@@ -1095,6 +1153,9 @@ pub const Runtime = struct {
out = .fixed(&storage);
try writeReport(&out, defaults_context);
const defaults_report = storage[0..out.end];
+ try std.testing.expect(std.mem.indexOf(u8, defaults_report, "WindowOpacity: unsupported\n") != null);
+ try std.testing.expect(!find("WindowOpacity").?.enabled(defaults_context.capabilities));
+ try std.testing.expect(find("WindowOpacity").?.enabled(context.capabilities));
try std.testing.expect(std.mem.indexOf(u8, defaults_report, "Shell requested (new panes): /bin/sh (default)\n") != null);
try std.testing.expect(std.mem.indexOf(u8, defaults_report, "Shell effective (last spawn): (none)\n") != null);
try std.testing.expect(std.mem.indexOf(u8, defaults_report, "Shell pending: on\n") != null);