aboutsummaryrefslogtreecommitdiff
path: root/src/server/headless/notifications.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-02 14:24:33 +0300
committerGitHub <noreply@github.com>2026-09-02 14:24:33 +0300
commit6c0bb273d5d5405a00985621b17e36f8b4d64609 (patch)
treeceef5ea8adf337bf3c1e977b133e76cb763c6f1b /src/server/headless/notifications.rs
parentcc88b3b8e5bb9f7d9f23ed6ae85a52fd7b5b9ed6 (diff)
feat: support independent multi-client tab views (#3526)
Diffstat (limited to 'src/server/headless/notifications.rs')
-rw-r--r--src/server/headless/notifications.rs49
1 files changed, 48 insertions, 1 deletions
diff --git a/src/server/headless/notifications.rs b/src/server/headless/notifications.rs
index 3587b5cf..92020d63 100644
--- a/src/server/headless/notifications.rs
+++ b/src/server/headless/notifications.rs
@@ -320,7 +320,20 @@ impl HeadlessServer {
/// in the headless server — use this method instead.
///
/// Returns true if the event changed visual state (requiring a re-render).
- pub(super) fn handle_internal_event_with_forwarding(&mut self, ev: AppEvent) -> bool {
+ pub(super) fn handle_internal_event_with_forwarding(&mut self, mut ev: AppEvent) -> bool {
+ let mut focused_worktree_response = if let AppEvent::WorktreeAddFinished(result) = &mut ev {
+ result
+ .api_request
+ .as_mut()
+ .filter(|request| request.focus)
+ .map(|request| {
+ let (proxy_tx, proxy_rx) = std::sync::mpsc::channel();
+ let original = std::mem::replace(&mut request.respond_to, proxy_tx);
+ (original, proxy_rx)
+ })
+ } else {
+ None
+ };
match &ev {
AppEvent::TerminalBell { pane_id, count } => {
if !self.send_to_foreground_client(ServerMessage::TerminalBell { count: *count }) {
@@ -592,7 +605,39 @@ impl HeadlessServer {
true
}
+ AppEvent::WorktreeAddFinished(result) => {
+ let deferred_request_id = result
+ .api_request
+ .as_ref()
+ .map(|request| request.id.as_str());
+ let shell_navigation_pending = deferred_request_id.is_some_and(|request_id| {
+ self.clients.values().any(|client| {
+ client.shell_deferred_navigation_request_id.as_deref() == Some(request_id)
+ })
+ });
+ let changed = self.app.handle_internal_event_with_render_impact(ev);
+ let api_focus_succeeded = super::client_views::forward_proxied_api_response(
+ focused_worktree_response.take(),
+ );
+ self.reconcile_client_shell_locations();
+ if shell_navigation_pending {
+ self.app.accept_current_focus_without_events();
+ } else if api_focus_succeeded {
+ self.focus_all_shell_clients_on_default_target();
+ }
+ changed
+ }
+ AppEvent::WorktreeRemoveFinished(_) => {
+ let focus_before = self.shell_focus_targets();
+ let focused_tabs_before = self.focused_shell_tabs();
+ let changed = self.app.handle_internal_event_with_render_impact(ev);
+ self.reconcile_client_shell_locations();
+ self.finish_shell_location_reconciliation(focus_before, &focused_tabs_before);
+ changed
+ }
AppEvent::PaneDied { pane_id } => {
+ let focus_before = self.shell_focus_targets();
+ let focused_tabs_before = self.focused_shell_tabs();
let pane_id_val = *pane_id;
let terminal_id = self.app.state.workspaces.iter().find_map(|ws| {
ws.tabs.iter().find_map(|tab| {
@@ -612,6 +657,8 @@ impl HeadlessServer {
}
self.app.handle_internal_event(ev);
+ self.reconcile_client_shell_locations();
+ self.finish_shell_location_reconciliation(focus_before, &focused_tabs_before);
if self.app.find_pane(pane_id_val).is_none() {
if let Some(terminal_id) = terminal_id {