shadow_terminal/
active_terminal.rs1use tracing::Instrument as _;
9
10#[non_exhaustive]
14pub struct ActiveTerminal {
15 pub task_handle: tokio::task::JoinHandle<()>,
17 pub surface_output_rx: tokio::sync::mpsc::Receiver<crate::output::native::Output>,
20 pub pty_input_tx: tokio::sync::mpsc::Sender<crate::pty::BytesFromSTDIN>,
22 pub control_tx: tokio::sync::broadcast::Sender<crate::Protocol>,
25}
26
27impl ActiveTerminal {
28 #[inline]
30 #[must_use]
31 pub fn start(config: crate::shadow_terminal::Config) -> Self {
32 tracing::debug!("Starting shadow terminal...");
33 let (pty_input_tx, pty_input_rx) = tokio::sync::mpsc::channel(1);
34 let (surface_output_tx, surface_output_rx) = tokio::sync::mpsc::channel(1);
35
36 let mut shadow_terminal =
37 crate::shadow_terminal::ShadowTerminal::new(config, surface_output_tx);
38 let control_tx = shadow_terminal.channels.control_tx.clone();
39
40 let current_span = tracing::Span::current();
41 let task_handle = tokio::spawn(async move {
42 shadow_terminal
43 .run(pty_input_rx)
44 .instrument(current_span)
45 .await;
46 });
47 tracing::debug!("Shadow terminal started.");
48
49 Self {
50 task_handle,
51 surface_output_rx,
52 pty_input_tx,
53 control_tx,
54 }
55 }
56
57 #[inline]
63 pub async fn send_input(
64 &self,
65 bytes: crate::pty::BytesFromSTDIN,
66 ) -> Result<(), tokio::sync::mpsc::error::SendError<crate::pty::BytesFromSTDIN>> {
67 self.pty_input_tx.send(bytes).await
68 }
69
70 #[inline]
75 pub fn kill(&self) -> Result<usize, tokio::sync::broadcast::error::SendError<crate::Protocol>> {
76 tracing::debug!("`kill()` called on `ActiveTerminal`");
77 self.control_tx.send(crate::Protocol::End)
78 }
79
80 #[inline]
85 pub fn resize(
86 &self,
87 width: u16,
88 height: u16,
89 ) -> Result<usize, tokio::sync::broadcast::error::SendError<crate::Protocol>> {
90 self.control_tx
91 .send(crate::Protocol::Resize { width, height })
92 }
93
94 #[inline]
99 pub fn scroll_up(
100 &self,
101 ) -> Result<usize, tokio::sync::broadcast::error::SendError<crate::Protocol>> {
102 self.control_tx
103 .send(crate::Protocol::Scroll(crate::Scroll::Up))
104 }
105
106 #[inline]
111 pub fn scroll_down(
112 &self,
113 ) -> Result<usize, tokio::sync::broadcast::error::SendError<crate::Protocol>> {
114 self.control_tx
115 .send(crate::Protocol::Scroll(crate::Scroll::Down))
116 }
117
118 #[inline]
123 pub fn scroll_cancel(
124 &self,
125 ) -> Result<usize, tokio::sync::broadcast::error::SendError<crate::Protocol>> {
126 self.control_tx
127 .send(crate::Protocol::Scroll(crate::Scroll::Cancel))
128 }
129}
130
131impl Drop for ActiveTerminal {
132 #[inline]
133 fn drop(&mut self) {
134 let result = self.kill();
135 if let Err(error) = result {
136 tracing::debug!("`ActiveTerminal.drop()`: {error:?}");
137 }
138 }
139}