fix(messaging): cache hold pane messages by their tab_id if the tab is not ready (#2196)

* fix(messaging): cache hold pane messages by their tab_id if the tab is not ready

* style(fmt): rustfmt
This commit is contained in:
Aram Drevekenin 2023-02-26 15:38:52 +01:00 committed by GitHub
parent c5929d45bf
commit c41dfa33df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 7 deletions

View file

@ -147,6 +147,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
pty.bus.senders.clone(), pty.bus.senders.clone(),
*terminal_id, *terminal_id,
run_command.clone(), run_command.clone(),
None,
) )
.with_context(err_context)?; .with_context(err_context)?;
} }
@ -243,6 +244,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
Some(2), // exit status Some(2), // exit status
run_command, run_command,
None, None,
None,
)) ))
.with_context(err_context)?; .with_context(err_context)?;
} }
@ -313,6 +315,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
Some(2), // exit status Some(2), // exit status
run_command, run_command,
None, None,
None,
)) ))
.with_context(err_context)?; .with_context(err_context)?;
} }
@ -422,6 +425,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
Some(2), // exit status Some(2), // exit status
run_command, run_command,
None, None,
None,
)) ))
.with_context(err_context)?; .with_context(err_context)?;
} }
@ -532,6 +536,7 @@ impl Pty {
exit_status, exit_status,
command, command,
None, None,
None,
)); ));
} else { } else {
let _ = senders.send_to_screen(ScreenInstruction::ClosePane(pane_id, None)); let _ = senders.send_to_screen(ScreenInstruction::ClosePane(pane_id, None));
@ -599,14 +604,14 @@ impl Pty {
// new_pane_pids // new_pane_pids
for run_instruction in extracted_run_instructions { for run_instruction in extracted_run_instructions {
if let Some(new_pane_data) = if let Some(new_pane_data) =
self.apply_run_instruction(run_instruction, default_shell.clone())? self.apply_run_instruction(run_instruction, default_shell.clone(), tab_index)?
{ {
new_pane_pids.push(new_pane_data); new_pane_pids.push(new_pane_data);
} }
} }
for run_instruction in extracted_floating_run_instructions { for run_instruction in extracted_floating_run_instructions {
if let Some(new_pane_data) = if let Some(new_pane_data) =
self.apply_run_instruction(run_instruction, default_shell.clone())? self.apply_run_instruction(run_instruction, default_shell.clone(), tab_index)?
{ {
new_floating_panes_pids.push(new_pane_data); new_floating_panes_pids.push(new_pane_data);
} }
@ -686,6 +691,7 @@ impl Pty {
self.bus.senders.clone(), self.bus.senders.clone(),
terminal_id, terminal_id,
run_command.clone(), run_command.clone(),
Some(tab_index),
) )
.with_context(err_context)?; .with_context(err_context)?;
} else { } else {
@ -706,6 +712,7 @@ impl Pty {
&mut self, &mut self,
run_instruction: Option<Run>, run_instruction: Option<Run>,
default_shell: TerminalAction, default_shell: TerminalAction,
tab_index: usize,
) -> Result<Option<(u32, bool, Option<RunCommand>, Result<i32>)>> { ) -> Result<Option<(u32, bool, Option<RunCommand>, Result<i32>)>> {
// terminal_id, // terminal_id,
// starts_held, // starts_held,
@ -730,6 +737,7 @@ impl Pty {
pane_id, pane_id,
exit_status, exit_status,
command, command,
Some(tab_index),
None, None,
)); ));
} else { } else {
@ -935,6 +943,7 @@ impl Pty {
exit_status, exit_status,
command, command,
None, None,
None,
)); ));
} else { } else {
let _ = let _ =
@ -996,6 +1005,7 @@ fn send_command_not_found_to_screen(
senders: ThreadSenders, senders: ThreadSenders,
terminal_id: u32, terminal_id: u32,
run_command: RunCommand, run_command: RunCommand,
tab_index: Option<usize>,
) -> Result<()> { ) -> Result<()> {
let err_context = || format!("failed to send command_not_fount for terminal {terminal_id}"); let err_context = || format!("failed to send command_not_fount for terminal {terminal_id}");
senders senders
@ -1011,6 +1021,7 @@ fn send_command_not_found_to_screen(
PaneId::Terminal(terminal_id), PaneId::Terminal(terminal_id),
Some(2), Some(2),
run_command.clone(), run_command.clone(),
tab_index,
None, None,
)) ))
.with_context(err_context)?; .with_context(err_context)?;

