fix cursor after suspend (#2690)
This was supposed to be fixed by #2569, but I think the actual fix got lost in the refactoring. Intended behavior: pressing ^Z moves the cursor below the viewport before suspending.
This commit is contained in:
@@ -7,6 +7,8 @@ use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
#[cfg(unix)]
|
||||
use std::sync::atomic::AtomicU8;
|
||||
#[cfg(unix)]
|
||||
use std::sync::atomic::AtomicU16;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
@@ -168,6 +170,8 @@ pub struct Tui {
|
||||
alt_saved_viewport: Option<ratatui::layout::Rect>,
|
||||
#[cfg(unix)]
|
||||
resume_pending: Arc<AtomicU8>, // Stores a ResumeAction
|
||||
#[cfg(unix)]
|
||||
suspend_cursor_y: Arc<AtomicU16>, // Bottom line of inline viewport
|
||||
// True when overlay alt-screen UI is active
|
||||
alt_screen_active: Arc<AtomicBool>,
|
||||
}
|
||||
@@ -274,6 +278,8 @@ impl Tui {
|
||||
alt_saved_viewport: None,
|
||||
#[cfg(unix)]
|
||||
resume_pending: Arc::new(AtomicU8::new(0)),
|
||||
#[cfg(unix)]
|
||||
suspend_cursor_y: Arc::new(AtomicU16::new(0)),
|
||||
alt_screen_active: Arc::new(AtomicBool::new(false)),
|
||||
}
|
||||
}
|
||||
@@ -292,6 +298,8 @@ impl Tui {
|
||||
let resume_pending = self.resume_pending.clone();
|
||||
#[cfg(unix)]
|
||||
let alt_screen_active = self.alt_screen_active.clone();
|
||||
#[cfg(unix)]
|
||||
let suspend_cursor_y = self.suspend_cursor_y.clone();
|
||||
let event_stream = async_stream::stream! {
|
||||
loop {
|
||||
select! {
|
||||
@@ -340,6 +348,11 @@ impl Tui {
|
||||
} else {
|
||||
resume_pending.store(ResumeAction::RealignInline as u8, Ordering::Relaxed);
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let y = suspend_cursor_y.load(Ordering::Relaxed);
|
||||
let _ = execute!(stdout(), MoveTo(0, y));
|
||||
}
|
||||
let _ = execute!(stdout(), crossterm::cursor::Show);
|
||||
let _ = Tui::suspend();
|
||||
yield TuiEvent::Draw;
|
||||
@@ -396,7 +409,7 @@ impl Tui {
|
||||
)))
|
||||
}
|
||||
ResumeAction::RestoreAlt => {
|
||||
if let Ok((_x, y)) = crossterm::cursor::position()
|
||||
if let Ok(ratatui::layout::Position { y, .. }) = self.terminal.get_cursor_position()
|
||||
&& let Some(saved) = self.alt_saved_viewport.as_mut()
|
||||
{
|
||||
saved.y = y;
|
||||
@@ -532,6 +545,19 @@ impl Tui {
|
||||
);
|
||||
self.pending_history_lines.clear();
|
||||
}
|
||||
// Update the y position for suspending so Ctrl-Z can place the cursor correctly.
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let inline_area_bottom = if self.alt_screen_active.load(Ordering::Relaxed) {
|
||||
self.alt_saved_viewport
|
||||
.map(|r| r.bottom().saturating_sub(1))
|
||||
.unwrap_or_else(|| area.bottom().saturating_sub(1))
|
||||
} else {
|
||||
area.bottom().saturating_sub(1)
|
||||
};
|
||||
self.suspend_cursor_y
|
||||
.store(inline_area_bottom, Ordering::Relaxed);
|
||||
}
|
||||
terminal.draw(|frame| {
|
||||
draw_fn(frame);
|
||||
})?;
|
||||
|
||||
Reference in New Issue
Block a user