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:
parent
86a0f0939c
commit
ba7add140e
@ -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> {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user