aboutsummaryrefslogtreecommitdiff
path: root/src/app/creation.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-01 15:48:22 +0300
committerGitHub <noreply@github.com>2026-09-01 15:48:22 +0300
commit207be3c771d281baae6e5fa0fb74be9a056e97a2 (patch)
treed7b037ecdf629224a048c841d11659efdc23507d /src/app/creation.rs
parent8a6d697308162874a236c84aac0b0f8c7ac01f83 (diff)
refactor: render the shell in the client (#3487)
* feat: add opt-in client-rendered shell * feat: add client-owned shell mouse controls * feat: complete client-owned shell chrome * feat: add client-owned shell settings and notifications * feat: run client shell custom commands * feat: render popup terminals in client shell * feat: add client-owned scrollback and copy mode * fix: preserve client worktree trust defaults * feat: render startup diagnostics in client shell * feat: render onboarding in client shell * feat: render product announcements in client shell * feat: render release notes in client shell * feat: render mobile switcher in client shell * feat: render kitty graphics in client shell * fix: preserve client shell lifecycle coherence * refactor: route client shell commands through endpoint connections * refactor: make the client-rendered shell the default * refactor: remove monolithic launch mode * refactor: complete client-rendered shell cutover * perf: retain client pane surface updates * perf: scale retained pane surface updates * perf: remove remote pane input latency * test: make client shell checks platform-independent * fix: prevent client timer starvation * test: fix client shell platform gates * test: accept retained surfaces in cross-area checks * test: make client mode assertions platform-neutral * fix: badge only outdated integrations
Diffstat (limited to 'src/app/creation.rs')
-rw-r--r--src/app/creation.rs145
1 files changed, 8 insertions, 137 deletions
diff --git a/src/app/creation.rs b/src/app/creation.rs
index d531e733..fbe61902 100644
--- a/src/app/creation.rs
+++ b/src/app/creation.rs
@@ -1,13 +1,10 @@
use std::path::PathBuf;
-use crate::api::schema::{EventData, EventEnvelope, EventKind};
-#[cfg(test)]
-use tracing::error;
-
use super::{
api_helpers::{pane_agent_status, tab_attention_priority},
App, Mode,
};
+use crate::api::schema::{EventData, EventEnvelope, EventKind};
use crate::{config::NewTerminalCwdConfig, workspace::Workspace};
pub(crate) fn resolve_new_terminal_cwd(
@@ -81,6 +78,13 @@ impl App {
resolve_new_terminal_cwd(&self.state.new_terminal_cwd, follow_cwd)
}
+ pub(crate) fn resolved_new_workspace_cwd_from(&self, ws_idx: usize) -> PathBuf {
+ let follow_cwd = self
+ .focused_pane_cwd_in_workspace(ws_idx)
+ .or_else(|| self.seed_cwd_from_workspace(ws_idx));
+ self.resolve_new_terminal_cwd(follow_cwd)
+ }
+
pub(super) fn workspace_creation_source(&self) -> Option<usize> {
if self.state.mode == Mode::Navigate
&& self.state.workspaces.get(self.state.selected).is_some()
@@ -96,128 +100,6 @@ impl App {
})
}
- pub(super) fn begin_tui_workspace_create(&mut self, request_id: &'static str) {
- if self.state.prompt_new_workspace_name {
- let follow_cwd = self.workspace_creation_source().and_then(|ws_idx| {
- self.focused_pane_cwd_in_workspace(ws_idx)
- .or_else(|| self.seed_cwd_from_workspace(ws_idx))
- });
- let cwd = self.resolve_new_terminal_cwd(follow_cwd);
- super::input::open_new_workspace_dialog(&mut self.state, cwd);
- return;
- }
-
- self.runtime_workspace_create(
- request_id,
- crate::api::schema::WorkspaceCreateParams {
- cwd: None,
- focus: true,
- label: None,
- env: Default::default(),
- },
- );
- self.state.mode = if self.state.active.is_some() {
- Mode::Terminal
- } else {
- Mode::Navigate
- };
- }
-
- /// Create a workspace with a real PTY (needs event_tx).
- #[cfg(test)]
- pub(crate) fn create_workspace(&mut self) {
- let follow_cwd = self.workspace_creation_source().and_then(|ws_idx| {
- self.focused_pane_cwd_in_workspace(ws_idx)
- .or_else(|| self.seed_cwd_from_workspace(ws_idx))
- });
- let initial_cwd = self.resolve_new_terminal_cwd(follow_cwd);
- if let Err(e) = self.create_workspace_with_events(initial_cwd, true) {
- error!(err = %e, "failed to create workspace");
- self.state.mode = Mode::Navigate;
- }
- }
-
- #[cfg(test)]
- pub(crate) fn create_tab(&mut self) {
- let custom_name = self.state.requested_new_tab_name.take();
- let active_before = self.state.active;
- let follow_cwd = self.state.active.and_then(|ws_idx| {
- self.focused_pane_cwd_in_workspace(ws_idx)
- .or_else(|| self.seed_cwd_from_workspace(ws_idx))
- });
- let initial_cwd = self.resolve_new_terminal_cwd(follow_cwd);
- match self.create_tab_with_options(initial_cwd, true) {
- Ok(created_idx) => {
- let created_workspace = active_before.is_none();
- let ws_idx = if created_workspace {
- Some(created_idx)
- } else {
- self.state.active
- };
- let tab_idx = if created_workspace { 0 } else { created_idx };
- if let Some(name) = custom_name {
- if let Some(ws) =
- ws_idx.and_then(|ws_idx| self.state.workspaces.get_mut(ws_idx))
- {
- if let Some(tab) = ws.tabs.get_mut(tab_idx) {
- tab.set_custom_name(name);
- }
- self.schedule_session_save();
- }
- }
- if let Some(ws_idx) = ws_idx {
- if created_workspace {
- self.emit_workspace_open_events(ws_idx);
- } else {
- self.emit_tab_created_events(ws_idx, tab_idx);
- }
- }
- }
- Err(e) => {
- error!(err = %e, "failed to create tab");
- }
- }
- }
-
- #[cfg(test)]
- pub(super) fn create_tab_with_options(
- &mut self,
- initial_cwd: PathBuf,
- focus: bool,
- ) -> std::io::Result<usize> {
- let Some(ws_idx) = self.state.active else {
- return self.create_workspace_with_options(initial_cwd, focus);
- };
- let (rows, cols) = self.state.estimate_pane_size();
- let ws = &mut self.state.workspaces[ws_idx];
- let (idx, terminal, runtime) = ws.create_tab(
- rows,
- cols,
- initial_cwd,
- self.state.pane_scrollback_limit_bytes,
- self.state.host_terminal_theme,
- self.state.host_terminal_appearance,
- crate::pane::PaneShellConfig::new(&self.state.default_shell, self.state.shell_mode),
- Vec::new(),
- )?;
- let root_pane = ws.tabs[idx].root_pane;
- self.terminal_runtimes.insert(terminal.id.clone(), runtime);
- self.state.terminals.insert(terminal.id.clone(), terminal);
- self.state.remove_alias_shadowed_by_new_pane(root_pane);
- if focus {
- self.state.switch_workspace_tab(ws_idx, idx);
- self.state.mode = Mode::Terminal;
- }
- let workspace_id = self.state.workspaces[ws_idx].id.clone();
- let tab_id = self
- .public_tab_id(ws_idx, idx)
- .unwrap_or_else(|| crate::workspace::public_tab_id_for_number(&workspace_id, idx + 1));
- let root_pane = self.state.workspaces[ws_idx].tabs[idx].root_pane.raw();
- crate::logging::tab_created(&workspace_id, &tab_id, root_pane);
- self.schedule_session_save();
- Ok(idx)
- }
-
pub(crate) fn create_workspace_with_options(
&mut self,
initial_cwd: PathBuf,
@@ -226,17 +108,6 @@ impl App {
self.create_workspace_with_launch_env(initial_cwd, focus, Vec::new())
}
- #[cfg(test)]
- pub(crate) fn create_workspace_with_events(
- &mut self,
- initial_cwd: PathBuf,
- focus: bool,
- ) -> std::io::Result<()> {
- let ws_idx = self.create_workspace_with_options(initial_cwd, focus)?;
- self.emit_workspace_open_events(ws_idx);
- Ok(())
- }
-
pub(crate) fn create_workspace_with_launch_env(
&mut self,
initial_cwd: PathBuf,