fix use mouse + tabs

This commit is contained in:
Simon Klee
2026-04-17 16:08:39 +02:00
parent 52c196c723
commit a4f6a3d191
3 changed files with 46 additions and 28 deletions

View File

@@ -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<string>()
return (
<box
id="run-direct-footer-subagent-tabs"
@@ -55,25 +52,11 @@ export function RunFooterSubagentTabs(props: {
flexShrink={0}
>
<box flexDirection="row" gap={3} flexShrink={1} flexGrow={1}>
{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 (
<box
paddingRight={1}
onMouseOver={() => {
setHover(tab.sessionID)
}}
onMouseOut={() => {
if (hover() === tab.sessionID) {
setHover(undefined)
}
}}
onMouseUp={() => {
props.onToggle(tab.sessionID)
}}
>
<box paddingRight={1}>
<box flexDirection="row" gap={1} width="100%">
{tab.status === "running" ? (
<box flexShrink={0}>
@@ -84,8 +67,8 @@ export function RunFooterSubagentTabs(props: {
{statusIcon(tab.status)}
</text>
)}
<text fg={emphasized() ? props.theme.text : props.theme.muted} wrapMode="none" truncate>
{tab.label}
<text fg={active() ? props.theme.text : props.theme.muted} wrapMode="none" truncate>
{`[${slot}] ${tab.label}`}
</text>
</box>
</box>
@@ -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
}

View File

@@ -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) {
<box id="run-direct-footer-top-spacer" width="100%" height={1} flexShrink={0} backgroundColor="transparent" />
<Show when={showTabs()}>
<RunFooterSubagentTabs tabs={tabs()} selected={selected()} theme={theme()} onToggle={toggleTab} />
<RunFooterSubagentTabs tabs={tabs()} selected={selected()} theme={theme()} />
</Show>
<Show

View File

@@ -154,7 +154,7 @@ export async function createRuntimeLifecycle(input: LifecycleInput): Promise<Lif
const renderer = await createCliRenderer({
targetFps: 30,
maxFps: 60,
useMouse: true,
useMouse: false,
autoFocus: false,
openConsoleOnError: false,
exitOnCtrlC: false,