From 740d7a49284ef1ca1cc135a07eea1d50930cd5cb Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Mon, 4 May 2026 20:20:43 -0400 Subject: [PATCH] feat(resource-usage): kill X on every session row with confirm dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the Settings > Manage Sessions row behavior. Every session now gets a kill X in the trailing slot; bound sessions hide it until the row is hovered/focused, orphan sessions show it always. Clicking opens a confirm Dialog (anti-dismiss while in-flight) that calls pty.kill on confirm — same flow the settings pane uses. Co-authored-by: Orca --- .../status-bar/ResourceUsageStatusSegment.tsx | 130 ++++++++++++++---- 1 file changed, 103 insertions(+), 27 deletions(-) diff --git a/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx b/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx index c0e62a1d5e5..43a6079c4b7 100644 --- a/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx +++ b/src/renderer/src/components/status-bar/ResourceUsageStatusSegment.tsx @@ -8,15 +8,25 @@ import { AlertTriangle, ChevronDown, ChevronRight, + LoaderCircle, MemoryStick, Moon, RotateCw, Terminal, - Trash2 + Trash2, + X } from 'lucide-react' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import { Button } from '@/components/ui/button' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog' import { cn } from '@/lib/utils' import { activateAndRevealWorktree } from '@/lib/worktree-activation' import { useAppStore } from '../../store' @@ -679,17 +689,27 @@ function SessionsTabPanel({ ? sessions.filter((s) => !boundPtyIds.has(s.id)).length : 0 - const handleKill = useCallback( - async (id: string) => { - try { - await window.api.pty.kill(id) - } catch { - /* already dead */ - } + // Why: match the Settings page Manage Sessions pane — destructive + // single-session kill goes through a confirm dialog rather than + // firing on click. The dialog stays mounted on top of the popover. + const [killConfirm, setKillConfirm] = useState(null) + const [killing, setKilling] = useState(false) + + const runKillConfirmed = useCallback(async () => { + if (!killConfirm) { + return + } + setKilling(true) + try { + await window.api.pty.kill(killConfirm.id) + } catch { + /* already dead */ + } finally { + setKilling(false) + setKillConfirm(null) onSessionsChanged() - }, - [onSessionsChanged] - ) + } + }, [killConfirm, onSessionsChanged]) const handleKillOrphans = useCallback(async () => { if (!workspaceSessionReady) { @@ -745,9 +765,10 @@ function SessionsTabPanel({ return (
handleNavigate(tabId) : undefined} >
- {!isBound && ( - - )} + {/* Why: mirrors the Settings > Manage Sessions row — every + session gets a kill X. Bound sessions hide the X until + the row is hovered/focused so the list stays calm; the + kill flow opens a confirm Dialog before invoking IPC. */} + ) })} @@ -787,6 +814,55 @@ function SessionsTabPanel({ )} + + { + if (open) { + return + } + if (killing) { + return + } + setKillConfirm(null) + }} + > + { + if (killing) { + e.preventDefault() + } + }} + onEscapeKeyDown={(e) => { + if (killing) { + e.preventDefault() + } + }} + > + + Kill this session? + + Force-quits {killConfirm?.id}. + Any unsaved work in that pane is lost. This can't be undone. + + + + + + + + ) }