aboutsummaryrefslogtreecommitdiff
path: root/src/ui/panes.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-17 01:41:16 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-17 01:41:16 +0300
commita36da363f14639085bec91d7a378d6c2eeaa6c58 (patch)
tree2c86155b115f8c79db2b8826fd8b2199d153f7bf /src/ui/panes.rs
parente4de58b37f58d59d146158239ed218a8accd5c3c (diff)
refactor: extract terminal state and runtime from panes
Diffstat (limited to 'src/ui/panes.rs')
-rw-r--r--src/ui/panes.rs45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/ui/panes.rs b/src/ui/panes.rs
index 289d5fab..c90183ea 100644
--- a/src/ui/panes.rs
+++ b/src/ui/panes.rs
@@ -11,9 +11,9 @@ use super::widgets::panel_contrast_fg;
use crate::app::state::Palette;
use crate::app::{AppState, Mode};
use crate::layout::PaneInfo;
-use crate::pane::PaneRuntime;
+use crate::terminal::TerminalRuntime;
-pub(crate) fn pane_is_scrolled_back(rt: &PaneRuntime) -> bool {
+pub(crate) fn pane_is_scrolled_back(rt: &TerminalRuntime) -> bool {
rt.scroll_metrics()
.is_some_and(|metrics| metrics.offset_from_bottom > 0)
}
@@ -55,7 +55,20 @@ fn stable_terminal_inner_rect(pane_inner: Rect) -> Rect {
)
}
-fn stable_scrollbar_gutter(rt: &PaneRuntime, pane_inner: Rect) -> (Rect, Option<Rect>) {
+fn runtime_for_tab_pane<'a>(
+ app: &'a AppState,
+ tab: &'a crate::workspace::Tab,
+ pane_id: crate::layout::PaneId,
+) -> Option<&'a TerminalRuntime> {
+ #[cfg(test)]
+ if let Some(runtime) = tab.runtimes.get(&pane_id) {
+ return Some(runtime);
+ }
+ let terminal_id = tab.terminal_id(pane_id)?;
+ app.terminal_runtimes.get(terminal_id)
+}
+
+fn stable_scrollbar_gutter(rt: &TerminalRuntime, pane_inner: Rect) -> (Rect, Option<Rect>) {
let inner_rect = stable_terminal_inner_rect(pane_inner);
if inner_rect == pane_inner {
return (inner_rect, None);
@@ -76,6 +89,7 @@ fn stable_scrollbar_gutter(rt: &PaneRuntime, pane_inner: Rect) -> (Rect, Option<
/// Resize every visible runtime in a tab to the geometry it would receive if the tab were selected.
pub(super) fn resize_tab_panes(
+ app: &AppState,
tab: &crate::workspace::Tab,
area: Rect,
cell_size: crate::kitty_graphics::HostCellSize,
@@ -84,7 +98,7 @@ pub(super) fn resize_tab_panes(
if tab.zoomed {
let focused_id = tab.layout.focused();
- if let Some(rt) = tab.runtimes.get(&focused_id) {
+ if let Some(rt) = runtime_for_tab_pane(app, tab, focused_id) {
let inner_rect = stable_terminal_inner_rect(area);
rt.resize(
inner_rect.height,
@@ -103,7 +117,7 @@ pub(super) fn resize_tab_panes(
area
};
- if let Some(rt) = tab.runtimes.get(&info.id) {
+ if let Some(rt) = runtime_for_tab_pane(app, tab, info.id) {
let inner_rect = stable_terminal_inner_rect(pane_inner);
rt.resize(
inner_rect.height,
@@ -136,7 +150,7 @@ pub(super) fn compute_pane_infos(
let focused_id = ws.layout.focused();
let mut inner_rect = area;
let mut scrollbar_rect = None;
- if let Some(rt) = ws.runtimes.get(&focused_id) {
+ if let Some(rt) = app.runtime_for_pane_in_workspace(ws_idx, focused_id) {
(inner_rect, scrollbar_rect) = stable_scrollbar_gutter(rt, area);
if resize_panes {
rt.resize(
@@ -175,7 +189,7 @@ pub(super) fn compute_pane_infos(
let mut inner_rect = pane_inner;
let mut scrollbar_rect = None;
- if let Some(rt) = ws.runtimes.get(&info.id) {
+ if let Some(rt) = app.runtime_for_pane_in_workspace(ws_idx, info.id) {
(inner_rect, scrollbar_rect) = stable_scrollbar_gutter(rt, pane_inner);
if resize_panes {
rt.resize(
@@ -208,7 +222,7 @@ pub(super) fn render_panes(app: &AppState, frame: &mut Frame, area: Rect) {
let terminal_active = app.mode == Mode::Terminal;
for info in &app.view.pane_infos {
- if let Some(rt) = ws.runtimes.get(&info.id) {
+ if let Some(rt) = app.runtime_for_pane_in_workspace(ws_idx, info.id) {
if multi_pane {
let (border_style, border_set) = if info.is_focused && terminal_active {
(
@@ -233,7 +247,10 @@ pub(super) fn render_panes(app: &AppState, frame: &mut Frame, area: Rect) {
.border_set(border_set);
if let Some(title) = ws
.pane_state(info.id)
- .and_then(|pane| pane.border_label(app.show_agent_labels_on_pane_borders))
+ .and_then(|pane| app.terminals.get(&pane.attached_terminal_id))
+ .and_then(|terminal| {
+ terminal.border_label(app.show_agent_labels_on_pane_borders)
+ })
.and_then(|label| pane_border_title(label, info.rect.width))
{
block = block.title(Line::from(Span::styled(title, border_style)));
@@ -360,7 +377,7 @@ fn render_empty(app: &AppState, frame: &mut Frame, area: Rect) {
#[cfg(test)]
mod tests {
use super::*;
- use crate::pane::PaneRuntime;
+ use crate::terminal::TerminalRuntime;
use crate::workspace::Workspace;
#[test]
@@ -381,7 +398,7 @@ mod tests {
let root_pane = workspace.tabs[0].root_pane;
workspace.tabs[0].runtimes.insert(
root_pane,
- PaneRuntime::test_with_scrollback_bytes(40, 8, 1024, b"ready\n"),
+ TerminalRuntime::test_with_scrollback_bytes(40, 8, 1024, b"ready\n"),
);
app.workspaces = vec![workspace];
app.active = Some(0);
@@ -408,7 +425,7 @@ mod tests {
let root_pane = workspace.tabs[0].root_pane;
workspace.tabs[0].runtimes.insert(
root_pane,
- PaneRuntime::test_with_scrollback_bytes(40, 8, 1024, b"ready\n"),
+ TerminalRuntime::test_with_scrollback_bytes(40, 8, 1024, b"ready\n"),
);
app.workspaces = vec![workspace];
app.active = Some(0);
@@ -434,7 +451,7 @@ mod tests {
let root_pane = workspace.tabs[0].root_pane;
workspace.tabs[0].runtimes.insert(
root_pane,
- PaneRuntime::test_with_scrollback_bytes(4, 8, 1024, b"ready\n"),
+ TerminalRuntime::test_with_scrollback_bytes(4, 8, 1024, b"ready\n"),
);
app.workspaces = vec![workspace];
app.active = Some(0);
@@ -460,7 +477,7 @@ mod tests {
let root_pane = workspace.tabs[0].root_pane;
workspace.tabs[0].runtimes.insert(
root_pane,
- PaneRuntime::test_with_scrollback_bytes(
+ TerminalRuntime::test_with_scrollback_bytes(
40,
8,
1024,