fixed tmux system theme loading
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { createSignal } from "solid-js";
|
||||
import { useRenderer } from "@opentui/solid";
|
||||
import { Layout } from "./components/Layout";
|
||||
import { Navigation } from "./components/Navigation";
|
||||
import { TabNavigation } from "./components/TabNavigation";
|
||||
|
||||
@@ -9,7 +9,7 @@ import { generateSyntax, generateSubtleSyntax } from "../utils/syntax-highlighte
|
||||
import { resolveTerminalTheme, loadThemes } from "../utils/theme"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import { setupThemeSignalHandler, emitThemeChanged, emitThemeModeChanged } from "../utils/theme-observer"
|
||||
import type { RGBA, TerminalColors } from "@opentui/core"
|
||||
import { createTerminalPalette, type RGBA, type TerminalColors } from "@opentui/core"
|
||||
|
||||
type ThemeResolved = {
|
||||
primary: RGBA
|
||||
@@ -121,11 +121,58 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
||||
})
|
||||
}
|
||||
|
||||
function resolveSystemTheme() {
|
||||
renderer
|
||||
.getPalette({ size: 16 })
|
||||
.then((colors) => {
|
||||
if (!colors.palette[0]) {
|
||||
async function waitForCapabilities(timeoutMs = 300) {
|
||||
if (renderer.capabilities) return
|
||||
await new Promise<void>((resolve) => {
|
||||
let done = false
|
||||
const onCaps = () => {
|
||||
if (done) return
|
||||
done = true
|
||||
renderer.off("capabilities", onCaps)
|
||||
clearTimeout(timer)
|
||||
resolve()
|
||||
}
|
||||
const timer = setTimeout(() => {
|
||||
if (done) return
|
||||
done = true
|
||||
renderer.off("capabilities", onCaps)
|
||||
resolve()
|
||||
}, timeoutMs)
|
||||
renderer.on("capabilities", onCaps)
|
||||
})
|
||||
}
|
||||
|
||||
async function resolveSystemTheme() {
|
||||
if (process.env.TMUX) {
|
||||
await waitForCapabilities()
|
||||
}
|
||||
|
||||
let colors: TerminalColors | null = null
|
||||
|
||||
try {
|
||||
colors = await renderer.getPalette({ size: 16 })
|
||||
} catch {
|
||||
colors = null
|
||||
}
|
||||
|
||||
if (!colors?.palette?.[0] && process.env.TMUX) {
|
||||
const writeOut = (renderer as unknown as { writeOut?: (data: string | Buffer) => boolean }).writeOut
|
||||
const writeFn = typeof writeOut === "function" ? writeOut.bind(renderer) : process.stdout.write.bind(process.stdout)
|
||||
const detector = createTerminalPalette(process.stdin, process.stdout, writeFn, true)
|
||||
try {
|
||||
const tmuxColors = await detector.detect({ size: 16, timeout: 1200 })
|
||||
if (tmuxColors?.palette?.[0]) {
|
||||
colors = tmuxColors
|
||||
}
|
||||
} finally {
|
||||
detector.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
const hasPalette = Boolean(colors?.palette?.some((value) => Boolean(value)))
|
||||
const hasDefaultColors = Boolean(colors?.defaultBackground || colors?.defaultForeground)
|
||||
|
||||
if (!hasPalette && !hasDefaultColors) {
|
||||
// No system colors available, fall back to default
|
||||
// This happens when the terminal doesn't support OSC palette queries
|
||||
// (e.g., running inside tmux, or on unsupported terminals)
|
||||
@@ -139,6 +186,8 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (colors) {
|
||||
setStore(
|
||||
produce((draft) => {
|
||||
draft.system = colors
|
||||
@@ -147,18 +196,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
.catch(() => {
|
||||
// On error, fall back to default theme if using system
|
||||
if (store.active === "system") {
|
||||
setStore(
|
||||
produce((draft) => {
|
||||
draft.active = "opencode"
|
||||
draft.ready = true
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMount(init)
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { render } from "@opentui/solid"
|
||||
// Hack: Force TERM to tmux-256color when running in tmux to enable
|
||||
// correct palette detection in @opentui/core
|
||||
if (process.env.TMUX && !process.env.TERM?.includes("tmux")) {
|
||||
process.env.TERM = "tmux-256color"
|
||||
}
|
||||
|
||||
import { render, useRenderer } from "@opentui/solid"
|
||||
import { App } from "./App"
|
||||
import { ThemeProvider } from "./context/ThemeContext"
|
||||
import { ToastProvider, Toast } from "./ui/toast"
|
||||
@@ -6,7 +12,14 @@ import { KeybindProvider } from "./context/KeybindContext"
|
||||
import { DialogProvider } from "./ui/dialog"
|
||||
import { CommandProvider } from "./ui/command"
|
||||
|
||||
function RendererSetup(props: { children: unknown }) {
|
||||
const renderer = useRenderer()
|
||||
renderer.disableStdoutInterception()
|
||||
return props.children
|
||||
}
|
||||
|
||||
render(() => (
|
||||
<RendererSetup>
|
||||
<ToastProvider>
|
||||
<ThemeProvider mode="dark">
|
||||
<KeybindProvider>
|
||||
@@ -19,4 +32,5 @@ render(() => (
|
||||
</KeybindProvider>
|
||||
</ThemeProvider>
|
||||
</ToastProvider>
|
||||
</RendererSetup>
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user