fix(startup): recover from race condition that causes Zellij to start in the wrong size (#3218)
* fix(startup): recover from Zellij starting up in the wrong size * style(fmt): rustfmt * fix tests
This commit is contained in:
parent
b24386e6b1
commit
86e91ae137
5 changed files with 24 additions and 2 deletions
|
|
@ -51,6 +51,7 @@ pub(crate) enum ClientInstruction {
|
||||||
SetSynchronizedOutput(Option<SyncOutput>),
|
SetSynchronizedOutput(Option<SyncOutput>),
|
||||||
UnblockCliPipeInput(String), // String -> pipe name
|
UnblockCliPipeInput(String), // String -> pipe name
|
||||||
CliPipeOutput(String, String), // String -> pipe name, String -> output
|
CliPipeOutput(String, String), // String -> pipe name, String -> output
|
||||||
|
QueryTerminalSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ServerToClientMsg> for ClientInstruction {
|
impl From<ServerToClientMsg> for ClientInstruction {
|
||||||
|
|
@ -75,6 +76,7 @@ impl From<ServerToClientMsg> for ClientInstruction {
|
||||||
ServerToClientMsg::CliPipeOutput(pipe_name, output) => {
|
ServerToClientMsg::CliPipeOutput(pipe_name, output) => {
|
||||||
ClientInstruction::CliPipeOutput(pipe_name, output)
|
ClientInstruction::CliPipeOutput(pipe_name, output)
|
||||||
},
|
},
|
||||||
|
ServerToClientMsg::QueryTerminalSize => ClientInstruction::QueryTerminalSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +99,7 @@ impl From<&ClientInstruction> for ClientContext {
|
||||||
ClientInstruction::SetSynchronizedOutput(..) => ClientContext::SetSynchronisedOutput,
|
ClientInstruction::SetSynchronizedOutput(..) => ClientContext::SetSynchronisedOutput,
|
||||||
ClientInstruction::UnblockCliPipeInput(..) => ClientContext::UnblockCliPipeInput,
|
ClientInstruction::UnblockCliPipeInput(..) => ClientContext::UnblockCliPipeInput,
|
||||||
ClientInstruction::CliPipeOutput(..) => ClientContext::CliPipeOutput,
|
ClientInstruction::CliPipeOutput(..) => ClientContext::CliPipeOutput,
|
||||||
|
ClientInstruction::QueryTerminalSize => ClientContext::QueryTerminalSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -499,6 +502,11 @@ pub fn start_client(
|
||||||
ClientInstruction::SetSynchronizedOutput(enabled) => {
|
ClientInstruction::SetSynchronizedOutput(enabled) => {
|
||||||
synchronised_output = enabled;
|
synchronised_output = enabled;
|
||||||
},
|
},
|
||||||
|
ClientInstruction::QueryTerminalSize => {
|
||||||
|
os_input.send_to_server(ClientToServerMsg::TerminalResize(
|
||||||
|
os_input.get_terminal_size_using_fd(0),
|
||||||
|
));
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3000,6 +3000,18 @@ pub(crate) fn screen_thread_main(
|
||||||
|
|
||||||
screen.unblock_input()?;
|
screen.unblock_input()?;
|
||||||
screen.render(None)?;
|
screen.render(None)?;
|
||||||
|
// we do this here in order to recover from a race condition on app start
|
||||||
|
// that sometimes causes Zellij to think the terminal window is a different size
|
||||||
|
// than it actually is - here, we query the client for its terminal size after
|
||||||
|
// we've finished the setup and handle it as we handle a normal resize,
|
||||||
|
// while this can affect other instances of a layout being applied, the query is
|
||||||
|
// very short and cheap and shouldn't cause any trouble
|
||||||
|
if let Some(os_input) = &mut screen.bus.os_input {
|
||||||
|
for client_id in screen.connected_clients.borrow().iter() {
|
||||||
|
let _ = os_input
|
||||||
|
.send_to_client(*client_id, ServerToClientMsg::QueryTerminalSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ScreenInstruction::GoToTab(tab_index, client_id) => {
|
ScreenInstruction::GoToTab(tab_index, client_id) => {
|
||||||
let client_id_to_switch = if client_id.is_none() {
|
let client_id_to_switch = if client_id.is_none() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 1711
|
assertion_line: 2465
|
||||||
expression: "format!(\"{:?}\", *\n mock_screen.os_input.server_to_client_messages.lock().unwrap())"
|
expression: "format!(\"{:?}\", *\n mock_screen.os_input.server_to_client_messages.lock().unwrap())"
|
||||||
---
|
---
|
||||||
{1: [SwitchToMode(Locked)]}
|
{1: [QueryTerminalSize, SwitchToMode(Locked)]}
|
||||||
|
|
|
||||||
|
|
@ -424,6 +424,7 @@ pub enum ClientContext {
|
||||||
SetSynchronisedOutput,
|
SetSynchronisedOutput,
|
||||||
UnblockCliPipeInput,
|
UnblockCliPipeInput,
|
||||||
CliPipeOutput,
|
CliPipeOutput,
|
||||||
|
QueryTerminalSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stack call representations corresponding to the different types of [`ServerInstruction`]s.
|
/// Stack call representations corresponding to the different types of [`ServerInstruction`]s.
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ pub enum ServerToClientMsg {
|
||||||
SwitchSession(ConnectToSession),
|
SwitchSession(ConnectToSession),
|
||||||
UnblockCliPipeInput(String), // String -> pipe name
|
UnblockCliPipeInput(String), // String -> pipe name
|
||||||
CliPipeOutput(String, String), // String -> pipe name, String -> Output
|
CliPipeOutput(String, String), // String -> pipe name, String -> Output
|
||||||
|
QueryTerminalSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue