From ff25aa038fe156811f91df244251b8a9c68effd3 Mon Sep 17 00:00:00 2001 From: Simon Klee Date: Fri, 17 Apr 2026 16:08:39 +0200 Subject: [PATCH] fix use mouse + tabs --- .../src/cli/cmd/run/footer.subagent.tsx | 33 ++++------------ .../opencode/src/cli/cmd/run/footer.view.tsx | 39 ++++++++++++++++++- .../src/cli/cmd/run/runtime.lifecycle.ts | 2 +- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/packages/opencode/src/cli/cmd/run/footer.subagent.tsx b/packages/opencode/src/cli/cmd/run/footer.subagent.tsx index 7e5e4dacf6..019a550c14 100644 --- a/packages/opencode/src/cli/cmd/run/footer.subagent.tsx +++ b/packages/opencode/src/cli/cmd/run/footer.subagent.tsx @@ -2,7 +2,7 @@ import type { ScrollBoxRenderable } from "@opentui/core" import { useKeyboard } from "@opentui/solid" import "opentui-spinner/solid" -import { For, createMemo, createSignal } from "solid-js" +import { For, createMemo } from "solid-js" import { SPINNER_FRAMES } from "../tui/component/spinner" import { RunEntryContent, sameEntryGroup } from "./scrollback.writer" import type { FooterSubagentDetail, FooterSubagentTab, RunDiffStyle } from "./types" @@ -39,10 +39,7 @@ export function RunFooterSubagentTabs(props: { tabs: FooterSubagentTab[] selected?: string theme: RunFooterTheme - onToggle: (sessionID: string) => void }) { - const [hover, setHover] = createSignal() - return ( - {props.tabs.map((tab) => { + {props.tabs.map((tab, index) => { const active = () => props.selected === tab.sessionID - const hovered = () => hover() === tab.sessionID - const emphasized = () => active() || hovered() + const slot = String(index + 1) return ( - { - setHover(tab.sessionID) - }} - onMouseOut={() => { - if (hover() === tab.sessionID) { - setHover(undefined) - } - }} - onMouseUp={() => { - props.onToggle(tab.sessionID) - }} - > + {tab.status === "running" ? ( @@ -84,8 +67,8 @@ export function RunFooterSubagentTabs(props: { {statusIcon(tab.status)} )} - - {tab.label} + + {`[${slot}] ${tab.label}`} @@ -125,9 +108,9 @@ export function RunFooterSubagentBody(props: { return } - if (event.name === "tab") { + if (event.name === "tab" && !event.shift) { event.preventDefault() - props.onCycle(event.shift ? -1 : 1) + props.onCycle(1) return } diff --git a/packages/opencode/src/cli/cmd/run/footer.view.tsx b/packages/opencode/src/cli/cmd/run/footer.view.tsx index cfe746c76b..3754e7027e 100644 --- a/packages/opencode/src/cli/cmd/run/footer.view.tsx +++ b/packages/opencode/src/cli/cmd/run/footer.view.tsx @@ -10,7 +10,7 @@ // All state comes from the parent RunFooter through SolidJS signals. // The view itself is stateless except for derived memos. /** @jsxImportSource @opentui/solid */ -import { useTerminalDimensions } from "@opentui/solid" +import { useKeyboard, useTerminalDimensions } from "@opentui/solid" import { Match, Show, Switch, createEffect, createMemo, createSignal } from "solid-js" import "opentui-spinner/solid" import { createColors, createFrames } from "../tui/ui/spinner" @@ -76,6 +76,24 @@ type RunFooterViewProps = { onSubagentSelect?: (sessionID: string | undefined) => void } +function subagentShortcut(event: { + name: string + ctrl?: boolean + meta?: boolean + shift?: boolean + super?: boolean +}): number | undefined { + if (!event.ctrl || event.meta || event.super) { + return + } + + if (!/^[1-9]$/.test(event.name)) { + return + } + + return Number(event.name) - 1 +} + export { TEXTAREA_MIN_ROWS, TEXTAREA_MAX_ROWS } from "./footer.prompt" export function RunFooterView(props: RunFooterViewProps) { @@ -211,6 +229,23 @@ export function RunFooterView(props: RunFooterViewProps) { }) const menu = createMemo(() => prompt() && composer.visible()) + useKeyboard((event) => { + if (active().type !== "prompt") { + return + } + + const slot = subagentShortcut(event) + if (slot !== undefined) { + const next = tabs()[slot] + if (!next) { + return + } + + event.preventDefault() + toggleTab(next.sessionID) + } + }) + createEffect(() => { const current = route() if (current.type === "composer") { @@ -245,7 +280,7 @@ export function RunFooterView(props: RunFooterViewProps) { - +