summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/pty_writer.rs
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-07-12 20:30:41 +0200
committerGitHub <noreply@github.com>2023-07-12 20:30:41 +0200
commit0825cb65a79c03a473b87bfbab82ffdb2aef9fea (patch)
treeddaf7e817012f8f60941e42b4cf1f326316a1f37 /zellij-server/src/pty_writer.rs
parent385cc1c81b5ee40dff91971ceddce82a4732af82 (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.rs44
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(());
},