View file

@ -175,7 +175,13 @@ pub enum ScreenInstruction {
TogglePaneFrames, TogglePaneFrames,
SetSelectable(PaneId, bool, usize), SetSelectable(PaneId, bool, usize),
ClosePane(PaneId, Option<ClientId>), ClosePane(PaneId, Option<ClientId>),
HoldPane(PaneId, Option<i32>, RunCommand, Option<ClientId>), // Option<i32> is the exit status HoldPane(
PaneId,
Option<i32>,
RunCommand,
Option<usize>,
Option<ClientId>,
), // Option<i32> is the exit status, Option<usize> is the tab_index
UpdatePaneName(Vec<u8>, ClientId), UpdatePaneName(Vec<u8>, ClientId),
UndoRenamePane(ClientId), UndoRenamePane(ClientId),
NewTab( NewTab(
@ -1914,10 +1920,10 @@ pub(crate) fn screen_thread_main(
screen.update_tabs()?; screen.update_tabs()?;
screen.unblock_input()?; screen.unblock_input()?;
}, },
ScreenInstruction::HoldPane(id, exit_status, run_command, client_id) => { ScreenInstruction::HoldPane(id, exit_status, run_command, tab_index, client_id) => {
let is_first_run = false; let is_first_run = false;
match client_id { match (client_id, tab_index) {
Some(client_id) => { (Some(client_id), _) => {
active_tab!(screen, client_id, |tab: &mut Tab| tab.hold_pane( active_tab!(screen, client_id, |tab: &mut Tab| tab.hold_pane(
id, id,
exit_status, exit_status,
@ -1925,7 +1931,14 @@ pub(crate) fn screen_thread_main(
run_command run_command
)); ));
}, },
None => { (_, Some(tab_index)) => {
let tab = screen
.tabs
.get_mut(&tab_index)
.context("couldn't find tab with index {tab_index}")?;
tab.hold_pane(id, exit_status, is_first_run, run_command);
},
_ => {
for tab in screen.tabs.values_mut() { for tab in screen.tabs.values_mut() {
if tab.get_all_pane_ids().contains(&id) { if tab.get_all_pane_ids().contains(&id) {
tab.hold_pane(id, exit_status, is_first_run, run_command); tab.hold_pane(id, exit_status, is_first_run, run_command);

View file

@ -89,6 +89,7 @@ type HoldForCommand = Option<RunCommand>;
enum BufferedTabInstruction { enum BufferedTabInstruction {
SetPaneSelectable(PaneId, bool), SetPaneSelectable(PaneId, bool),
HandlePtyBytes(u32, VteBytes), HandlePtyBytes(u32, VteBytes),
HoldPane(PaneId, Option<i32>, bool, RunCommand), // Option<i32> is the exit status, bool is is_first_run
} }
pub(crate) struct Tab { pub(crate) struct Tab {
@ -737,6 +738,14 @@ impl Tab {
BufferedTabInstruction::HandlePtyBytes(terminal_id, bytes) => { BufferedTabInstruction::HandlePtyBytes(terminal_id, bytes) => {
self.handle_pty_bytes(terminal_id, bytes)?; self.handle_pty_bytes(terminal_id, bytes)?;
}, },
BufferedTabInstruction::HoldPane(
terminal_id,
exit_status,
is_first_run,
run_command,
) => {
self.hold_pane(terminal_id, exit_status, is_first_run, run_command);
},
} }
} }
Ok(()) Ok(())
@ -2145,6 +2154,16 @@ impl Tab {
is_first_run: bool, is_first_run: bool,
run_command: RunCommand, run_command: RunCommand,
) { ) {
if self.is_pending {
self.pending_instructions
.push(BufferedTabInstruction::HoldPane(
id,
exit_status,
is_first_run,
run_command,
));
return;
}
if self.floating_panes.panes_contain(&id) { if self.floating_panes.panes_contain(&id) {
self.floating_panes self.floating_panes
.hold_pane(id, exit_status, is_first_run, run_command); .hold_pane(id, exit_status, is_first_run, run_command);