aboutsummaryrefslogtreecommitdiff
path: root/src/client/shell/input.rs
diff options
context:
space:
mode:
authorakbash <akbash@herdr.dev>2026-09-09 02:35:31 +0300
committerGitHub <noreply@github.com>2026-09-09 02:35:31 +0300
commitb9ce96869e89937278d673d70ae4c135dd318469 (patch)
treefea7e39dad42f8cad1f1846af6babda546c1fa78 /src/client/shell/input.rs
parent8be4cf765afddfd9cf3206602ba4dab682a29fa1 (diff)
feat: navigate and highlight workspaces across machines (#3755)
* fix: highlight workspace navigation with saved machines refs #3754 * feat: navigate workspaces across connected machines refs #3754 * feat: navigate workspaces across machines refs #3754 --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
Diffstat (limited to 'src/client/shell/input.rs')
-rw-r--r--src/client/shell/input.rs77
1 files changed, 25 insertions, 52 deletions
diff --git a/src/client/shell/input.rs b/src/client/shell/input.rs
index 9b5fff21..dd7bf87d 100644
--- a/src/client/shell/input.rs
+++ b/src/client/shell/input.rs
@@ -128,7 +128,9 @@ impl ClientShellState {
}
fn prepare_committed_text(&mut self, text: &str, outcome: &mut ClientShellInput) -> bool {
- if self.insert_copy_search_text(text) {
+ if !(self.mode == ClientShellMode::Navigate && self.workspace_preview_action_blocked())
+ && self.insert_copy_search_text(text)
+ {
outcome.repaint = true;
return true;
}
@@ -425,7 +427,12 @@ impl ClientShellState {
}
pub(super) fn modal_paste_target_active(&self) -> bool {
- if self.popup_pending || self.popup_input_target().is_some() {
+ if self.popup_pending
+ || self.popup_input_target().is_some()
+ || (self.overlay.is_none()
+ && self.mode == ClientShellMode::Navigate
+ && self.workspace_preview_action_blocked())
+ {
return false;
}
if self
@@ -655,6 +662,22 @@ impl ClientShellState {
return;
}
+ let (code, modifiers) = crate::config::normalize_key_combo((key.code, key.modifiers));
+ if code == KeyCode::Enter && modifiers.is_empty() {
+ self.accept_navigate_workspace(outcome);
+ return;
+ }
+ if self.workspace_preview_action_blocked() {
+ self.push_endpoint_notice(
+ ClientEndpointNoticeKind::Rejected,
+ "navigate_endpoint_inactive",
+ "Confirm workspace first",
+ "Select an available workspace and press Enter before using workspace or pane actions",
+ );
+ outcome.repaint = true;
+ return;
+ }
+
if let Some(index) = ('1'..='9').position(|digit| {
crate::config::terminal_key_matches_combo(
key,
@@ -678,24 +701,8 @@ impl ClientShellState {
return;
}
- let (code, modifiers) = crate::config::normalize_key_combo((key.code, key.modifiers));
if modifiers.is_empty() {
match code {
- KeyCode::Enter => {
- let selected = self.navigate_workspace_id.clone();
- self.mode = ClientShellMode::Terminal;
- self.navigate_workspace_id = None;
- if let Some(workspace_id) = selected {
- self.push_endpoint_method(
- crate::api::schema::Method::WorkspaceFocus(
- crate::api::schema::WorkspaceTarget { workspace_id },
- ),
- outcome,
- );
- }
- outcome.repaint = true;
- return;
- }
KeyCode::Tab => {
self.record_navigate_binding(
KeybindMatch::Action(KeybindAction::CyclePaneNext),
@@ -804,7 +811,6 @@ impl ClientShellState {
if !self.indexed_navigation_target_exists(&binding) {
return;
}
-
if let KeybindMatch::Action(KeybindAction::CyclePaneNext) = binding {
self.cycle_pane(false, outcome);
} else if let KeybindMatch::Action(KeybindAction::CyclePanePrevious) = binding {
@@ -862,39 +868,6 @@ impl ClientShellState {
}
}
- fn move_navigate_workspace(&mut self, delta: isize) {
- let Some(snapshot) = self.snapshot.as_deref() else {
- return;
- };
- let mobile = self.mobile_layout_active();
- let entries = self.navigation_workspace_entries(snapshot);
- if entries.is_empty() {
- return;
- }
- let current = self
- .navigate_workspace_id
- .as_deref()
- .and_then(|selected| {
- entries
- .iter()
- .position(|entry| snapshot.workspaces[entry.index].workspace_id == selected)
- })
- .unwrap_or(0);
- let next = if mobile {
- (current as isize + delta).clamp(0, entries.len().saturating_sub(1) as isize) as usize
- } else {
- (current as isize + delta).rem_euclid(entries.len() as isize) as usize
- };
- let workspace_id = snapshot.workspaces[entries[next].index]
- .workspace_id
- .clone();
- self.navigate_workspace_id = Some(workspace_id.clone());
- self.reveal_mobile_workspace = mobile;
- if !mobile {
- self.reveal_workspace(&workspace_id);
- }
- }
-
fn cycle_pane(&mut self, reverse: bool, outcome: &mut ClientShellInput) {
let Some(snapshot) = self.snapshot.as_deref() else {
return;