fix(hit): move cursor to the logical end of mixed-bidi line

This commit is contained in:
Hojjat 2026-03-26 15:47:54 -06:00 committed by Jeremy Soller
parent aa2c305039
commit e5926aec74

View file

@ -1109,11 +1109,13 @@ impl Buffer {
new_cursor.affinity = new_cursor_affinity; new_cursor.affinity = new_cursor_affinity;
} }
None => { None => {
if let Some(glyph) = run.glyphs.last() { // Click was past all glyphs in this visual run.
// Position at end of line // Use the maximum glyph.end across all glyphs.
new_cursor.index = glyph.end; // this is the logical end of this visual line's byte coverage,
new_cursor.affinity = Affinity::Before; // correct for LTR, RTL, mixed-BiDi, and wrapped paragraphs.
} let run_end = run.glyphs.iter().map(|g| g.end).max().unwrap_or(0);
new_cursor.index = run_end;
new_cursor.affinity = Affinity::Before;
} }
} }
@ -1121,10 +1123,10 @@ impl Buffer {
break; break;
} else if runs.peek().is_none() && y > run.line_y { } else if runs.peek().is_none() && y > run.line_y {
let mut new_cursor = Cursor::new(run.line_i, 0); // Click below the last run: place cursor at the logical end of the
if let Some(glyph) = run.glyphs.last() { // line, regardless of paragraph direction or BiDi mixing.
new_cursor = run.cursor_from_glyph_right(glyph); let new_cursor =
} Cursor::new_with_affinity(run.line_i, run.text.len(), Affinity::Before);
new_cursor_opt = Some(new_cursor); new_cursor_opt = Some(new_cursor);
} }
} }