fix: reset double-width chars at overlay left edge to prevent border corruption

When a double-width character (e.g. CJK) sits just outside the left
boundary of an overlay (input, tasks, etc.), its second half occupies
the cell where the border should be drawn. The terminal then renders
the wide character over the border, producing the visual artifacts
reported in #3947.

Before clearing the overlay area, check the column immediately left
of the area for each row. If a cell there contains a wide symbol
(width > 1), reset it so the border at area.x renders correctly.

Closes #3947
This commit is contained in:
June Kim 2026-05-09 10:06:54 -07:00
parent 247f925e53
commit 8573087e03

View file

@ -1,6 +1,7 @@
use std::sync::atomic::{AtomicBool, Ordering};
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
use unicode_width::UnicodeWidthStr;
use yazi_adapter::ADAPTOR;
pub static COLLISION: AtomicBool = AtomicBool::new(false);
@ -13,6 +14,18 @@ impl Widget for Clear {
where
Self: Sized,
{
// Reset any double-width characters just outside the left edge whose
// second half would overlap into the cleared area, which would otherwise
// obscure the border drawn at area.x.
if area.x > 0 {
let left = area.x - 1;
for y in area.top()..area.bottom() {
if buf[(left, y)].symbol().width() > 1 {
buf[(left, y)].reset();
}
}
}
ratatui::widgets::Clear.render(area, buf);
let Some(r) = ADAPTOR.get().shown_load().and_then(|r| overlap(area, r)) else {