1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 13:52:55 +03:00

Attach gui window invalidation to pty output event

I'm not convinced that this is 100% good, but @fanzeyi reported
some latency when using tmux to mirror two sessions.  The session
that was accepting interactive input responded quickly, but the
mirroring session was laggy.

This change connects the mux pane output event to window invalidation,
which should cause repaints to happen more often.

I couldn't reproduce the scenario above on my M1 mac, but that may
just be because M1 has dark magicks.
This commit is contained in:
Wez Furlong 2021-03-17 20:20:08 -07:00
parent 86a0f0939c
commit ba7add140e
2 changed files with 87 additions and 3 deletions

View File

@ -543,6 +543,20 @@ impl Tab {
} }
} }
pub fn contains_pane(&self, pane: PaneId) -> bool {
fn contains(tree: &Tree, pane: PaneId) -> bool {
match tree {
Tree::Empty => false,
Tree::Node { left, right, .. } => contains(left, pane) || contains(right, pane),
Tree::Leaf(p) => p.pane_id() == pane,
}
}
match &*self.pane.borrow() {
Some(root) => contains(root, pane),
None => false,
}
}
/// Walks the pane tree to produce the topologically ordered flattened /// Walks the pane tree to produce the topologically ordered flattened
/// list of PositionedPane instances along with their positioning information. /// list of PositionedPane instances along with their positioning information.
pub fn iter_panes(&self) -> Vec<PositionedPane> { pub fn iter_panes(&self) -> Vec<PositionedPane> {

View File

@ -27,15 +27,15 @@ use mux::pane::{Pane, PaneId};
use mux::renderable::RenderableDimensions; use mux::renderable::RenderableDimensions;
use mux::tab::{PositionedPane, PositionedSplit, SplitDirection, TabId}; use mux::tab::{PositionedPane, PositionedSplit, SplitDirection, TabId};
use mux::window::WindowId as MuxWindowId; use mux::window::WindowId as MuxWindowId;
use mux::Mux; use mux::{Mux, MuxNotification};
use portable_pty::PtySize; use portable_pty::PtySize;
use std::any::Any; use std::any::Any;
use std::cell::{RefCell, RefMut}; use std::cell::{RefCell, RefMut};
use std::collections::HashMap; use std::collections::HashMap;
use std::ops::Add; use std::ops::Add;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex; use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use termwiz::hyperlink::Hyperlink; use termwiz::hyperlink::Hyperlink;
use termwiz::image::ImageData; use termwiz::image::ImageData;
@ -585,6 +585,7 @@ impl TermWindow {
window window
.apply(move |tw, _ops| { .apply(move |tw, _ops| {
if let Some(term_window) = tw.downcast_mut::<TermWindow>() { if let Some(term_window) = tw.downcast_mut::<TermWindow>() {
term_window.subscribe_to_pane_updates();
term_window.emit_status_event(); term_window.emit_status_event();
} }
Ok(()) Ok(())
@ -595,6 +596,75 @@ impl TermWindow {
} }
} }
fn mux_pane_output_event(&mut self, pane_id: PaneId) {
if let Some(pane) = self.get_active_pane_or_overlay() {
if pane.pane_id() == pane_id {
let mux = Mux::get().expect("mux started and running on main thread");
if let Some(mut mux_window) = mux.get_window_mut(self.mux_window_id) {
mux_window.check_and_reset_invalidated();
}
if let Some(ref win) = self.window {
win.invalidate();
}
}
}
}
fn mux_pane_output_event_callback(
n: MuxNotification,
window: &Window,
mux_window_id: MuxWindowId,
dead: &Arc<AtomicBool>,
) -> bool {
if dead.load(Ordering::Relaxed) {
// Subscription cancelled asynchronously
return false;
}
if let MuxNotification::PaneOutput(pane_id) = n {
let mut pane_in_window = false;
let mux = Mux::get().expect("mux is calling us");
if let Some(mux_window) = mux.get_window(mux_window_id) {
for tab in mux_window.iter() {
if tab.contains_pane(pane_id) {
pane_in_window = true;
break;
}
}
} else {
// Something inconsistent: cancel subscription
return false;
}
if pane_in_window {
let dead = Arc::clone(dead);
window.apply(move |myself, _window| {
if let Some(myself) = myself.downcast_mut::<Self>() {
myself.mux_pane_output_event(pane_id);
} else {
// Something inconsistent: cancel subscription
dead.store(true, Ordering::Relaxed);
}
Ok(())
});
}
}
true
}
fn subscribe_to_pane_updates(&self) {
let window = self.window.clone().expect("window to be valid on startup");
let mux_window_id = self.mux_window_id;
let mux = Mux::get().expect("mux started and running on main thread");
let dead = Arc::new(AtomicBool::new(false));
mux.subscribe(move |n| {
Self::mux_pane_output_event_callback(n, &window, mux_window_id, &dead)
});
}
fn emit_status_event(&mut self) { fn emit_status_event(&mut self) {
self.emit_window_event("update-right-status"); self.emit_window_event("update-right-status");
} }