mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 13:16:39 +03:00
mux: avoid WindowTitleChanged cycle
double-tapping the window title could lead to a cycle between client and server. The cycle is broken here by having the client defer advising the server of a title change, and sending the now-current title rather than the title embedded in the notification from the mux layer. refs: #1598 refs: #522
This commit is contained in:
parent
c3472cc969
commit
25be7fb9b1
@ -339,6 +339,7 @@ macro_rules! pdu {
|
||||
Pdu::$name(s) => {
|
||||
let (data, is_compressed) = serialize(s)?;
|
||||
let encoded_size = encode_raw($vers, serial, &data, is_compressed, w)?;
|
||||
log::debug!("encode {} size={encoded_size}", stringify!($name));
|
||||
metrics::histogram!("pdu.size", encoded_size as f64, "pdu" => stringify!($name));
|
||||
metrics::histogram!("pdu.size.rate", encoded_size as f64, "pdu" => stringify!($name));
|
||||
Ok(())
|
||||
@ -354,6 +355,7 @@ macro_rules! pdu {
|
||||
Pdu::$name(s) => {
|
||||
let (data, is_compressed) = serialize(s)?;
|
||||
let encoded_size = encode_raw_async($vers, serial, &data, is_compressed, w).await?;
|
||||
log::debug!("encode_async {} size={encoded_size}", stringify!($name));
|
||||
metrics::histogram!("pdu.size", encoded_size as f64, "pdu" => stringify!($name));
|
||||
metrics::histogram!("pdu.size.rate", encoded_size as f64, "pdu" => stringify!($name));
|
||||
Ok(())
|
||||
@ -362,6 +364,17 @@ macro_rules! pdu {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pdu_name(&self) -> &'static str {
|
||||
match self {
|
||||
Pdu::Invalid{..} => "Invalid",
|
||||
$(
|
||||
Pdu::$name(_) => {
|
||||
stringify!($name)
|
||||
}
|
||||
,)*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode<R: std::io::Read>(r: R) -> Result<DecodedPdu, Error> {
|
||||
let decoded = decode_raw(r).context("decoding a PDU")?;
|
||||
match decoded.ident {
|
||||
|
@ -391,7 +391,11 @@ async fn client_thread_async(
|
||||
Ok(ReaderMessage::Readable) => {
|
||||
match Pdu::decode_async(&mut stream, Some(next_serial)).await {
|
||||
Ok(decoded) => {
|
||||
log::trace!("decoded serial {}", decoded.serial);
|
||||
log::debug!(
|
||||
"decoded serial {} {}",
|
||||
decoded.serial,
|
||||
decoded.pdu.pdu_name()
|
||||
);
|
||||
if decoded.serial == 0 {
|
||||
process_unilateral(local_domain_id, decoded)
|
||||
.context("processing unilateral PDU from server")
|
||||
|
@ -361,17 +361,37 @@ fn mux_notify_client_domain(local_domain_id: DomainId, notif: MuxNotification) -
|
||||
}
|
||||
}
|
||||
}
|
||||
MuxNotification::WindowTitleChanged { window_id, title } => {
|
||||
MuxNotification::WindowTitleChanged {
|
||||
window_id,
|
||||
title: _,
|
||||
} => {
|
||||
if let Some(remote_window_id) = client_domain.local_to_remote_window_id(window_id) {
|
||||
if let Some(inner) = client_domain.inner() {
|
||||
promise::spawn::spawn(async move {
|
||||
inner
|
||||
.client
|
||||
.set_window_title(codec::WindowTitleChanged {
|
||||
window_id: remote_window_id,
|
||||
title,
|
||||
})
|
||||
.await
|
||||
promise::spawn::spawn_into_main_thread(async move {
|
||||
// De-bounce the title propagation.
|
||||
// There is a bit of a race condition with these async
|
||||
// updates that can trigger a cycle of WindowTitleChanged
|
||||
// PDUs being exchanged between client and server if the
|
||||
// title is changed twice in quick succession.
|
||||
// To avoid that, here on the client, we wait a second
|
||||
// and then report the now-current name of the window, rather
|
||||
// than propagating the title encoded in the MuxNotification.
|
||||
smol::Timer::after(std::time::Duration::from_secs(1)).await;
|
||||
if let Some(mux) = Mux::try_get() {
|
||||
let title = mux
|
||||
.get_window(window_id)
|
||||
.map(|win| win.get_title().to_string());
|
||||
if let Some(title) = title {
|
||||
inner
|
||||
.client
|
||||
.set_window_title(codec::WindowTitleChanged {
|
||||
window_id: remote_window_id,
|
||||
title,
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
anyhow::Result::<()>::Ok(())
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user