Merge pull request #2034 from jcollie/asymmetric-window-padding

Implement asymmetric window padding.
This commit is contained in:
Mitchell Hashimoto
2024-08-05 15:56:15 -07:00
committed by GitHub
3 changed files with 167 additions and 31 deletions

View File

@ -217,8 +217,10 @@ const DerivedConfig = struct {
macos_non_native_fullscreen: configpkg.NonNativeFullscreen, macos_non_native_fullscreen: configpkg.NonNativeFullscreen,
macos_option_as_alt: configpkg.OptionAsAlt, macos_option_as_alt: configpkg.OptionAsAlt,
vt_kam_allowed: bool, vt_kam_allowed: bool,
window_padding_x: u32, window_padding_top: u32,
window_padding_y: u32, window_padding_bottom: u32,
window_padding_left: u32,
window_padding_right: u32,
window_padding_balance: bool, window_padding_balance: bool,
title: ?[:0]const u8, title: ?[:0]const u8,
links: []Link, links: []Link,
@ -275,8 +277,10 @@ const DerivedConfig = struct {
.macos_non_native_fullscreen = config.@"macos-non-native-fullscreen", .macos_non_native_fullscreen = config.@"macos-non-native-fullscreen",
.macos_option_as_alt = config.@"macos-option-as-alt", .macos_option_as_alt = config.@"macos-option-as-alt",
.vt_kam_allowed = config.@"vt-kam-allowed", .vt_kam_allowed = config.@"vt-kam-allowed",
.window_padding_x = config.@"window-padding-x", .window_padding_top = config.@"window-padding-y".top_left,
.window_padding_y = config.@"window-padding-y", .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", .window_padding_balance = config.@"window-padding-balance",
.title = config.title, .title = config.title,
.links = links, .links = links,
@ -341,19 +345,27 @@ pub fn init(
const cell_size = font_grid.cellSize(); const cell_size = font_grid.cellSize();
// Convert our padding from points to pixels // Convert our padding from points to pixels
const padding_x: u32 = padding_x: { const padding_top: u32 = padding_top: {
const padding_x: f32 = @floatFromInt(config.@"window-padding-x"); const padding_top: f32 = @floatFromInt(derived_config.window_padding_top);
break :padding_x @intFromFloat(@floor(padding_x * x_dpi / 72)); break :padding_top @intFromFloat(@floor(padding_top * y_dpi / 72));
}; };
const padding_y: u32 = padding_y: { const padding_bottom: u32 = padding_bottom: {
const padding_y: f32 = @floatFromInt(config.@"window-padding-y"); const padding_bottom: f32 = @floatFromInt(derived_config.window_padding_bottom);
break :padding_y @intFromFloat(@floor(padding_y * y_dpi / 72)); break :padding_bottom @intFromFloat(@floor(padding_bottom * y_dpi / 72));
};
const padding_left: u32 = 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(derived_config.window_padding_right);
break :padding_right @intFromFloat(@floor(padding_right * x_dpi / 72));
}; };
const padding: renderer.Padding = .{ const padding: renderer.Padding = .{
.top = padding_y, .top = padding_top,
.bottom = padding_y, .bottom = padding_bottom,
.right = padding_x, .left = padding_left,
.left = padding_x, .right = padding_right,
}; };
// Create our terminal grid with the initial size // Create our terminal grid with the initial size
@ -1825,20 +1837,28 @@ pub fn contentScaleCallback(self: *Surface, content_scale: apprt.ContentScale) !
// Update our padding which is dependent on DPI. // Update our padding which is dependent on DPI.
self.padding = padding: { self.padding = padding: {
const padding_x: u32 = padding_x: { const padding_top: u32 = padding_top: {
const padding_x: f32 = @floatFromInt(self.config.window_padding_x); const padding_top: f32 = @floatFromInt(self.config.window_padding_top);
break :padding_x @intFromFloat(@floor(padding_x * x_dpi / 72)); break :padding_top @intFromFloat(@floor(padding_top * y_dpi / 72));
}; };
const padding_y: u32 = padding_y: { const padding_bottom: u32 = padding_bottom: {
const padding_y: f32 = @floatFromInt(self.config.window_padding_y); const padding_bottom: f32 = @floatFromInt(self.config.window_padding_bottom);
break :padding_y @intFromFloat(@floor(padding_y * y_dpi / 72)); break :padding_bottom @intFromFloat(@floor(padding_bottom * y_dpi / 72));
};
const padding_left: u32 = padding_left: {
const padding_left: f32 = @floatFromInt(self.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(self.config.window_padding_right);
break :padding_right @intFromFloat(@floor(padding_right * x_dpi / 72));
}; };
break :padding .{ break :padding .{
.top = padding_y, .top = padding_top,
.bottom = padding_y, .bottom = padding_bottom,
.right = padding_x, .left = padding_left,
.left = padding_x, .right = padding_right,
}; };
}; };

View File

@ -12,7 +12,7 @@ pub const fish_completions = comptimeGenerateFishCompletions();
fn comptimeGenerateFishCompletions() []const u8 { fn comptimeGenerateFishCompletions() []const u8 {
comptime { comptime {
@setEvalBranchQuota(15000); @setEvalBranchQuota(16000);
var counter = std.io.countingWriter(std.io.null_writer); var counter = std.io.countingWriter(std.io.null_writer);
try writeFishCompletions(&counter.writer()); try writeFishCompletions(&counter.writer());

View File

@ -650,10 +650,28 @@ class: ?[:0]const u8 = null,
/// "unconsumed:ctrl+a=reload_config" /// "unconsumed:ctrl+a=reload_config"
keybind: Keybinds = .{}, keybind: Keybinds = .{},
/// Window padding. This applies padding between the terminal cells and the /// Horizontal window padding. This applies padding between the terminal cells
/// window border. The `x` option applies to the left and right padding and the /// and the left and right window borders. The value is in points, meaning that
/// `y` option is top and bottom. The value is in points, meaning that it will /// it will be scaled appropriately for screen DPI.
/// 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.
///
/// 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
/// will be scaled appropriately for screen DPI.
/// ///
/// If this value is set too large, the screen will render nothing, because the /// 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 /// grid will be completely squished by the padding. It is up to you as the user
@ -662,8 +680,13 @@ keybind: Keybinds = .{},
/// ///
/// Changing this configuration at runtime will only affect new terminals, /// Changing this configuration at runtime will only affect new terminals,
/// i.e. new windows, tabs, etc. /// i.e. new windows, tabs, etc.
@"window-padding-x": u32 = 2, ///
@"window-padding-y": 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 /// 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 /// size. In this case, some extra padding on the end of a column and the bottom
@ -4014,6 +4037,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" { test "parse duration" {
inline for (Duration.units) |unit| { inline for (Duration.units) |unit| {
var buf: [16]u8 = undefined; var buf: [16]u8 = undefined;