Merge #390: Keep text selection highlight inside the box at the end of the text (@Silvertree2010)

This commit is contained in:
bflatastic
2026-10-15 15:08:55 +07:00
2 changed files with 23 additions and 1 deletions
+2 -1
View File
@@ -1213,7 +1213,8 @@ impl TextLayout {
}
let (x0, _) = self.caret(a.max(line.char_start));
let x1 = if b >= line.char_end {
self.line_end_x(line) + if line.para_end && b > line.char_end.saturating_sub(1) { 4.0 } else { 0.0 }
// The last line has no paragraph break to show, so it ends at its glyphs.
self.line_end_x(line) + if line.para_end && li + 1 < self.lines.len() && b > line.char_end.saturating_sub(1) { 4.0 } else { 0.0 }
} else {
self.caret(b).0
};
+21
View File
@@ -416,3 +416,24 @@ fn arrows_move_visually_through_right_to_left_runs() {
// Plain left-to-right lines step by char (the caller's default).
assert!(layout(&TextData::new("plain"), None, None).visual_step(1, true).is_none());
}
#[test]
fn selection_through_text_end_stays_inside_auto_width_box() {
if !have_fonts() {
return;
}
for size in [12.0, 24.0, 96.0] {
let mut t = TextData::new("Hello world");
t.style.font_size = size;
let l = layout(&t, None, None);
let n = "Hello world".chars().count();
let right = l.selection_rects(0, n).last().map_or(f64::NAN, |r| r.x1);
assert!(right <= l.width.ceil(), "size {size}: right {right} > ceil(width) {}", l.width.ceil());
}
// A selected paragraph break still shows past the end of its line.
let t = TextData::new("Hello\nworld");
let l = layout(&t, None, None);
let r = l.selection_rects(0, 6);
let first = r.first().map_or(f64::NAN, |r| r.x1);
assert!(first > l.caret(5).0 + 1.0, "{first}");
}