diff --git a/emain/emain.ts b/emain/emain.ts index 9f47b4033..9b5808877 100644 --- a/emain/emain.ts +++ b/emain/emain.ts @@ -13,7 +13,6 @@ import { Readable } from "stream"; import { debounce } from "throttle-debounce"; import * as util from "util"; import winston from "winston"; -import { initGlobal } from "../frontend/app/store/global"; import * as services from "../frontend/app/store/services"; import { initElectronWshrpc, shutdownWshrpc } from "../frontend/app/store/wshrpcutil"; import { WSServerEndpointVarName, WebServerEndpointVarName, getWebServerEndpoint } from "../frontend/util/endpoints"; @@ -108,8 +107,6 @@ if (isDev) { console.log("waveterm-app WAVETERM_DEV set"); } -initGlobal({ windowId: null, clientId: null, platform: unamePlatform, environment: "electron" }); - function getWindowForEvent(event: Electron.IpcMainEvent): Electron.BrowserWindow { const windowId = event.sender.id; return electron.BrowserWindow.fromId(windowId); @@ -369,7 +366,7 @@ function createBrowserWindow(clientId: string, waveWindow: WaveWindow, fullConfi webviewTag: true, }, show: false, - autoHideMenuBar: true, + autoHideMenuBar: !settings?.["window:showmenubar"], }; const isTransparent = settings?.["window:transparent"] ?? false; const isBlur = !isTransparent && (settings?.["window:blur"] ?? false); diff --git a/frontend/app/store/global.ts b/frontend/app/store/global.ts index 65abf14e7..7309e77b3 100644 --- a/frontend/app/store/global.ts +++ b/frontend/app/store/global.ts @@ -11,14 +11,14 @@ import { import { getWebServerEndpoint } from "@/util/endpoints"; import { fetch } from "@/util/fetchutil"; import { getPrefixedSettings, isBlank } from "@/util/util"; -import { atom, Atom, createStore, PrimitiveAtom, useAtomValue } from "jotai"; +import { atom, Atom, PrimitiveAtom, useAtomValue } from "jotai"; +import { globalStore } from "./jotaiStore"; import { modalsModel } from "./modalmodel"; import { ClientService, ObjectService } from "./services"; import * as WOS from "./wos"; import { getFileSubject, waveEventSubscribe } from "./wps"; let PLATFORM: NodeJS.Platform = "darwin"; -const globalStore = createStore(); let atoms: GlobalAtomsType; let globalEnvironment: "electron" | "renderer"; const blockComponentModelMap = new Map(); diff --git a/frontend/app/store/jotaiStore.ts b/frontend/app/store/jotaiStore.ts new file mode 100644 index 000000000..d6bf8e24a --- /dev/null +++ b/frontend/app/store/jotaiStore.ts @@ -0,0 +1,3 @@ +import { createStore } from "jotai"; + +export const globalStore = createStore(); diff --git a/frontend/app/store/wos.ts b/frontend/app/store/wos.ts index eb1b6bc4b..6b2c01c12 100644 --- a/frontend/app/store/wos.ts +++ b/frontend/app/store/wos.ts @@ -7,7 +7,7 @@ import { getWebServerEndpoint } from "@/util/endpoints"; import { fetch } from "@/util/fetchutil"; import { atom, Atom, Getter, PrimitiveAtom, Setter, useAtomValue } from "jotai"; import { useEffect } from "react"; -import { atoms, globalStore } from "./global"; +import { globalStore } from "./jotaiStore"; import { ObjectService } from "./services"; type WaveObjectDataItemType = { @@ -79,8 +79,8 @@ function debugLogBackendCall(methodName: string, durationStr: string, args: any[ function callBackendService(service: string, method: string, args: any[], noUIContext?: boolean): Promise { const startTs = Date.now(); let uiContext: UIContext = null; - if (!noUIContext) { - uiContext = globalStore.get(atoms.uiContext); + if (!noUIContext && globalThis.window != null) { + uiContext = globalStore.get(((window as any).globalAtoms as GlobalAtomsType).uiContext); } const waveCall: WebCallType = { service: service, diff --git a/frontend/app/store/wps.ts b/frontend/app/store/wps.ts index 28dc2cf55..dcc06f7b0 100644 --- a/frontend/app/store/wps.ts +++ b/frontend/app/store/wps.ts @@ -1,6 +1,6 @@ import { isBlank } from "@/util/util"; import { Subject } from "rxjs"; -import { sendRawRpcMessage } from "./wshrpcutil"; +import { sendRawRpcMessage } from "./ws"; type WaveEventSubject = { handler: (event: WaveEvent) => void; diff --git a/frontend/app/store/ws.ts b/frontend/app/store/ws.ts index 81a223662..1b11ab326 100644 --- a/frontend/app/store/ws.ts +++ b/frontend/app/store/ws.ts @@ -218,4 +218,32 @@ class WSControl { } } -export { WSControl, addWSReconnectHandler, removeWSReconnectHandler, type ElectronOverrideOpts }; +let globalWS: WSControl; +function initGlobalWS( + baseHostPort: string, + windowId: string, + messageCallback: WSEventCallback, + electronOverrideOpts?: ElectronOverrideOpts +) { + globalWS = new WSControl(baseHostPort, windowId, messageCallback, electronOverrideOpts); +} + +function sendRawRpcMessage(msg: RpcMessage) { + const wsMsg: WSRpcCommand = { wscommand: "rpc", message: msg }; + sendWSCommand(wsMsg); +} + +function sendWSCommand(cmd: WSCommandType) { + globalWS?.pushMessage(cmd); +} + +export { + WSControl, + addWSReconnectHandler, + globalWS, + initGlobalWS, + removeWSReconnectHandler, + sendRawRpcMessage, + sendWSCommand, + type ElectronOverrideOpts, +}; diff --git a/frontend/app/store/wshrouter.ts b/frontend/app/store/wshrouter.ts index 2679c9d10..9acb0442e 100644 --- a/frontend/app/store/wshrouter.ts +++ b/frontend/app/store/wshrouter.ts @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import { handleWaveEvent } from "@/app/store/wps"; +import * as util from "@/util/util"; import debug from "debug"; -import * as util from "../../util/util"; const dlog = debug("wave:router"); diff --git a/frontend/app/store/wshrpcutil.ts b/frontend/app/store/wshrpcutil.ts index 487fc2831..868725ca6 100644 --- a/frontend/app/store/wshrpcutil.ts +++ b/frontend/app/store/wshrpcutil.ts @@ -5,9 +5,8 @@ import { wpsReconnectHandler } from "@/app/store/wps"; import { WshClient } from "@/app/store/wshclient"; import { makeWindowRouteId, WshRouter } from "@/app/store/wshrouter"; import { getWSServerEndpoint } from "@/util/endpoints"; -import { addWSReconnectHandler, ElectronOverrideOpts, WSControl } from "./ws"; +import { addWSReconnectHandler, ElectronOverrideOpts, globalWS, initGlobalWS, WSControl } from "./ws"; -let globalWS: WSControl; let DefaultRouter: WshRouter; let WindowRpcClient: WshClient; @@ -91,11 +90,6 @@ function sendRpcCommand( return rtnGen; } -function sendRawRpcMessage(msg: RpcMessage) { - const wsMsg: WSRpcCommand = { wscommand: "rpc", message: msg }; - sendWSCommand(wsMsg); -} - async function consumeGenerator(gen: AsyncGenerator) { let idx = 0; try { @@ -119,7 +113,7 @@ function initElectronWshrpc(electronClient: WshClient, eoOpts: ElectronOverrideO const handleFn = (event: WSEventType) => { DefaultRouter.recvRpcMessage(event.data); }; - globalWS = new WSControl(getWSServerEndpoint(), "electron", handleFn, eoOpts); + initGlobalWS(getWSServerEndpoint(), "electron", handleFn, eoOpts); globalWS.connectNow("connectWshrpc"); DefaultRouter.registerRoute(electronClient.routeId, electronClient); addWSReconnectHandler(() => { @@ -137,7 +131,7 @@ function initWshrpc(windowId: string): WSControl { const handleFn = (event: WSEventType) => { DefaultRouter.recvRpcMessage(event.data); }; - globalWS = new WSControl(getWSServerEndpoint(), windowId, handleFn); + initGlobalWS(getWSServerEndpoint(), windowId, handleFn); globalWS.connectNow("connectWshrpc"); WindowRpcClient = new WshClient(makeWindowRouteId(windowId)); DefaultRouter.registerRoute(WindowRpcClient.routeId, WindowRpcClient); @@ -148,10 +142,6 @@ function initWshrpc(windowId: string): WSControl { return globalWS; } -function sendWSCommand(cmd: WSCommandType) { - globalWS?.pushMessage(cmd); -} - class UpstreamWshRpcProxy implements AbstractWshClient { recvRpcMessage(msg: RpcMessage): void { const wsMsg: WSRpcCommand = { wscommand: "rpc", message: msg }; @@ -163,10 +153,8 @@ export { DefaultRouter, initElectronWshrpc, initWshrpc, - sendRawRpcMessage, sendRpcCommand, sendRpcResponse, - sendWSCommand, shutdownWshrpc, WindowRpcClient, }; diff --git a/frontend/app/tab/tabbar.tsx b/frontend/app/tab/tabbar.tsx index 51482fc4f..f5111f2dc 100644 --- a/frontend/app/tab/tabbar.tsx +++ b/frontend/app/tab/tabbar.tsx @@ -74,6 +74,8 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => { const isFullScreen = useAtomValue(atoms.isFullScreen); + const settings = useAtomValue(atoms.settingsAtom); + let prevDelta: number; let prevDragDirection: string; @@ -469,7 +471,7 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => { ) : undefined; const appMenuButton = - PLATFORM !== "darwin" ? ( + PLATFORM !== "darwin" && !settings["window:showmenubar"] ? (
diff --git a/frontend/app/view/term/termwrap.ts b/frontend/app/view/term/termwrap.ts index 7e441d9d4..eb098b0f9 100644 --- a/frontend/app/view/term/termwrap.ts +++ b/frontend/app/view/term/termwrap.ts @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 import { getFileSubject } from "@/app/store/wps"; +import { sendWSCommand } from "@/app/store/ws"; import { RpcApi } from "@/app/store/wshclientapi"; -import { WindowRpcClient, sendWSCommand } from "@/app/store/wshrpcutil"; +import { WindowRpcClient } from "@/app/store/wshrpcutil"; import { PLATFORM, WOS, atoms, fetchWaveFile, globalStore, openLink } from "@/store/global"; import * as services from "@/store/services"; import * as util from "@/util/util"; diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 0fcdc6fba..91d211cd9 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -466,6 +466,7 @@ declare global { "window:bgcolor"?: string; "window:reducedmotion"?: boolean; "window:tilegapsize"?: number; + "window:showmenubar"?: boolean; "window:nativetitlebar"?: boolean; "window:disablehardwareacceleration"?: boolean; "telemetry:*"?: boolean; diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go index efd577f12..a2b469bd2 100644 --- a/pkg/wconfig/metaconsts.go +++ b/pkg/wconfig/metaconsts.go @@ -55,6 +55,7 @@ const ( ConfigKey_WindowBgColor = "window:bgcolor" ConfigKey_WindowReducedMotion = "window:reducedmotion" ConfigKey_WindowTileGapSize = "window:tilegapsize" + ConfigKey_WindowShowMenuBar = "window:showmenubar" ConfigKey_WindowNativeTitleBar = "window:nativetitlebar" ConfigKey_WindowDisableHardwareAcceleration = "window:disablehardwareacceleration" diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index a856bd753..7bf196eaa 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -89,6 +89,7 @@ type SettingsType struct { WindowBgColor string `json:"window:bgcolor,omitempty"` WindowReducedMotion bool `json:"window:reducedmotion,omitempty"` WindowTileGapSize *int64 `json:"window:tilegapsize,omitempty"` + WindowShowMenuBar bool `json:"window:showmenubar,omitempty"` WindowNativeTitleBar bool `json:"window:nativetitlebar,omitempty"` WindowDisableHardwareAcceleration bool `json:"window:disablehardwareacceleration,omitempty"`