mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-11 03:39:36 +00:00
terminal: clamp mirrored selection corners
Rectangle orientation swaps endpoint columns when a selection is mirrored. During incomplete reflow, copying a column from a wider page onto the narrower corner page created an invalid pin that panicked when resolved. Clamp every swapped column to the page that owns the oriented corner. Top-left and bottom-right calculations now always return valid pins.
This commit is contained in:
@@ -155,12 +155,12 @@ pub fn topLeft(self: Selection, s: *const Screen) Pin {
|
||||
.reverse => self.end(),
|
||||
.mirrored_forward => pin: {
|
||||
var p = self.start();
|
||||
p.x = self.end().x;
|
||||
p.x = @min(self.end().x, p.node.cols() - 1);
|
||||
break :pin p;
|
||||
},
|
||||
.mirrored_reverse => pin: {
|
||||
var p = self.end();
|
||||
p.x = self.start().x;
|
||||
p.x = @min(self.start().x, p.node.cols() - 1);
|
||||
break :pin p;
|
||||
},
|
||||
};
|
||||
@@ -173,12 +173,12 @@ pub fn bottomRight(self: Selection, s: *const Screen) Pin {
|
||||
.reverse => self.start(),
|
||||
.mirrored_forward => pin: {
|
||||
var p = self.end();
|
||||
p.x = self.start().x;
|
||||
p.x = @min(self.start().x, p.node.cols() - 1);
|
||||
break :pin p;
|
||||
},
|
||||
.mirrored_reverse => pin: {
|
||||
var p = self.start();
|
||||
p.x = self.end().x;
|
||||
p.x = @min(self.end().x, p.node.cols() - 1);
|
||||
break :pin p;
|
||||
},
|
||||
};
|
||||
@@ -1055,6 +1055,32 @@ test "Selection: order, standard" {
|
||||
}
|
||||
}
|
||||
|
||||
test "Selection: rectangle corners clamp across mixed-width pages" {
|
||||
const testing = std.testing;
|
||||
var s = try Screen.init(testing.allocator, .{
|
||||
.cols = 4,
|
||||
.rows = 2,
|
||||
.max_scrollback = 0,
|
||||
});
|
||||
defer s.deinit();
|
||||
|
||||
const first = s.pages.pages.first.?;
|
||||
try s.pages.split(.{ .node = first, .y = 1 });
|
||||
const second = first.next.?;
|
||||
second.page().size.cols = 2;
|
||||
|
||||
const sel = Selection.init(
|
||||
.{ .node = first, .x = 3 },
|
||||
.{ .node = second, .x = 1 },
|
||||
true,
|
||||
);
|
||||
try testing.expectEqual(.mirrored_forward, sel.order(&s));
|
||||
|
||||
const bottom_right = sel.bottomRight(&s);
|
||||
_ = bottom_right.rowAndCell();
|
||||
try testing.expect((Pin{ .node = second, .x = 1 }).eql(bottom_right));
|
||||
}
|
||||
|
||||
test "Selection: order, rectangle" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
Reference in New Issue
Block a user