summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLuke Parker <[email protected]>2026-04-02 09:15:19 +1000
committerGitHub <[email protected]>2026-04-02 09:15:19 +1000
commitf7f41dc3a0ced9ab625cc3665424b7b8a4c571d0 (patch)
treeae1a685793dc2b32f2883f05db4d3955c4e7f47b
parent1fcfb69bf772f085289dd22f6898ac5d926226e9 (diff)
downloadopencode-f7f41dc3a0ced9ab625cc3665424b7b8a4c571d0.tar.gz
opencode-f7f41dc3a0ced9ab625cc3665424b7b8a4c571d0.zip
fix(tui): apply scroll configuration uniformly across all scrollboxes (#14735)
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/error-component.tsx3
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx5
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/index.tsx23
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx3
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx6
-rw-r--r--packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx8
-rw-r--r--packages/opencode/src/cli/cmd/tui/util/scroll.ts23
7 files changed, 49 insertions, 22 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/component/error-component.tsx b/packages/opencode/src/cli/cmd/tui/component/error-component.tsx
index c568e54e4..b22163902 100644
--- a/packages/opencode/src/cli/cmd/tui/component/error-component.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/error-component.tsx
@@ -4,6 +4,7 @@ import { Clipboard } from "@tui/util/clipboard"
import { createSignal } from "solid-js"
import { Installation } from "@/installation"
import { win32FlushInputBuffer } from "../win32"
+import { getScrollAcceleration } from "../util/scroll"
export function ErrorComponent(props: {
error: Error
@@ -82,7 +83,7 @@ export function ErrorComponent(props: {
<text fg={colors.bg}>Exit</text>
</box>
</box>
- <scrollbox height={Math.floor(term().height * 0.7)}>
+ <scrollbox height={Math.floor(term().height * 0.7)} scrollAcceleration={getScrollAcceleration()}>
<text fg={colors.muted}>{props.error.stack}</text>
</scrollbox>
<text fg={colors.text}>{props.error.message}</text>
diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
index 3240afab3..1c5ede4d7 100644
--- a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
@@ -6,6 +6,8 @@ import { createMemo, createResource, createEffect, onMount, onCleanup, Index, Sh
import { createStore } from "solid-js/store"
import { useSDK } from "@tui/context/sdk"
import { useSync } from "@tui/context/sync"
+import { getScrollAcceleration } from "../../util/scroll"
+import { useTuiConfig } from "../../context/tui-config"
import { useTheme, selectedForeground } from "@tui/context/theme"
import { SplitBorder } from "@tui/component/border"
import { useCommandDialog } from "@tui/component/dialog-command"
@@ -81,6 +83,7 @@ export function Autocomplete(props: {
const { theme } = useTheme()
const dimensions = useTerminalDimensions()
const frecency = useFrecency()
+ const tuiConfig = useTuiConfig()
const [store, setStore] = createStore({
index: 0,
@@ -605,6 +608,7 @@ export function Autocomplete(props: {
})
let scroll: ScrollBoxRenderable
+ const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig))
return (
<box
@@ -622,6 +626,7 @@ export function Autocomplete(props: {
backgroundColor={theme.backgroundMenu}
height={height()}
scrollbarOptions={{ visible: false }}
+ scrollAcceleration={scrollAcceleration()}
>
<Index
each={options()}
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index fb62de9ac..e51580638 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -82,16 +82,7 @@ import { UI } from "@/cli/ui.ts"
import { useTuiConfig } from "../../context/tui-config"
addDefaultParsers(parsers.parsers)
-
-class CustomSpeedScroll implements ScrollAcceleration {
- constructor(private speed: number) {}
-
- tick(_now?: number): number {
- return this.speed
- }
-
- reset(): void {}
-}
+import { getScrollAcceleration } from "../../util/scroll"
const context = createContext<{
width: number
@@ -168,17 +159,7 @@ export function Session() {
const showTimestamps = createMemo(() => timestamps() === "show")
const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 42 : 0) - 4)
- const scrollAcceleration = createMemo(() => {
- const tui = tuiConfig
- if (tui?.scroll_acceleration?.enabled) {
- return new MacOSScrollAccel()
- }
- if (tui?.scroll_speed) {
- return new CustomSpeedScroll(tui.scroll_speed)
- }
-
- return new CustomSpeedScroll(3)
- })
+ const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig))
createEffect(() => {
if (session()?.workspaceID) {
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
index a50cd96fc..a0d9a54ea 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
@@ -15,6 +15,7 @@ import { Keybind } from "@/util/keybind"
import { Locale } from "@/util/locale"
import { Global } from "@/global"
import { useDialog } from "../../ui/dialog"
+import { getScrollAcceleration } from "../../util/scroll"
import { useTuiConfig } from "../../context/tui-config"
type PermissionStage = "permission" | "always" | "reject"
@@ -62,12 +63,14 @@ function EditBody(props: { request: PermissionRequest }) {
})
const ft = createMemo(() => filetype(filepath()))
+ const scrollAcceleration = createMemo(() => getScrollAcceleration(config))
return (
<box flexDirection="column" gap={1}>
<Show when={diff()}>
<scrollbox
height="100%"
+ scrollAcceleration={scrollAcceleration()}
verticalScrollbarOptions={{
trackOptions: {
backgroundColor: theme.background,
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx
index 66bf82dba..3c87cfe47 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx
@@ -1,13 +1,18 @@
import { useSync } from "@tui/context/sync"
import { createMemo, Show } from "solid-js"
import { useTheme } from "../../context/theme"
+import { useTuiConfig } from "../../context/tui-config"
import { Installation } from "@/installation"
import { TuiPluginRuntime } from "../../plugin"
+import { getScrollAcceleration } from "../../util/scroll"
+
export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
const sync = useSync()
const { theme } = useTheme()
+ const tuiConfig = useTuiConfig()
const session = createMemo(() => sync.session.get(props.sessionID))
+ const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig))
return (
<Show when={session()}>
@@ -23,6 +28,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
>
<scrollbox
flexGrow={1}
+ scrollAcceleration={scrollAcceleration()}
verticalScrollbarOptions={{
trackOptions: {
backgroundColor: theme.background,
diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
index 34c6ee878..0e05c4866 100644
--- a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
+++ b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
@@ -10,6 +10,9 @@ import { useDialog, type DialogContext } from "@tui/ui/dialog"
import { useKeybind } from "@tui/context/keybind"
import { Keybind } from "@/util/keybind"
import { Locale } from "@/util/locale"
+import { useSync } from "@tui/context/sync"
+import { getScrollAcceleration } from "../util/scroll"
+import { useTuiConfig } from "../context/tui-config"
export interface DialogSelectProps<T> {
title: string
@@ -50,6 +53,10 @@ export type DialogSelectRef<T> = {
export function DialogSelect<T>(props: DialogSelectProps<T>) {
const dialog = useDialog()
const { theme } = useTheme()
+ const sync = useSync()
+ const tuiConfig = useTuiConfig()
+ const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig))
+
const [store, setStore] = createStore({
selected: 0,
filter: "",
@@ -276,6 +283,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
paddingLeft={1}
paddingRight={1}
scrollbarOptions={{ visible: false }}
+ scrollAcceleration={scrollAcceleration()}
ref={(r: ScrollBoxRenderable) => (scroll = r)}
maxHeight={height()}
>
diff --git a/packages/opencode/src/cli/cmd/tui/util/scroll.ts b/packages/opencode/src/cli/cmd/tui/util/scroll.ts
new file mode 100644
index 000000000..601c7fa92
--- /dev/null
+++ b/packages/opencode/src/cli/cmd/tui/util/scroll.ts
@@ -0,0 +1,23 @@
+import { MacOSScrollAccel, type ScrollAcceleration } from "@opentui/core"
+import { TuiConfig } from "@/config/tui"
+
+export class CustomSpeedScroll implements ScrollAcceleration {
+ constructor(private speed: number) {}
+
+ tick(_now?: number): number {
+ return this.speed
+ }
+
+ reset(): void {}
+}
+
+export function getScrollAcceleration(tuiConfig?: TuiConfig.Info): ScrollAcceleration {
+ if (tuiConfig?.scroll_acceleration?.enabled) {
+ return new MacOSScrollAccel()
+ }
+ if (tuiConfig?.scroll_speed) {
+ return new CustomSpeedScroll(tuiConfig.scroll_speed)
+ }
+
+ return new CustomSpeedScroll(3)
+}