pub struct Tab { /* private fields */ }Expand description
A single terminal tab with its own state (supports split panes).
§Mutex Strategy
terminal is behind a tokio::sync::RwLock because TerminalManager is
shared across async tasks (PTY reader, input sender, resize handler) and the
sync winit event loop. See the global policy in crate (lib.rs) and the
locking table on the terminal field below.
pane_manager is owned directly (not behind a Mutex) because it is only ever
accessed from the sync winit event loop on the main thread.
For the complete threading model see docs/MUTEX_PATTERNS.md.
Implementations§
Source§impl Tab
impl Tab
Sourcepub fn new(
id: TabId,
tab_number: usize,
config: &Config,
runtime: Arc<Runtime>,
working_directory: Option<String>,
grid_size: Option<(usize, usize)>,
) -> Result<Self>
pub fn new( id: TabId, tab_number: usize, config: &Config, runtime: Arc<Runtime>, working_directory: Option<String>, grid_size: Option<(usize, usize)>, ) -> Result<Self>
Create a new tab with a terminal session
§Arguments
id- Unique tab identifiertab_number- Display number for the tab (1-indexed)config- Terminal configurationruntime- Tokio runtime for async operationsworking_directory- Optional working directory to start ingrid_size- Optional (cols, rows) override. When provided, uses these dimensions instead of config.cols/rows. This ensures the shell starts with the correct dimensions when the renderer has already calculated the grid size accounting for tab bar height.
Sourcepub fn new_from_profile(
id: TabId,
config: &Config,
_runtime: Arc<Runtime>,
profile: &Profile,
grid_size: Option<(usize, usize)>,
) -> Result<Self>
pub fn new_from_profile( id: TabId, config: &Config, _runtime: Arc<Runtime>, profile: &Profile, grid_size: Option<(usize, usize)>, ) -> Result<Self>
Create a new tab from a profile configuration
The profile can override:
- Working directory
- Command and arguments (instead of default shell)
- Tab name
If a profile specifies a command, it always runs from the profile’s working directory (or config default if unset).
§Arguments
id- Unique tab identifierconfig- Terminal configuration_runtime- Tokio runtime (unused: profile tabs don’t send initial text)profile- Profile configuration to usegrid_size- Optional (cols, rows) override for initial terminal size
§Unique logic vs Tab::new()
This constructor’s divergent logic (not shared with Tab::new() via new_internal):
- SSH command detection (
profile.ssh_command_args()) - Per-profile
login_shelloverride (takes precedence overconfig.login_shell) - Per-profile
SHELLenv-var injection whenprofile.shellis set - Title derived from
profile.tab_name→profile.name(not “Tab N”) - Profile tabs do NOT send
config.initial_texton startup
Sourcepub fn new_from_pane(
id: TabId,
pane: Pane,
_config: &Config,
_runtime: Arc<Runtime>,
tab_number: usize,
) -> Self
pub fn new_from_pane( id: TabId, pane: Pane, _config: &Config, _runtime: Arc<Runtime>, tab_number: usize, ) -> Self
Create a new tab wrapping an existing Pane (e.g., from a promote operation).
The pane’s PTY, scroll state, and session logger are preserved.
No new shell is spawned — the pane’s terminal keeps running.
The tab shares the pane’s Arc<RwLock<TerminalManager>> as its primary terminal.
Source§impl Tab
impl Tab
Sourcepub fn has_multiple_panes(&self) -> bool
pub fn has_multiple_panes(&self) -> bool
Check if this tab has multiple panes (split)
Sourcepub fn pane_count(&self) -> usize
pub fn pane_count(&self) -> usize
Get the number of panes in this tab
Sourcepub fn split_horizontal(
&mut self,
focus_new: bool,
config: &Config,
runtime: Arc<Runtime>,
dpi_scale: f32,
initial_command: Option<(String, Vec<String>)>,
split_percent: u8,
) -> Result<Option<PaneId>>
pub fn split_horizontal( &mut self, focus_new: bool, config: &Config, runtime: Arc<Runtime>, dpi_scale: f32, initial_command: Option<(String, Vec<String>)>, split_percent: u8, ) -> Result<Option<PaneId>>
Split the current pane horizontally (panes stacked vertically)
Returns the new pane ID if successful.
dpi_scale converts logical pixel config values to physical pixels.
focus_new controls whether the new pane receives focus after splitting.
initial_command — when Some((cmd, args)) the new pane runs that process directly.
Sourcepub fn split_vertical(
&mut self,
focus_new: bool,
config: &Config,
runtime: Arc<Runtime>,
dpi_scale: f32,
initial_command: Option<(String, Vec<String>)>,
split_percent: u8,
) -> Result<Option<PaneId>>
pub fn split_vertical( &mut self, focus_new: bool, config: &Config, runtime: Arc<Runtime>, dpi_scale: f32, initial_command: Option<(String, Vec<String>)>, split_percent: u8, ) -> Result<Option<PaneId>>
Split the current pane vertically (panes side by side)
Returns the new pane ID if successful.
dpi_scale converts logical pixel config values to physical pixels.
focus_new controls whether the new pane receives focus after splitting.
initial_command — when Some((cmd, args)) the new pane runs that process directly.
Sourcepub fn close_focused_pane(&mut self) -> bool
pub fn close_focused_pane(&mut self) -> bool
Close the focused pane
Returns true if this was the last pane (tab should close)
Sourcepub fn close_exited_panes(&mut self) -> (Vec<PaneId>, bool)
pub fn close_exited_panes(&mut self) -> (Vec<PaneId>, bool)
Check for exited panes and close them
Returns (closed_pane_ids, tab_should_close) where:
closed_pane_ids: Vec of pane IDs that were closedtab_should_close: true if all panes have exited (tab should close)
Sourcepub fn pane_manager(&self) -> Option<&PaneManager>
pub fn pane_manager(&self) -> Option<&PaneManager>
Get the pane manager if split panes are enabled
Sourcepub fn pane_manager_mut(&mut self) -> Option<&mut PaneManager>
pub fn pane_manager_mut(&mut self) -> Option<&mut PaneManager>
Get mutable access to the pane manager
Sourcepub fn init_pane_manager(&mut self)
pub fn init_pane_manager(&mut self)
Initialize the pane manager if not already present
This is used for tmux integration where we need to create the pane manager before applying a layout.
Sourcepub fn set_pane_bounds(
&mut self,
bounds: PaneBounds,
cell_width: f32,
cell_height: f32,
)
pub fn set_pane_bounds( &mut self, bounds: PaneBounds, cell_width: f32, cell_height: f32, )
Set the pane bounds and resize terminals
This should be called before creating splits to ensure panes are sized correctly. If the pane manager doesn’t exist yet, this creates it with the bounds set.
Sourcepub fn set_pane_bounds_with_padding(
&mut self,
bounds: PaneBounds,
cell_width: f32,
cell_height: f32,
padding: f32,
)
pub fn set_pane_bounds_with_padding( &mut self, bounds: PaneBounds, cell_width: f32, cell_height: f32, padding: f32, )
Set the pane bounds and resize terminals with padding
This should be called before creating splits to ensure panes are sized correctly. The padding parameter accounts for content inset from pane edges.
Sourcepub fn focus_pane_at(&mut self, x: f32, y: f32) -> Option<PaneId>
pub fn focus_pane_at(&mut self, x: f32, y: f32) -> Option<PaneId>
Focus the pane at the given pixel coordinates
Returns the ID of the newly focused pane, or None if no pane at that position
Sourcepub fn focused_pane_id(&self) -> Option<PaneId>
pub fn focused_pane_id(&self) -> Option<PaneId>
Get the ID of the currently focused pane
Sourcepub fn is_pane_focused(&self, pane_id: PaneId) -> bool
pub fn is_pane_focused(&self, pane_id: PaneId) -> bool
Check if a specific pane is focused
Navigate to an adjacent pane
Sourcepub fn is_on_divider(&self, x: f32, y: f32) -> bool
pub fn is_on_divider(&self, x: f32, y: f32) -> bool
Check if a position is on a divider
Sourcepub fn find_divider_at(&self, x: f32, y: f32) -> Option<usize>
pub fn find_divider_at(&self, x: f32, y: f32) -> Option<usize>
Find divider at position
Returns the divider index if found
Sourcepub fn get_divider(&self, index: usize) -> Option<DividerRect>
pub fn get_divider(&self, index: usize) -> Option<DividerRect>
Get divider info by index
Sourcepub fn drag_divider(&mut self, divider_index: usize, x: f32, y: f32)
pub fn drag_divider(&mut self, divider_index: usize, x: f32, y: f32)
Drag a divider to a new position
Sourcepub fn restore_pane_layout(
&mut self,
layout: &SessionPaneNode,
config: &Config,
runtime: Arc<Runtime>,
)
pub fn restore_pane_layout( &mut self, layout: &SessionPaneNode, config: &Config, runtime: Arc<Runtime>, )
Restore a pane layout from a saved session
Replaces the current single-pane layout with a saved pane tree. Each leaf in the tree gets a new terminal session with the saved CWD. If the build fails, the tab keeps its existing single pane.
Sourcepub fn start_pane_refresh_tasks(
&mut self,
runtime: Arc<Runtime>,
window: Arc<Window>,
active_fps: u32,
inactive_fps: u32,
)
pub fn start_pane_refresh_tasks( &mut self, runtime: Arc<Runtime>, window: Arc<Window>, active_fps: u32, inactive_fps: u32, )
Start refresh tasks for all panes that don’t already have one.
Must be called after pane creation (split, restore) to ensure each pane’s
terminal output triggers redraws. Without this, only tab.terminal is polled
by the tab refresh task, so secondary panes never trigger redraws.
Source§impl Tab
impl Tab
Sourcepub fn is_bell_active(&self) -> bool
pub fn is_bell_active(&self) -> bool
Check if the visual bell is currently active (within flash duration)
Sourcepub fn update_title(
&mut self,
title_mode: TabTitleMode,
remote_format: RemoteTabTitleFormat,
remote_osc_priority: bool,
)
pub fn update_title( &mut self, title_mode: TabTitleMode, remote_format: RemoteTabTitleFormat, remote_osc_priority: bool, )
Update tab title from terminal OSC sequences or shell integration data.
Priority when on a remote host (hostname detected via OSC 7):
- Explicit OSC title (
\033]0;...\007) ifremote_osc_priorityis true remote_format— formatted from hostname/username/cwd
Priority when local:
- Explicit OSC title
- Last CWD component (only in
TabTitleMode::Auto)
User-named tabs are never auto-updated.
Sourcepub fn set_default_title(&mut self, tab_number: usize)
pub fn set_default_title(&mut self, tab_number: usize)
Set the tab’s default title based on its position
Sourcepub fn set_title(&mut self, title: &str)
pub fn set_title(&mut self, title: &str)
Explicitly set the tab title (for tmux window names, etc.)
This overrides any default title and marks the tab as having a custom title.
Sourcepub fn is_running(&self) -> bool
pub fn is_running(&self) -> bool
Check if the terminal in this tab is still running
Sourcepub fn set_custom_color(&mut self, color: [u8; 3])
pub fn set_custom_color(&mut self, color: [u8; 3])
Set a custom color for this tab
Sourcepub fn clear_custom_color(&mut self)
pub fn clear_custom_color(&mut self)
Clear the custom color for this tab (reverts to default config colors)
Sourcepub fn has_custom_color(&self) -> bool
pub fn has_custom_color(&self) -> bool
Check if this tab has a custom color set
Sourcepub fn parse_hostname_from_osc7_url(url: &str) -> Option<String>
pub fn parse_hostname_from_osc7_url(url: &str) -> Option<String>
Parse hostname from an OSC 7 file:// URL
OSC 7 format: file://hostname/path or file:///path (localhost)
Returns the hostname if present and not localhost, None otherwise.
Sourcepub fn check_hostname_change(&mut self) -> Option<String>
pub fn check_hostname_change(&mut self) -> Option<String>
Check if hostname has changed and update tracking
Returns Some(hostname) if a new remote hostname was detected, None if hostname hasn’t changed or is local.
This uses the hostname extracted from OSC 7 sequences by the terminal emulator.
Sourcepub fn check_cwd_change(&mut self) -> Option<String>
pub fn check_cwd_change(&mut self) -> Option<String>
Check if CWD has changed and update tracking
Returns Some(cwd) if the CWD has changed, None otherwise. Uses the CWD reported via OSC 7 by the terminal emulator.
Sourcepub fn clear_auto_profile(&mut self)
pub fn clear_auto_profile(&mut self)
Clear auto-applied profile tracking
Call this when manually switching profiles or when the hostname returns to local, or when disconnecting from tmux.
Source§impl Tab
impl Tab
Sourcepub fn start_refresh_task(
&mut self,
runtime: Arc<Runtime>,
window: Arc<Window>,
active_fps: u32,
inactive_fps: u32,
)
pub fn start_refresh_task( &mut self, runtime: Arc<Runtime>, window: Arc<Window>, active_fps: u32, inactive_fps: u32, )
Start the refresh polling task for this tab
Sourcepub fn stop_refresh_task(&mut self)
pub fn stop_refresh_task(&mut self)
Stop the refresh polling task
Source§impl Tab
impl Tab
Sourcepub fn toggle_session_logging(&mut self, config: &Config) -> Result<bool>
pub fn toggle_session_logging(&mut self, config: &Config) -> Result<bool>
Toggle session logging on/off.
Returns Ok(true) if logging is now active, Ok(false) if stopped.
If logging wasn’t active and no logger exists, creates a new one.
Sourcepub fn is_session_logging_active(&self) -> bool
pub fn is_session_logging_active(&self) -> bool
Check if session logging is currently active.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Tab
impl !RefUnwindSafe for Tab
impl !UnwindSafe for Tab
impl Send for Tab
impl Sync for Tab
impl Unpin for Tab
impl UnsafeUnpin for Tab
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more