Skip to main content

Daemon

Struct Daemon 

struct Daemon<'a> {
    hosts: Vec<String>,
    username: Option<String>,
    port: Option<u16>,
    config: &'a DaemonConfig,
    clusters: &'a [Cluster],
    control_mode_state: ControlModeState,
    debug: bool,
}
Expand description

The daemon is responsible to launch a client for each host, positioning the client windows, forwarding input records to all clients and handling control mode.

Fields§

§hosts: Vec<String>

A list of hostnames to connect to.

§username: Option<String>

A username to use to connect to all clients.

If it is empty the clients will use the SSH config to find an approriate username.

§port: Option<u16>

Optional port used for all SSH connections.

§config: &'a DaemonConfig

The DaemonConfig that controls how the daemon console window looks like.

§clusters: &'a [Cluster]

List of available cluster tags

§control_mode_state: ControlModeState

The current control mode state. The submenu’s selected client is carried inline on ControlModeState::EnableDisableSubmenu - tying its lifetime to the variant guarantees no stale highlight survives after Esc.

§debug: bool

If debug mode is enabled on the daemon it will also be enabled on all clients.

Implementations§

§

impl<'a> Daemon<'a>

async fn launch<W: WindowsApi + Clone + 'static>(self, windows_api: &W)

Launches all client windows and blocks on the main run loop.

Sets up the daemon console by disabling processed input mode and applying the configured colors and dimensions. Once all client windows have successfully started the daemon console window is moved to the foreground and receives focus.

async fn run<W: WindowsApi + Clone + 'static>( &mut self, windows_api: &W, clients: &mut Arc<Mutex<Clients>>, workspace_area: &WorkspaceArea, )

The main run loop of the daemon subcommand.

Opens a multi-producer, multi-consumer broadcasting channel used to send the read input records in parallel to the name pipe servers the clients are listening on. Spawns a background thread that waits for all clients to terminate and then stops the current process. Spawns a background thread that ensures the z-order of all client windows is in sync with the daemon window. I.e. if the daemon window is focussed, all clients should be moved to the foreground.

The main loop consists of waiting for input records to read from the keyboard, sending them to all clients and handling control mode.

§Arguments
  • windows_api - The Windows API implementation to use
  • clients - A thread safe mapping from the number a client console window was launched at in relation to the other client windows and the clients console window handle.
  • workspace_area - The available workspace area on the primary monitor minus the space occupied by the daemon console window.

fn launch_named_pipe_servers( &self, sender: &Sender<[u8; 13]>, clients: Arc<Mutex<Clients>>, ) -> Vec<JoinHandle<()>>

Launch a named pipe server for each host in a dedicated thread.

§Arguments
  • sender - The sender end of the broadcast channel through which the main thread will send the input records that are to be forwarded to the clients.
§Returns

Returns a list of [JoinHandle]s, one handle for each thread.

fn launch_named_pipe_server( &self, servers: &mut Vec<JoinHandle<()>>, sender: &Sender<[u8; 13]>, clients: Arc<Mutex<Clients>>, )

Launch a named pipe server in a dedicated thread.

§Arguments
  • servers - A list of [JoinHandle]s to which the join handle for the new thread will be added.
  • sender - The sender end of the broadcast channel through which the main thread will send the input records that are to be forwarded to the clients.

async fn handle_input_record<W: WindowsApi + Clone + 'static>( &mut self, windows_api: &W, sender: &Sender<[u8; 13]>, input_record: INPUT_RECORD_0, clients: &mut Arc<Mutex<Clients>>, workspace_area: &WorkspaceArea, servers: &mut Arc<Mutex<Vec<JoinHandle<()>>>>, )

Handle the given input record.

Input records are being forwarded to all clients. If a sequence of input records matches the control mode key combination, forwarding is temporarily interrupted, until control mode is exited.

§Arguments
  • sender - The sender end of the broadcast channel through which we will send the input records that are being forwarded to the clients by the named pipe servers (servers).
  • input_record - The [INPUT_RECORD_0].KeyEvent read from the console input buffer.
  • clients - A thread safe mapping from the number a client console window was launched at in relation to the other client windows and the clients console window handle. The mapping will be extended if additional clients are being added through control mode [c]reate window(s).
  • workspace_area - The available workspace area on the primary monitor minus the space occupied by the daemon console window.
  • servers - A thread safe list of [JoinHandle]s, one handle for each named pipe server background thread. The list will be extended if additional clients are being added through control mode [c]reate window(s).

fn control_mode_is_active<W: WindowsApi>( &mut self, windows_api: &W, clients: &Mutex<Clients>, input_record: INPUT_RECORD_0, ) -> bool

Updates self.control_mode_state for the given input record and reports whether control mode owned the keystroke.

