From 64084d3e27388377c817b557aa2cdc48399775ac Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Thu, 10 Oct 2024 13:12:42 -0400 Subject: [PATCH] Remove global.ts dependency from emain (#1003) Removes global atoms dependency from emain by moving WOS to grab the globalAtoms from window, if present. Also removes interdependency between wshrpcutil and wps Also adds showmenubar setting for Windows and Linux --- emain/emain.ts | 5 +---- frontend/app/store/global.ts | 4 ++-- frontend/app/store/jotaiStore.ts | 3 +++ frontend/app/store/wos.ts | 6 +++--- frontend/app/store/wps.ts | 2 +- frontend/app/store/ws.ts | 30 +++++++++++++++++++++++++++++- frontend/app/store/wshrouter.ts | 2 +- frontend/app/store/wshrpcutil.ts | 18 +++--------------- frontend/app/tab/tabbar.tsx | 4 +++- frontend/app/view/term/termwrap.ts | 3 ++- frontend/types/gotypes.d.ts | 1 + pkg/wconfig/metaconsts.go | 1 + pkg/wconfig/settingsconfig.go | 1 + 13 files changed, 51 insertions(+), 29 deletions(-) create mode 100644 frontend/app/store/jotaiStore.ts 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"`