diff options
| author | Adam <[email protected]> | 2026-03-10 11:29:57 -0500 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-03-10 13:00:14 -0500 |
| commit | 835a27cf517fae5d9952c30989de8be8f760d7a5 (patch) | |
| tree | 94c5ec763e09517d42ce86a960264854c139f2f3 /packages/app/src/components | |
| parent | 85afaaa13d693f400d8ec8e257fec086a58b68c1 (diff) | |
| download | opencode-835a27cf517fae5d9952c30989de8be8f760d7a5.tar.gz opencode-835a27cf517fae5d9952c30989de8be8f760d7a5.zip | |
fix(app): terminal jank
Diffstat (limited to 'packages/app/src/components')
| -rw-r--r-- | packages/app/src/components/session/session-header.tsx | 75 | ||||
| -rw-r--r-- | packages/app/src/components/terminal.tsx | 5 |
2 files changed, 47 insertions, 33 deletions
diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 9b4551584..97f0530e9 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -21,6 +21,8 @@ import { useLayout } from "@/context/layout" import { usePlatform } from "@/context/platform" import { useServer } from "@/context/server" import { useSync } from "@/context/sync" +import { useTerminal } from "@/context/terminal" +import { focusTerminalById } from "@/pages/session/helpers" import { decode64 } from "@/utils/base64" import { Persist, persisted } from "@/utils/persist" import { StatusPopover } from "../status-popover" @@ -229,6 +231,7 @@ export function SessionHeader() { const sync = useSync() const platform = usePlatform() const language = useLanguage() + const terminal = useTerminal() const projectDirectory = createMemo(() => decode64(params.dir) ?? "") const project = createMemo(() => { @@ -296,6 +299,16 @@ export function SessionHeader() { ] as const }) + const toggleTerminal = () => { + const next = !view().terminal.opened() + view().terminal.toggle() + if (!next) return + + const id = terminal.active() + if (!id) return + focusTerminalById(id) + } + const [prefs, setPrefs] = persisted(Persist.global("open.app"), createStore({ app: "finder" as OpenApp })) const [menu, setMenu] = createStore({ open: false }) const [openRequest, setOpenRequest] = createStore({ @@ -617,39 +630,39 @@ export function SessionHeader() { </div> </Show> <div class="flex items-center gap-1"> - <div class="hidden md:flex items-center gap-1 shrink-0"> - <TooltipKeybind - title={language.t("command.terminal.toggle")} - keybind={command.keybind("terminal.toggle")} + <TooltipKeybind + title={language.t("command.terminal.toggle")} + keybind={command.keybind("terminal.toggle")} + > + <Button + variant="ghost" + class="group/terminal-toggle titlebar-icon w-8 h-6 p-0 box-border shrink-0" + onClick={toggleTerminal} + aria-label={language.t("command.terminal.toggle")} + aria-expanded={view().terminal.opened()} + aria-controls="terminal-panel" > - <Button - variant="ghost" - class="group/terminal-toggle titlebar-icon w-8 h-6 p-0 box-border" - onClick={() => view().terminal.toggle()} - aria-label={language.t("command.terminal.toggle")} - aria-expanded={view().terminal.opened()} - aria-controls="terminal-panel" - > - <div class="relative flex items-center justify-center size-4 [&>*]:absolute [&>*]:inset-0"> - <Icon - size="small" - name={view().terminal.opened() ? "layout-bottom-partial" : "layout-bottom"} - class="group-hover/terminal-toggle:hidden" - /> - <Icon - size="small" - name="layout-bottom-partial" - class="hidden group-hover/terminal-toggle:inline-block" - /> - <Icon - size="small" - name={view().terminal.opened() ? "layout-bottom" : "layout-bottom-partial"} - class="hidden group-active/terminal-toggle:inline-block" - /> - </div> - </Button> - </TooltipKeybind> + <div class="relative flex items-center justify-center size-4 [&>*]:absolute [&>*]:inset-0"> + <Icon + size="small" + name={view().terminal.opened() ? "layout-bottom-partial" : "layout-bottom"} + class="group-hover/terminal-toggle:hidden" + /> + <Icon + size="small" + name="layout-bottom-partial" + class="hidden group-hover/terminal-toggle:inline-block" + /> + <Icon + size="small" + name={view().terminal.opened() ? "layout-bottom" : "layout-bottom-partial"} + class="hidden group-active/terminal-toggle:inline-block" + /> + </div> + </Button> + </TooltipKeybind> + <div class="hidden md:flex items-center gap-1 shrink-0"> <TooltipKeybind title={language.t("command.review.toggle")} keybind={command.keybind("review.toggle")} diff --git a/packages/app/src/components/terminal.tsx b/packages/app/src/components/terminal.tsx index 9e5f12ee4..120af0a17 100644 --- a/packages/app/src/components/terminal.tsx +++ b/packages/app/src/components/terminal.tsx @@ -17,6 +17,7 @@ const TOGGLE_TERMINAL_ID = "terminal.toggle" const DEFAULT_TOGGLE_TERMINAL_KEYBIND = "ctrl+`" export interface TerminalProps extends ComponentProps<"div"> { pty: LocalPTY + autoFocus?: boolean onSubmit?: () => void onCleanup?: (pty: Partial<LocalPTY> & { id: string }) => void onConnect?: () => void @@ -157,7 +158,7 @@ export const Terminal = (props: TerminalProps) => { const language = useLanguage() const server = useServer() let container!: HTMLDivElement - const [local, others] = splitProps(props, ["pty", "class", "classList", "onConnect", "onConnectError"]) + const [local, others] = splitProps(props, ["pty", "class", "classList", "autoFocus", "onConnect", "onConnectError"]) const id = local.pty.id const restore = typeof local.pty.buffer === "string" ? local.pty.buffer : "" const restoreSize = @@ -386,7 +387,7 @@ export const Terminal = (props: TerminalProps) => { handleLinkClick, }) - focusTerminal() + if (local.autoFocus !== false) focusTerminal() if (typeof document !== "undefined" && document.fonts) { document.fonts.ready.then(scheduleFit) |
