diff options
| author | Satoru Higa <satoruhiga@gmail.com> | 2026-04-03 17:21:34 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-03 10:21:34 +0200 |
| commit | 27a825ebdcae75d00a90396acf861fe1c90a2a6d (patch) | |
| tree | 107a4a6a9f4dbc323eecfbaadbcb0425daa148a5 /src | |
| parent | fix(windows): encode modifiers in raw bytes for non-Char keys (#4967) (diff) | |
| download | sl0ppij-27a825ebdcae75d00a90396acf861fe1c90a2a6d.tar.gz sl0ppij-27a825ebdcae75d00a90396acf861fe1c90a2a6d.tar.xz sl0ppij-27a825ebdcae75d00a90396acf861fe1c90a2a6d.zip | |
fix: position host cursor for CJK IME even when app hides cursor (#4951)
* fix: position host cursor for CJK IME even when app hides cursor
When apps like Claude Code (ink/React library) hide the cursor during
rendering, Zellij's render_cursor() was not sending a CUP sequence to
the host terminal. This caused IME composition candidates to appear at
the wrong position, breaking CJK input in these apps.
Change cursor_coordinates() to return the cursor position unconditionally
(as long as it is within bounds) along with a bool indicating visibility.
render_cursor() now positions the host cursor even when the app has hidden
it, so the IME subsystem can read the correct cursor position.
* add test
* rustfmt
---------
Co-authored-by: Aram Drevekenin <aram@poor.dev>
Diffstat (limited to 'src')
| -rw-r--r-- | src/tests/e2e/remote_runner.rs | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/tests/e2e/remote_runner.rs b/src/tests/e2e/remote_runner.rs index 20f4e0c3..958b8f1e 100644 --- a/src/tests/e2e/remote_runner.rs +++ b/src/tests/e2e/remote_runner.rs @@ -337,8 +337,10 @@ fn read_from_channel( Ok(0) => { let current_snapshot = take_snapshot(&mut terminal_output); let mut last_snapshot = last_snapshot.lock().unwrap(); - *cursor_coordinates.lock().unwrap() = - terminal_output.cursor_coordinates().unwrap_or((0, 0)); + *cursor_coordinates.lock().unwrap() = terminal_output + .cursor_coordinates() + .map(|(x, y, _)| (x, y)) + .unwrap_or((0, 0)); *last_snapshot = current_snapshot; should_sleep = true; }, @@ -348,8 +350,11 @@ fn read_from_channel( } let current_snapshot = take_snapshot(&mut terminal_output); let mut last_snapshot = last_snapshot.lock().unwrap(); - *cursor_coordinates.lock().unwrap() = - terminal_output.grid.cursor_coordinates().unwrap_or((0, 0)); + *cursor_coordinates.lock().unwrap() = terminal_output + .grid + .cursor_coordinates() + .map(|(x, y, _)| (x, y)) + .unwrap_or((0, 0)); *last_snapshot = current_snapshot; should_sleep = true; }, @@ -357,8 +362,10 @@ fn read_from_channel( if e.kind() == std::io::ErrorKind::WouldBlock { let current_snapshot = take_snapshot(&mut terminal_output); let mut last_snapshot = last_snapshot.lock().unwrap(); - *cursor_coordinates.lock().unwrap() = - terminal_output.cursor_coordinates().unwrap_or((0, 0)); + *cursor_coordinates.lock().unwrap() = terminal_output + .cursor_coordinates() + .map(|(x, y, _)| (x, y)) + .unwrap_or((0, 0)); *last_snapshot = current_snapshot; should_sleep = true; } else if retries_left > 0 { @@ -377,7 +384,9 @@ fn read_from_channel( pub fn take_snapshot(terminal_output: &mut TerminalPane) -> String { let output_lines = terminal_output.read_buffer_as_lines(); - let cursor_coordinates = terminal_output.cursor_coordinates(); + let cursor_coordinates = terminal_output + .cursor_coordinates() + .and_then(|(x, y, visible)| if visible { Some((x, y)) } else { None }); let mut snapshot = String::new(); for (line_index, line) in output_lines.iter().enumerate() { for (character_index, terminal_character) in line.iter().enumerate() { |
