fix(tui): apply scroll configuration uniformly across all scrollboxes (#14735)

pull/20551/head^2
Luke Parker 2026-04-02 09:15:19 +10:00 committed by GitHub
parent 1fcfb69bf7
commit f7f41dc3a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 49 additions and 22 deletions

View File

@ -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>

View File

@ -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()}

View File

@ -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) {

View File

@ -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,

View File

@ -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,

View File

@ -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()}
>

View File

@ -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)
}