mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-05 22:48:48 +00:00
parent
9bbe87f617
commit
b2b9432a7a
5 changed files with 48 additions and 61 deletions
|
|
@ -25,6 +25,7 @@ New minor release that introduces Wave's connected computing extensions. We've i
|
|||
- [bugfix] Presets directory was not loading correctly on Windows
|
||||
- [bugfix] Magnified blocks were not showing correct on startup
|
||||
- [bugfix] Window opacity and background color was not getting applied properly in all cases
|
||||
- [bugfix] Fix terminal theming when applying global defaults [#1287](https://github.com/wavetermdev/waveterm/issues/1287)
|
||||
- MacOS 10.15 (Catalina) is no longer supported
|
||||
- Other bug fixes, docs improvements, and dependency bumps
|
||||
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ function useBlockMetaKeyAtom<T extends keyof MetaType>(blockId: string, key: T):
|
|||
|
||||
const settingsAtomCache = new Map<string, Atom<any>>();
|
||||
|
||||
function makeOverrideConfigAtom<T extends keyof SettingsType>(blockId: string, key: T): Atom<SettingsType[T]> {
|
||||
function getOverrideConfigAtom<T extends keyof SettingsType>(blockId: string, key: T): Atom<SettingsType[T]> {
|
||||
const blockCache = getSingleBlockAtomCache(blockId);
|
||||
const overrideAtomName = "#settingsoverride-" + key;
|
||||
let overrideAtom = blockCache.get(overrideAtomName);
|
||||
|
|
@ -271,7 +271,7 @@ function makeOverrideConfigAtom<T extends keyof SettingsType>(blockId: string, k
|
|||
}
|
||||
|
||||
function useOverrideConfigAtom<T extends keyof SettingsType>(blockId: string, key: T): SettingsType[T] {
|
||||
return useAtomValue(makeOverrideConfigAtom(blockId, key));
|
||||
return useAtomValue(getOverrideConfigAtom(blockId, key));
|
||||
}
|
||||
|
||||
function getSettingsKeyAtom<T extends keyof SettingsType>(key: T): Atom<SettingsType[T]> {
|
||||
|
|
@ -636,6 +636,7 @@ export {
|
|||
getConnStatusAtom,
|
||||
getHostName,
|
||||
getObjectId,
|
||||
getOverrideConfigAtom,
|
||||
getSettingsKeyAtom,
|
||||
getUserName,
|
||||
globalStore,
|
||||
|
|
@ -643,7 +644,6 @@ export {
|
|||
initGlobalWaveEventSubs,
|
||||
isDev,
|
||||
loadConnStatus,
|
||||
makeOverrideConfigAtom,
|
||||
openLink,
|
||||
PLATFORM,
|
||||
pushFlashError,
|
||||
|
|
|
|||
|
|
@ -11,14 +11,16 @@ import { DefaultRouter, TabRpcClient } from "@/app/store/wshrpcutil";
|
|||
import { TermWshClient } from "@/app/view/term/term-wsh";
|
||||
import { VDomModel } from "@/app/view/vdom/vdom-model";
|
||||
import {
|
||||
WOS,
|
||||
atoms,
|
||||
getBlockComponentModel,
|
||||
getBlockMetaKeyAtom,
|
||||
getConnStatusAtom,
|
||||
getOverrideConfigAtom,
|
||||
getSettingsKeyAtom,
|
||||
globalStore,
|
||||
useBlockAtom,
|
||||
useSettingsPrefixAtom,
|
||||
WOS,
|
||||
} from "@/store/global";
|
||||
import * as services from "@/store/services";
|
||||
import * as keyutil from "@/util/keyutil";
|
||||
|
|
@ -28,7 +30,7 @@ import * as jotai from "jotai";
|
|||
import * as React from "react";
|
||||
import { TermStickers } from "./termsticker";
|
||||
import { TermThemeUpdater } from "./termtheme";
|
||||
import { computeTheme } from "./termutil";
|
||||
import { computeTheme, DefaultTermTheme } from "./termutil";
|
||||
import { TermWrap } from "./termwrap";
|
||||
import "./xterm.css";
|
||||
|
||||
|
|
@ -138,16 +140,17 @@ class TermViewModel {
|
|||
}
|
||||
return true;
|
||||
});
|
||||
this.termThemeNameAtom = useBlockAtom(blockId, "termthemeatom", () => {
|
||||
return jotai.atom<string>((get) => {
|
||||
return get(getOverrideConfigAtom(this.blockId, "term:theme")) ?? DefaultTermTheme;
|
||||
});
|
||||
});
|
||||
this.blockBg = jotai.atom((get) => {
|
||||
const blockData = get(this.blockAtom);
|
||||
const fullConfig = get(atoms.fullConfigAtom);
|
||||
let themeName: string = get(getSettingsKeyAtom("term:theme"));
|
||||
if (blockData?.meta?.["term:theme"]) {
|
||||
themeName = blockData.meta["term:theme"];
|
||||
}
|
||||
const theme = computeTheme(fullConfig, themeName);
|
||||
if (theme != null && theme.background != null) {
|
||||
return { bg: theme.background };
|
||||
const themeName = get(this.termThemeNameAtom);
|
||||
const [_, bgcolor] = computeTheme(fullConfig, themeName);
|
||||
if (bgcolor != null) {
|
||||
return { bg: bgcolor };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
|
@ -169,13 +172,6 @@ class TermViewModel {
|
|||
return rtnFontSize;
|
||||
});
|
||||
});
|
||||
this.termThemeNameAtom = useBlockAtom(blockId, "termthemeatom", () => {
|
||||
return jotai.atom<string>((get) => {
|
||||
const blockData = get(this.blockAtom);
|
||||
const settingsKeyAtom = getSettingsKeyAtom("term:theme");
|
||||
return blockData?.meta?.["term:theme"] ?? get(settingsKeyAtom) ?? "default-dark";
|
||||
});
|
||||
});
|
||||
this.noPadding = jotai.atom(true);
|
||||
this.endIconButtons = jotai.atom((get) => {
|
||||
const blockData = get(this.blockAtom);
|
||||
|
|
@ -329,7 +325,7 @@ class TermViewModel {
|
|||
const fullConfig = globalStore.get(atoms.fullConfigAtom);
|
||||
const termThemes = fullConfig?.termthemes ?? {};
|
||||
const termThemeKeys = Object.keys(termThemes);
|
||||
const curThemeName = globalStore.get(this.termThemeNameAtom);
|
||||
const curThemeName = globalStore.get(getBlockMetaKeyAtom(this.blockId, "term:theme"));
|
||||
const defaultFontSize = globalStore.get(getSettingsKeyAtom("term:fontsize")) ?? 12;
|
||||
const blockData = globalStore.get(this.blockAtom);
|
||||
const overrideFontSize = blockData?.meta?.["term:fontsize"];
|
||||
|
|
@ -346,6 +342,12 @@ class TermViewModel {
|
|||
click: () => this.setTerminalTheme(themeName),
|
||||
};
|
||||
});
|
||||
submenu.unshift({
|
||||
label: "Default",
|
||||
type: "checkbox",
|
||||
checked: curThemeName == null,
|
||||
click: () => this.setTerminalTheme(null),
|
||||
});
|
||||
const fontSizeSubMenu: ContextMenuItem[] = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18].map(
|
||||
(fontSize: number) => {
|
||||
return {
|
||||
|
|
@ -551,9 +553,8 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
|
|||
|
||||
React.useEffect(() => {
|
||||
const fullConfig = globalStore.get(atoms.fullConfigAtom);
|
||||
const termTheme = computeTheme(fullConfig, blockData?.meta?.["term:theme"]);
|
||||
const themeCopy = { ...termTheme };
|
||||
themeCopy.background = "#00000000";
|
||||
const termThemeName = globalStore.get(model.termThemeNameAtom);
|
||||
const [termTheme, _] = computeTheme(fullConfig, termThemeName);
|
||||
let termScrollback = 1000;
|
||||
if (termSettings?.["term:scrollback"]) {
|
||||
termScrollback = Math.floor(termSettings["term:scrollback"]);
|
||||
|
|
@ -572,7 +573,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
|
|||
blockId,
|
||||
connectElemRef.current,
|
||||
{
|
||||
theme: themeCopy,
|
||||
theme: termTheme,
|
||||
fontSize: termFontSize,
|
||||
fontFamily: termSettings?.["term:fontfamily"] ?? "Hack",
|
||||
drawBoldTextInBrightColors: false,
|
||||
|
|
@ -650,7 +651,7 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
|
|||
return (
|
||||
<div className={clsx("view-term", "term-mode-" + termMode)} ref={viewRef}>
|
||||
<TermResyncHandler blockId={blockId} model={model} />
|
||||
<TermThemeUpdater blockId={blockId} termRef={termRef} />
|
||||
<TermThemeUpdater blockId={blockId} model={model} termRef={termRef} />
|
||||
<TermStickers config={stickerConfig} />
|
||||
<TermToolbarVDomNode key="vdom-toolbar" blockId={blockId} model={model} />
|
||||
<TermVDomNode key="vdom" blockId={blockId} model={model} />
|
||||
|
|
@ -659,4 +660,4 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
export { TermViewModel, TerminalView, makeTerminalModel };
|
||||
export { makeTerminalModel, TerminalView, TermViewModel };
|
||||
|
|
|
|||
|
|
@ -1,41 +1,28 @@
|
|||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TermViewModel } from "@/app/view/term/term";
|
||||
import { computeTheme } from "@/app/view/term/termutil";
|
||||
import { TermWrap } from "@/app/view/term/termwrap";
|
||||
import { atoms, WOS } from "@/store/global";
|
||||
import * as util from "@/util/util";
|
||||
import { atoms } from "@/store/global";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { useEffect } from "react";
|
||||
|
||||
interface TermThemeProps {
|
||||
blockId: string;
|
||||
termRef: React.RefObject<TermWrap>;
|
||||
model: TermViewModel;
|
||||
}
|
||||
|
||||
const TermThemeUpdater = ({ blockId, termRef }: TermThemeProps) => {
|
||||
const TermThemeUpdater = ({ blockId, model, termRef }: TermThemeProps) => {
|
||||
const fullConfig = useAtomValue(atoms.fullConfigAtom);
|
||||
const termthemes = fullConfig?.termthemes;
|
||||
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
|
||||
let defaultThemeName = "default-dark";
|
||||
let themeName = blockData.meta?.["term:theme"] ?? "default-dark";
|
||||
|
||||
const defaultTheme: TermThemeType = termthemes?.[defaultThemeName] || ({} as any);
|
||||
const theme: TermThemeType = termthemes?.[themeName] || ({} as any);
|
||||
|
||||
const blockTermTheme = useAtomValue(model.termThemeNameAtom);
|
||||
const [theme, _] = computeTheme(fullConfig, blockTermTheme);
|
||||
useEffect(() => {
|
||||
const combinedTheme = { ...defaultTheme };
|
||||
for (const key in theme) {
|
||||
if (!util.isBlank(theme[key])) {
|
||||
combinedTheme[key] = theme[key];
|
||||
}
|
||||
}
|
||||
if (termRef.current?.terminal) {
|
||||
let themeCopy = { ...combinedTheme };
|
||||
themeCopy.background = "#00000000";
|
||||
termRef.current.terminal.options.theme = themeCopy;
|
||||
termRef.current.terminal.options.theme = theme;
|
||||
}
|
||||
}, [defaultTheme, theme]);
|
||||
|
||||
}, [theme]);
|
||||
return null;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as util from "@/util/util";
|
||||
export const DefaultTermTheme = "default-dark";
|
||||
|
||||
function computeTheme(fullConfig: FullConfigType, themeName: string): TermThemeType {
|
||||
let defaultThemeName = "default-dark";
|
||||
themeName = themeName ?? "default-dark";
|
||||
const defaultTheme: TermThemeType = fullConfig?.termthemes?.[defaultThemeName] || ({} as any);
|
||||
const theme: TermThemeType = fullConfig?.termthemes?.[themeName] || ({} as any);
|
||||
const combinedTheme = { ...defaultTheme };
|
||||
for (const key in theme) {
|
||||
if (!util.isBlank(theme[key])) {
|
||||
combinedTheme[key] = theme[key];
|
||||
}
|
||||
// returns (theme, bgcolor)
|
||||
function computeTheme(fullConfig: FullConfigType, themeName: string): [TermThemeType, string] {
|
||||
let theme: TermThemeType = fullConfig?.termthemes?.[themeName];
|
||||
if (theme == null) {
|
||||
theme = fullConfig?.termthemes?.[DefaultTermTheme] || ({} as any);
|
||||
}
|
||||
return combinedTheme;
|
||||
const themeCopy = { ...theme };
|
||||
let bgcolor = themeCopy.background;
|
||||
themeCopy.background = "#00000000";
|
||||
return [themeCopy, bgcolor];
|
||||
}
|
||||
|
||||
export { computeTheme };
|
||||
|
|
|
|||
Loading…
Reference in a new issue