diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-07-12 20:30:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-12 20:30:41 +0200 |
commit | 0825cb65a79c03a473b87bfbab82ffdb2aef9fea (patch) | |
tree | ddaf7e817012f8f60941e42b4cf1f326316a1f37 /zellij-server/src/pty_writer.rs | |
parent | 385cc1c81b5ee40dff91971ceddce82a4732af82 (diff) |
fix(rendering): occasional glitches while resizing (#2621)
Diffstat (limited to 'zellij-server/src/pty_writer.rs')
-rw-r--r-- | zellij-server/src/pty_writer.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/zellij-server/src/pty_writer.rs b/zellij-server/src/pty_writer.rs index 9c3b6d49a..017fed39a 100644 --- a/zellij-server/src/pty_writer.rs +++ b/zellij-server/src/pty_writer.rs @@ -2,9 +2,16 @@ use zellij_utils::errors::{prelude::*, ContextType, PtyWriteContext}; use crate::thread_bus::Bus; +// we separate these instruction to a different thread because some programs get deadlocked if +// you write into their STDIN while reading from their STDOUT (I'm looking at you, vim) +// while the same has not been observed to happen with resizes, it could conceivably happen and we have this +// here anyway, so #[derive(Debug, Clone, Eq, PartialEq)] pub enum PtyWriteInstruction { Write(Vec<u8>, u32), + ResizePty(u32, u16, u16, Option<u16>, Option<u16>), // terminal_id, columns, rows, pixel width, pixel height + StartCachingResizes, + ApplyCachedResizes, Exit, } @@ -12,6 +19,9 @@ impl From<&PtyWriteInstruction> for PtyWriteContext { fn from(tty_write_instruction: &PtyWriteInstruction) -> Self { match *tty_write_instruction { PtyWriteInstruction::Write(..) => PtyWriteContext::Write, + PtyWriteInstruction::ResizePty(..) => PtyWriteContext::ResizePty, + PtyWriteInstruction::ApplyCachedResizes => PtyWriteContext::ApplyCachedResizes, + PtyWriteInstruction::StartCachingResizes => PtyWriteContext::StartCachingResizes, PtyWriteInstruction::Exit => PtyWriteContext::Exit, } } @@ -23,7 +33,7 @@ pub(crate) fn pty_writer_main(bus: Bus<PtyWriteInstruction>) -> Result<()> { loop { let (event, mut err_ctx) = bus.recv().with_context(err_context)?; err_ctx.add_call(ContextType::PtyWrite((&event).into())); - let os_input = bus + let mut os_input = bus .os_input .clone() .context("no OS input API found") @@ -39,6 +49,38 @@ pub(crate) fn pty_writer_main(bus: Bus<PtyWriteInstruction>) -> Result<()> { .with_context(err_context) .non_fatal(); }, + PtyWriteInstruction::ResizePty( + terminal_id, + columns, + rows, + width_in_pixels, + height_in_pixels, + ) => { + os_input + .set_terminal_size_using_terminal_id( + terminal_id, + columns, + rows, + width_in_pixels, + height_in_pixels, + ) + .with_context(err_context) + .non_fatal(); + }, + PtyWriteInstruction::StartCachingResizes => { + // we do this because there are some logic traps inside the screen/tab/layout code + // the cause multiple resizes to be sent to the pty - while the last one is always + // the correct one, many programs and shells debounce those (I guess due to the + // trauma of dealing with GUI resizes of the controlling terminal window), and this + // then causes glitches and missing redraws + // so we do this to play nice and always only send the last resize instruction to + // each pane + // the logic for this happens in the main Screen event loop + os_input.cache_resizes(); + }, + PtyWriteInstruction::ApplyCachedResizes => { + os_input.apply_cached_resizes(); + }, PtyWriteInstruction::Exit => { return Ok(()); }, |