Entering control mode requires this function to be called twice because the activating chord Ctrl + A produces two input records (the modifier press and the A key). Once active, every subsequent key - including the Esc that exits control mode - is reported as consumed so callers do not forward it to clients.

§Arguments
  • windows_api - The Windows API implementation to use.
  • clients - Currently tracked clients. Used to clear the submenu highlight on the previously-selected client when Esc exits the enable/disable submenu.
  • input_record - A KeyEvent input record.
§Returns

Whether the input record was consumed by control mode. Returns true while control mode is active (including the Esc keystroke that exits it), so callers must not forward such records to clients.

fn quit_control_mode<W: WindowsApi>(&mut self, windows_api: &W)

Prints the default daemon instructions to the daemon console.

§Arguments
  • windows_api - Windows API used to clear and redraw the daemon console.

fn print_instructions<W: WindowsApi>(&self, windows_api: &W)

Clears the console screen and prints the default daemon instructions.

fn rearrange_client_windows<W: WindowsApi>( &self, windows_api: &W, clients: &mut Clients, workspace_area: &WorkspaceArea, )

Iterates over all still open client windows and re-arranges them on the screen based on the aspect ration adjustment daemon configuration.

Client windows will be re-sized and re-positioned.

§Arguments
  • windows_api - The Windows API implementation to use
  • clients - A thread safe mapping from the number a client console window was launched at in relation to the other client windows and the clients console window handle. The number is relevant to determine the position on the screen the window should be placed at.
  • workspace_area - The available workspace area on the primary monitor minus the space occupied by the daemon console window.

fn handle_enable_disable_submenu_key<W: WindowsApi>( &mut self, windows_api: &W, clients: &Mutex<Clients>, workspace_area: &WorkspaceArea, key_event: KEY_EVENT_RECORD, )

Dispatches a key press received while the daemon is in the ControlModeState::EnableDisableSubmenu state. [e]/[d]/[t] act on the currently selected client; Navigate moves the selection and redraws the prompt. The submenu is left via ESC, which is handled by the caller.

§Arguments
  • windows_api - Windows API implementation used by the render helper when redrawing after navigation.
  • clients - Shared client collection. Empty lists are a no-op for every action.
  • key_event - The key-down [KEY_EVENT_RECORD] dispatched from handle_input_record.

fn render_enable_disable_submenu<W: WindowsApi>(&self, windows_api: &W)

Redraws the enable/disable submenu prompt.

§Arguments
  • windows_api - Windows API used to clear the console.

fn apply_submenu_highlight( &self, clients: &Clients, prev_pid: Option<u32>, next_pid: Option<u32>, )

Move the per-client highlight from prev_pid to next_pid.

PID-based clearing tolerates the background monitor’s retain shifting indices while the submenu is open.

§Arguments
  • clients - Currently tracked clients.
  • prev_pid - PID currently highlighted, or None if no client is highlighted.
  • next_pid - PID to highlight now, or None to clear the highlight entirely.

fn update_client_states<F>(&self, clients: &Mutex<Clients>, f: F)
where F: FnOnce(&Clients) -> Vec<(u32, ClientState)>,

Apply a batch of ClientState updates while holding the Clients mutex exactly once.

f is called with the locked guard and returns the list of (pid, new_state) updates to apply. The guard is held across both the build and the apply phase so callers see a stable snapshot.

§Arguments
  • clients - Shared client collection.
  • f - Builds the updates from a &Clients snapshot.

fn set_client_state(&self, clients: &Clients, pid: u32, state: ClientState)

Push a new ClientState for the client identified by pid.

Looks the client up by PID and broadcasts the new state through its [watch::Sender]. The pipe-server task subscribed to that sender observes the change and forwards a crate::protocol::TAG_STATE_CHANGE frame to the client over the named pipe. Called from the control-mode handlers for [t]oggle enabled and e[n]able all via Daemon::update_client_states.

§Arguments
  • clients - The daemon’s tracked clients.
  • pid - Process id of the client whose state should change.
  • state - The new state to broadcast.

fn arrange_daemon_console<W: WindowsApi>( &self, windows_api: &W, workspace_area: &WorkspaceArea, )

Re-sizes and re-positions the daemon console window on the screen based on the daemon height configuration.

§Arguments
  • windows_api - The Windows API implementation to use
  • workspace_area - The available workspace area on the primary monitor minus the space occupied by the daemon console window.

Auto Trait Implementations§

§

impl<'a> Freeze for Daemon<'a>

§

impl<'a> RefUnwindSafe for Daemon<'a>

§

impl<'a> Send for Daemon<'a>

§

impl<'a> Sync for Daemon<'a>

§

impl<'a> Unpin for Daemon<'a>

§

impl<'a> UnsafeUnpin for Daemon<'a>

§

impl<'a> UnwindSafe for Daemon<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.