feat(theme): add background image dim scrim slider
New terminal.backgroundImageDim setting (0-90%, default 0 = off). A black scrim layer sits between the background image and the xterm screen, so bright wallpapers stay readable at any opacity: unlike the opacity slider (which blends the image toward the dark dock base), the scrim darkens the image while preserving its saturation, and the raised minimumContrastRatio (4.5) keeps lifted text legible on top. - settings: backgroundImageDim with deepMerge type-fallback sanitize - TerminalView: render .term-bg-dim only when image set and dim > 0 - ThemeSettingsTab: slider follows the existing draft + onChangeComplete pattern (no settings writes while dragging) - i18n: settings.theme.backgroundImageDim(+Desc) in zh-CN/zh-TW/en/ja - AGENTS.md: document the third image-mode invariant
This commit is contained in:
1 parent
e16c860c7a
commit
6c04f0e8c1
9 files changed
+53
-2
No files matched your search
@@ -32,6 +32,7 @@ export function ThemeSettingsTab({
|
||||
const setCustomThemes = useSettingsStore((s) => s.setCustomThemes)
|
||||
const activeTheme = useResolvedTheme()
|
||||
const [opacityDraft, setOpacityDraft] = useState<number | null>(null)
|
||||
const [dimDraft, setDimDraft] = useState<number | null>(null)
|
||||
|
||||
const themeCards = useMemo(
|
||||
() => [...BUILTIN_THEMES, ...settings.customThemes],
|
||||
@@ -90,6 +91,26 @@ export function ThemeSettingsTab({
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{settings.terminal.backgroundImage !== '' && (
|
||||
<div className="theme-accent-row">
|
||||
<div>
|
||||
<div className="settings-block-label">{t('settings.theme.backgroundImageDim')}</div>
|
||||
<div className="settings-block-hint">{t('settings.theme.backgroundImageDimDesc')}</div>
|
||||
</div>
|
||||
<Slider
|
||||
style={{ width: 200 }}
|
||||
min={0}
|
||||
max={90}
|
||||
step={5}
|
||||
value={dimDraft ?? settings.terminal.backgroundImageDim}
|
||||
onChange={(v) => setDimDraft(v)}
|
||||
onChangeComplete={(v) => {
|
||||
setDimDraft(null)
|
||||
void updateTerminal({ backgroundImageDim: v })
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="theme-accent-row">
|
||||
<div>
|
||||
<div className="settings-block-label">{t('settings.theme.accent')}</div>
|
||||
|
||||
@@ -1400,6 +1400,14 @@ export const TerminalView: ForwardRefExoticComponent<TerminalViewProps & { ref?:
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{settings.terminal.backgroundImage !== '' && settings.terminal.backgroundImageDim > 0 && (
|
||||
<div
|
||||
className="term-bg-dim"
|
||||
style={{
|
||||
opacity: Math.min(90, Math.max(0, settings.terminal.backgroundImageDim)) / 100
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{dead && (
|
||||
<div className="term-dead-mask">
|
||||
<div>{t('terminal.dead.message', { code: exitCode })}</div>
|
||||
|
||||
@@ -380,6 +380,17 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Black scrim between the background image and the xterm screen: dims the
|
||||
image without washing it out (unlike opacity, which blends toward the dark
|
||||
dock base), so bright images stay readable at any opacity. */
|
||||
.term-bg-dim {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
background: #000;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.terminal-view-dock > .xterm {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
Reference in new issue
Block a user