diff --git a/src/Surface.zig b/src/Surface.zig index a62f9b759..6d28c33c4 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -277,10 +277,10 @@ const DerivedConfig = struct { .macos_non_native_fullscreen = config.@"macos-non-native-fullscreen", .macos_option_as_alt = config.@"macos-option-as-alt", .vt_kam_allowed = config.@"vt-kam-allowed", - .window_padding_top = config.@"window-padding-y" orelse config.@"window-padding-top", - .window_padding_bottom = config.@"window-padding-y" orelse config.@"window-padding-bottom", - .window_padding_left = config.@"window-padding-x" orelse config.@"window-padding-left", - .window_padding_right = config.@"window-padding-x" orelse config.@"window-padding-right", + .window_padding_top = config.@"window-padding-y".top_left, + .window_padding_bottom = config.@"window-padding-y".bottom_right, + .window_padding_left = config.@"window-padding-x".top_left, + .window_padding_right = config.@"window-padding-x".bottom_right, .window_padding_balance = config.@"window-padding-balance", .title = config.title, .links = links, @@ -346,19 +346,19 @@ pub fn init( // Convert our padding from points to pixels const padding_top: u32 = padding_top: { - const padding_top: f32 = @floatFromInt(config.@"window-padding-y" orelse config.@"window-padding-top"); + const padding_top: f32 = @floatFromInt(derived_config.window_padding_top); break :padding_top @intFromFloat(@floor(padding_top * y_dpi / 72)); }; const padding_bottom: u32 = padding_bottom: { - const padding_bottom: f32 = @floatFromInt(config.@"window-padding-y" orelse config.@"window-padding-bottom"); + const padding_bottom: f32 = @floatFromInt(derived_config.window_padding_bottom); break :padding_bottom @intFromFloat(@floor(padding_bottom * y_dpi / 72)); }; const padding_left: u32 = padding_left: { - const padding_left: f32 = @floatFromInt(config.@"window-padding-x" orelse config.@"window-padding-left"); + const padding_left: f32 = @floatFromInt(derived_config.window_padding_left); break :padding_left @intFromFloat(@floor(padding_left * x_dpi / 72)); }; const padding_right: u32 = padding_right: { - const padding_right: f32 = @floatFromInt(config.@"window-padding-y" orelse config.@"window-padding-right"); + const padding_right: f32 = @floatFromInt(derived_config.window_padding_right); break :padding_right @intFromFloat(@floor(padding_right * x_dpi / 72)); }; const padding: renderer.Padding = .{ diff --git a/src/config/Config.zig b/src/config/Config.zig index f17bb44e6..383c5d6ad 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -652,11 +652,12 @@ keybind: Keybinds = .{}, /// Changing this configuration at runtime will only affect new terminals, i.e. /// new windows, tabs, etc. /// -/// If this value is set, the value of `window-padding-left` and -/// `window-padding-right` will have no effect. -/// -/// By default, this value is unset. -@"window-padding-x": ?u32 = null, +/// To set a different left and right padding, specify two numerical values +/// separated by a comma. For example, `window-padding-x = 2,4` will set the +/// left padding to 2 and the right padding to 4. If you want to set both +/// paddings to the same value, you can use a single value. For example, +/// `window-padding-x = 2` will set both paddings to 2. +@"window-padding-x": WindowPadding = .{ .top_left = 2, .bottom_right = 2 }, /// Vertical window padding. This applies padding between the terminal cells and /// the top and bottom window borders. The value is in points, meaning that it @@ -670,79 +671,12 @@ keybind: Keybinds = .{}, /// Changing this configuration at runtime will only affect new terminals, /// i.e. new windows, tabs, etc. /// -/// If this value is set, the value of `window-padding-top` and -/// `window-padding-bottom` will have no effect. -/// -/// By default, this value is unset. -@"window-padding-y": ?u32 = null, - -/// Top window padding. This applies padding between the terminal cells and the -/// top window border. The value is in points, meaning that it will be scaled -/// appropriately for screen DPI. -/// -/// If this value is set too large, the screen will render nothing, because the -/// grid will be completely squished by the padding. It is up to you as the user -/// to pick a reasonable value. If you pick an unreasonable value, a warning -/// will appear in the logs. -/// -/// Changing this configuration at runtime will only affect new terminals, -/// i.e. new windows, tabs, etc. -/// -/// If `window-padding-y` is set, this value will be ignored. -/// -/// This value is set to 2 by default. -@"window-padding-top": u32 = 2, - -/// Bottom window padding. This applies padding between the terminal cells and -/// the bottom window border. The value is in points, meaning that it will be -/// scaled appropriately for screen DPI. -/// -/// If this value is set too large, the screen will render nothing, because the -/// grid will be completely squished by the padding. It is up to you as the user -/// to pick a reasonable value. If you pick an unreasonable value, a warning -/// will appear in the logs. -/// -/// Changing this configuration at runtime will only affect new terminals, -/// i.e. new windows, tabs, etc. -/// -/// If `window-padding-y` is set, this value will be ignored. -/// -/// This value is set to 2 by default. -@"window-padding-bottom": u32 = 2, - -/// Left window padding. This applies padding between the terminal cells and the -/// left window border. The value is in points, meaning that it will be scaled -/// appropriately for screen DPI. -/// -/// If this value is set too large, the screen will render nothing, because the -/// grid will be completely squished by the padding. It is up to you as the user -/// to pick a reasonable value. If you pick an unreasonable value, a warning -/// will appear in the logs. -/// -/// Changing this configuration at runtime will only affect new terminals, -/// i.e. new windows, tabs, etc. -/// -/// If `window-padding-x` is set, this value will be ignored. -/// -/// This value is set to 2 by default. -@"window-padding-left": u32 = 2, - -/// Right window padding. This applies padding between the terminal cells and -/// the right window border. The value is in points, meaning that it will be -/// scaled appropriately for screen DPI. -/// -/// If this value is set too large, the screen will render nothing, because the -/// grid will be completely squished by the padding. It is up to you as the user -/// to pick a reasonable value. If you pick an unreasonable value, a warning -/// will appear in the logs. -/// -/// Changing this configuration at runtime will only affect new terminals, -/// i.e. new windows, tabs, etc. -/// -/// If `window-padding-x` is set, this value will be ignored. -/// -/// This value is set to 2 by default. -@"window-padding-right": u32 = 2, +/// To set a different top and bottom padding, specify two numerical values +/// separated by a comma. For example, `window-padding-y = 2,4` will set the +/// top padding to 2 and the bottom padding to 4. If you want to set both +/// paddings to the same value, you can use a single value. For example, +/// `window-padding-y = 2` will set both paddings to 2. +@"window-padding-y": WindowPadding = .{ .top_left = 2, .bottom_right = 2 }, /// The viewport dimensions are usually not perfectly divisible by the cell /// size. In this case, some extra padding on the end of a column and the bottom @@ -4067,6 +4001,99 @@ pub const Duration = struct { } }; +pub const WindowPadding = struct { + const Self = @This(); + + top_left: u32 = 0, + bottom_right: u32 = 0, + + pub fn clone(self: Self, _: Allocator) !Self { + return self; + } + + pub fn equal(self: Self, other: Self) bool { + return std.meta.eql(self, other); + } + + pub fn parseCLI(input_: ?[]const u8) !WindowPadding { + const input = input_ orelse return error.ValueRequired; + const whitespace = " \t"; + + if (std.mem.indexOf(u8, input, ",")) |idx| { + const input_left = std.mem.trim(u8, input[0..idx], whitespace); + const input_right = std.mem.trim(u8, input[idx + 1 ..], whitespace); + const left = std.fmt.parseInt(u32, input_left, 10) catch + return error.InvalidValue; + const right = std.fmt.parseInt(u32, input_right, 10) catch + return error.InvalidValue; + return .{ .top_left = left, .bottom_right = right }; + } else { + const value = std.fmt.parseInt( + u32, + std.mem.trim(u8, input, whitespace), + 10, + ) catch return error.InvalidValue; + return .{ .top_left = value, .bottom_right = value }; + } + } + + pub fn formatEntry(self: Self, formatter: anytype) !void { + var buf: [128]u8 = undefined; + if (self.top_left == self.bottom_right) { + try formatter.formatEntry( + []const u8, + std.fmt.bufPrint( + &buf, + "{}", + .{self.top_left}, + ) catch return error.OutOfMemory, + ); + } else { + try formatter.formatEntry( + []const u8, + std.fmt.bufPrint( + &buf, + "{},{}", + .{ self.top_left, self.bottom_right }, + ) catch return error.OutOfMemory, + ); + } + } + + test "parse WindowPadding" { + const testing = std.testing; + + { + const v = try WindowPadding.parseCLI("100"); + try testing.expectEqual(WindowPadding{ + .top_left = 100, + .bottom_right = 100, + }, v); + } + + { + const v = try WindowPadding.parseCLI("100,200"); + try testing.expectEqual(WindowPadding{ + .top_left = 100, + .bottom_right = 200, + }, v); + } + + // Trim whitespace + { + const v = try WindowPadding.parseCLI(" 100 , 200 "); + try testing.expectEqual(WindowPadding{ + .top_left = 100, + .bottom_right = 200, + }, v); + } + + try testing.expectError(error.ValueRequired, WindowPadding.parseCLI(null)); + try testing.expectError(error.InvalidValue, WindowPadding.parseCLI("")); + try testing.expectError(error.InvalidValue, WindowPadding.parseCLI("a")); + } +}; + test "parse duration" { inline for (Duration.units) |unit| { var buf: [16]u8 = undefined;