aboutsummaryrefslogtreecommitdiff
path: root/src/app/input/mouse.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/app/input/mouse.rs
parente4de58b37f58d59d146158239ed218a8accd5c3c (diff)
refactor: extract terminal state and runtime from panes
Diffstat (limited to 'src/app/input/mouse.rs')
-rw-r--r--src/app/input/mouse.rs67
1 files changed, 37 insertions, 30 deletions
diff --git a/src/app/input/mouse.rs b/src/app/input/mouse.rs
index a7a2159a..10ef9c18 100644
--- a/src/app/input/mouse.rs
+++ b/src/app/input/mouse.rs
@@ -712,7 +712,8 @@ impl AppState {
.active
.and_then(|ws_idx| self.workspaces.get(ws_idx))
.and_then(|ws| ws.pane_state(info.id))
- .and_then(|pane| pane.manual_label.as_ref())
+ .and_then(|pane| self.terminals.get(&pane.attached_terminal_id))
+ .and_then(|terminal| terminal.manual_label.as_ref())
.is_some();
self.context_menu = Some(ContextMenuState {
kind: ContextMenuKind::Pane {
@@ -1061,16 +1062,16 @@ impl AppState {
}
pub(super) fn scroll_pane_up(&self, pane_id: crate::layout::PaneId, lines: usize) {
- if let Some(ws) = self.active.and_then(|i| self.workspaces.get(i)) {
- if let Some(rt) = ws.runtimes.get(&pane_id) {
+ if let Some(ws_idx) = self.active {
+ if let Some(rt) = self.runtime_for_pane_in_workspace(ws_idx, pane_id) {
rt.scroll_up(lines);
}
}
}
pub(super) fn scroll_pane_down(&self, pane_id: crate::layout::PaneId, lines: usize) {
- if let Some(ws) = self.active.and_then(|i| self.workspaces.get(i)) {
- if let Some(rt) = ws.runtimes.get(&pane_id) {
+ if let Some(ws_idx) = self.active {
+ if let Some(rt) = self.runtime_for_pane_in_workspace(ws_idx, pane_id) {
rt.scroll_down(lines);
}
}
@@ -1081,9 +1082,8 @@ impl AppState {
pane_id: crate::layout::PaneId,
) -> Option<crate::pane::ScrollMetrics> {
self.active
- .and_then(|i| self.workspaces.get(i))
- .and_then(|ws| ws.runtime(pane_id))
- .and_then(crate::pane::PaneRuntime::scroll_metrics)
+ .and_then(|i| self.runtime_for_pane_in_workspace(i, pane_id))
+ .and_then(crate::terminal::TerminalRuntime::scroll_metrics)
}
pub(super) fn handle_terminal_wheel(&mut self, mouse: MouseEvent) {
@@ -1112,8 +1112,8 @@ impl AppState {
return;
}
- if let Some(ws) = self.active.and_then(|i| self.workspaces.get(i)) {
- if let Some(rt) = ws.focused_runtime() {
+ if let Some(ws_idx) = self.active {
+ if let Some(rt) = self.focused_runtime_in_workspace(ws_idx) {
match mouse.kind {
MouseEventKind::ScrollUp => rt.scroll_up(LINES_PER_NOTCH),
MouseEventKind::ScrollDown => rt.scroll_down(LINES_PER_NOTCH),
@@ -1124,10 +1124,10 @@ impl AppState {
}
pub(super) fn forward_pane_mouse_button(&self, info: &PaneInfo, mouse: MouseEvent) -> bool {
- let Some(ws) = self.active.and_then(|i| self.workspaces.get(i)) else {
+ let Some(ws_idx) = self.active else {
return false;
};
- let Some(rt) = ws.runtimes.get(&info.id) else {
+ let Some(rt) = self.runtime_for_pane_in_workspace(ws_idx, info.id) else {
return false;
};
let column = mouse.column.saturating_sub(info.inner_rect.x);
@@ -1169,10 +1169,10 @@ impl AppState {
}
pub(super) fn forward_pane_wheel(&self, info: &PaneInfo, mouse: MouseEvent) -> bool {
- let Some(ws) = self.active.and_then(|i| self.workspaces.get(i)) else {
+ let Some(ws_idx) = self.active else {
return false;
};
- let Some(rt) = ws.runtimes.get(&info.id) else {
+ let Some(rt) = self.runtime_for_pane_in_workspace(ws_idx, info.id) else {
return false;
};
match rt.wheel_routing() {
@@ -1209,8 +1209,8 @@ impl AppState {
pane_id: crate::layout::PaneId,
offset_from_bottom: usize,
) {
- if let Some(ws) = self.active.and_then(|i| self.workspaces.get(i)) {
- if let Some(rt) = ws.runtimes.get(&pane_id) {
+ if let Some(ws_idx) = self.active {
+ if let Some(rt) = self.runtime_for_pane_in_workspace(ws_idx, pane_id) {
rt.set_scroll_offset_from_bottom(offset_from_bottom);
}
}
@@ -1221,7 +1221,7 @@ impl AppState {
col: u16,
row: u16,
) -> Option<(crate::layout::PaneId, ScrollbarClickTarget)> {
- let ws = self.active.and_then(|i| self.workspaces.get(i))?;
+ let ws_idx = self.active?;
let info = self.view.pane_infos.iter().find(|info| {
crate::ui::pane_scrollbar_rect(info).is_some_and(|track| {
col >= track.x
@@ -1230,7 +1230,7 @@ impl AppState {
&& row < track.y + track.height
})
})?;
- let rt = ws.runtimes.get(&info.id)?;
+ let rt = self.runtime_for_pane_in_workspace(ws_idx, info.id)?;
let metrics = rt.scroll_metrics()?;
if metrics.max_offset_from_bottom == 0 {
return None;
@@ -1254,14 +1254,14 @@ impl AppState {
row: u16,
grab_row_offset: u16,
) -> Option<usize> {
- let ws = self.active.and_then(|i| self.workspaces.get(i))?;
+ let ws_idx = self.active?;
let info = self
.view
.pane_infos
.iter()
.find(|info| info.id == pane_id)?;
let track = crate::ui::pane_scrollbar_rect(info)?;
- let rt = ws.runtimes.get(&pane_id)?;
+ let rt = self.runtime_for_pane_in_workspace(ws_idx, pane_id)?;
let metrics = rt.scroll_metrics()?;
if metrics.max_offset_from_bottom == 0 {
return None;
@@ -1345,12 +1345,19 @@ mod tests {
background.tabs[0].layout.focus_pane(first_pane);
app.state.workspaces = vec![active, background];
+ app.state.ensure_test_terminals();
app.state.active = Some(0);
app.state.selected = 0;
app.state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
- app.state.workspaces[1]
+ let target_terminal_id = app.state.workspaces[1]
.panes
- .get_mut(&target_pane)
+ .get(&target_pane)
+ .unwrap()
+ .attached_terminal_id
+ .clone();
+ app.state
+ .terminals
+ .get_mut(&target_terminal_id)
.unwrap()
.state = AgentState::Working;
@@ -1606,17 +1613,17 @@ mod tests {
.expect("second pane info")
.clone();
- app.state.workspaces[0].tabs[0].runtimes.insert(
+ app.state.insert_test_runtime(
first_pane,
- crate::pane::PaneRuntime::test_with_screen_bytes(
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(
first_info.inner_rect.width.max(1),
first_info.inner_rect.height.max(1),
b"\x1b[?1002h",
),
);
- app.state.workspaces[0].tabs[0].runtimes.insert(
+ app.state.insert_test_runtime(
second_pane,
- crate::pane::PaneRuntime::test_with_screen_bytes(
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(
second_info.inner_rect.width.max(1),
second_info.inner_rect.height.max(1),
b"\x1b[?1002h",
@@ -1675,17 +1682,17 @@ mod tests {
.expect("second pane info")
.clone();
- app.state.workspaces[0].tabs[0].runtimes.insert(
+ app.state.insert_test_runtime(
first_pane,
- crate::pane::PaneRuntime::test_with_screen_bytes(
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(
first_info.inner_rect.width.max(1),
first_info.inner_rect.height.max(1),
b"\x1b[?1002h",
),
);
- app.state.workspaces[0].tabs[0].runtimes.insert(
+ app.state.insert_test_runtime(
second_pane,
- crate::pane::PaneRuntime::test_with_screen_bytes(
+ crate::terminal::TerminalRuntime::test_with_screen_bytes(
second_info.inner_rect.width.max(1),
second_info.inner_rect.height.max(1),
b"\x1b[?1002h",