Remove barriers to supporting multiple windows (#647)

This commit is contained in:
Evan Simkowitz 2024-05-03 13:41:53 -07:00 committed by GitHub
parent 9b1f5a2abd
commit 46b9c22f10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -34,7 +34,9 @@ let wasActive = true;
let wasInFg = true; let wasInFg = true;
let currentGlobalShortcut: string | null = null; let currentGlobalShortcut: string | null = null;
let initialClientData: ClientDataType = null; let initialClientData: ClientDataType = null;
let MainWindow: Electron.BrowserWindow | null = null; let windows: Windows = {};
interface Windows extends Record<string, Electron.BrowserWindow> {}
checkPromptMigrate(); checkPromptMigrate();
ensureDir(waveHome); ensureDir(waveHome);
@ -200,14 +202,15 @@ function readAuthKey(): string {
} }
const reloadAcceleratorKey = unamePlatform == "darwin" ? "Option+R" : "Super+R"; const reloadAcceleratorKey = unamePlatform == "darwin" ? "Option+R" : "Super+R";
const cmdOrAlt = process.platform === "darwin" ? "Cmd" : "Alt"; const cmdOrAlt = process.platform === "darwin" ? "Cmd" : "Alt";
let viewSubMenu: Electron.MenuItemConstructorOptions[] = []; let viewSubMenu: Electron.MenuItemConstructorOptions[] = [];
viewSubMenu.push({ role: "reload", accelerator: reloadAcceleratorKey }); viewSubMenu.push({ role: "reload", accelerator: reloadAcceleratorKey });
viewSubMenu.push({ role: "toggleDevTools" }); viewSubMenu.push({ role: "toggleDevTools" });
if (isDev) { if (isDev) {
viewSubMenu.push({ viewSubMenu.push({
label: "Toggle Dev UI", label: "Toggle Dev UI",
click: () => { click: (_, window) => {
MainWindow?.webContents.send("toggle-devui"); window?.webContents.send("toggle-devui");
}, },
}); });
} }
@ -215,36 +218,33 @@ viewSubMenu.push({ type: "separator" });
viewSubMenu.push({ viewSubMenu.push({
label: "Actual Size", label: "Actual Size",
accelerator: cmdOrAlt + "+0", accelerator: cmdOrAlt + "+0",
click: () => { click: (_, window) => {
if (MainWindow == null) { window?.webContents.setZoomFactor(1);
return; window?.webContents.send("zoom-changed");
}
MainWindow.webContents.setZoomFactor(1);
MainWindow.webContents.send("zoom-changed");
}, },
}); });
viewSubMenu.push({ viewSubMenu.push({
label: "Zoom In", label: "Zoom In",
accelerator: cmdOrAlt + "+Plus", accelerator: cmdOrAlt + "+Plus",
click: () => { click: (_, window) => {
if (MainWindow == null) { if (window == null) {
return; return;
} }
const zoomFactor = MainWindow.webContents.getZoomFactor(); const zoomFactor = window.webContents.getZoomFactor();
MainWindow.webContents.setZoomFactor(zoomFactor * 1.1); window.webContents.setZoomFactor(zoomFactor * 1.1);
MainWindow.webContents.send("zoom-changed"); window.webContents.send("zoom-changed");
}, },
}); });
viewSubMenu.push({ viewSubMenu.push({
label: "Zoom Out", label: "Zoom Out",
accelerator: cmdOrAlt + "+-", accelerator: cmdOrAlt + "+-",
click: () => { click: (_, window) => {
if (MainWindow == null) { if (window == null) {
return; return;
} }
const zoomFactor = MainWindow.webContents.getZoomFactor(); const zoomFactor = window.webContents.getZoomFactor();
MainWindow.webContents.setZoomFactor(zoomFactor / 1.1); window.webContents.setZoomFactor(zoomFactor / 1.1);
MainWindow.webContents.send("zoom-changed"); window.webContents.send("zoom-changed");
}, },
}); });
viewSubMenu.push({ type: "separator" }); viewSubMenu.push({ type: "separator" });
@ -255,8 +255,8 @@ const menuTemplate: Electron.MenuItemConstructorOptions[] = [
submenu: [ submenu: [
{ {
label: "About Wave Terminal", label: "About Wave Terminal",
click: () => { click: (_, window) => {
MainWindow?.webContents.send("menu-item-about"); window?.webContents.send("menu-item-about");
}, },
}, },
{ type: "separator" }, { type: "separator" },
@ -325,7 +325,10 @@ function shFrameNavHandler(event: Electron.Event<Electron.WebContentsWillFrameNa
console.log("frame navigation canceled"); console.log("frame navigation canceled");
} }
function createMainWindow(clientData: ClientDataType | null): Electron.BrowserWindow { function createWindow(id: string, clientData: ClientDataType | null): Electron.BrowserWindow {
if (windows[id]) {
console.error(`createWindow called for existing window ${id}`);
}
const bounds = calcBounds(clientData); const bounds = calcBounds(clientData);
setKeyUtilPlatform(platform()); setKeyUtilPlatform(platform());
const win = new electron.BrowserWindow({ const win = new electron.BrowserWindow({
@ -374,11 +377,17 @@ function createMainWindow(clientData: ClientDataType | null): Electron.BrowserWi
wasActive = true; wasActive = true;
}); });
win.on("close", () => { win.on("close", () => {
MainWindow = null; delete windows[id];
}); });
win.webContents.on("zoom-changed", (e) => { win.webContents.on("zoom-changed", (e) => {
win.webContents.send("zoom-changed"); win.webContents.send("zoom-changed");
}); });
windows[id] = win;
return win;
}
function createMainWindow(clientData: ClientDataType | null) {
const win = createWindow("main", clientData);
win.webContents.setWindowOpenHandler(({ url, frameName }) => { win.webContents.setWindowOpenHandler(({ url, frameName }) => {
if (url.startsWith("https://docs.waveterm.dev/")) { if (url.startsWith("https://docs.waveterm.dev/")) {
console.log("openExternal docs", url); console.log("openExternal docs", url);
@ -399,8 +408,6 @@ function createMainWindow(clientData: ClientDataType | null): Electron.BrowserWi
console.log("window-open denied", url); console.log("window-open denied", url);
return { action: "deny" }; return { action: "deny" };
}); });
return win;
} }
function mainResizeHandler(_: any, win: Electron.BrowserWindow) { function mainResizeHandler(_: any, win: Electron.BrowserWindow) {
@ -474,8 +481,9 @@ app.on("window-all-closed", () => {
}); });
electron.ipcMain.on("toggle-developer-tools", (event) => { electron.ipcMain.on("toggle-developer-tools", (event) => {
if (MainWindow != null) { const window = getWindowForEvent(event);
MainWindow.webContents.toggleDevTools(); if (window != null) {
window.webContents.toggleDevTools();
} }
event.returnValue = true; event.returnValue = true;
}); });
@ -487,8 +495,8 @@ function convertMenuDefArrToMenu(menuDefArr: ElectronContextMenuItem[]): electro
role: menuDef.role as any, role: menuDef.role as any,
label: menuDef.label, label: menuDef.label,
type: menuDef.type, type: menuDef.type,
click: () => { click: (_, window) => {
MainWindow?.webContents.send("contextmenu-click", menuDef.id); window?.webContents.send("contextmenu-click", menuDef.id);
}, },
}; };
if (menuDef.submenu != null) { if (menuDef.submenu != null) {
@ -500,6 +508,11 @@ function convertMenuDefArrToMenu(menuDefArr: ElectronContextMenuItem[]): electro
return electron.Menu.buildFromTemplate(menuItems); return electron.Menu.buildFromTemplate(menuItems);
} }
function getWindowForEvent(event: Electron.IpcMainEvent): Electron.BrowserWindow {
const windowId = event.sender.id;
return electron.BrowserWindow.fromId(windowId);
}
electron.ipcMain.on("contextmenu-show", (event, menuDefArr: ElectronContextMenuItem[], { x, y }) => { electron.ipcMain.on("contextmenu-show", (event, menuDefArr: ElectronContextMenuItem[], { x, y }) => {
if (menuDefArr == null || menuDefArr.length == 0) { if (menuDefArr == null || menuDefArr.length == 0) {
return; return;
@ -510,8 +523,9 @@ electron.ipcMain.on("contextmenu-show", (event, menuDefArr: ElectronContextMenuI
}); });
electron.ipcMain.on("hide-window", (event) => { electron.ipcMain.on("hide-window", (event) => {
if (MainWindow != null) { const window = getWindowForEvent(event);
MainWindow.hide(); if (window) {
window.hide();
} }
event.returnValue = true; event.returnValue = true;
}); });
@ -552,8 +566,9 @@ electron.ipcMain.on("restart-server", (event) => {
}); });
electron.ipcMain.on("reload-window", (event) => { electron.ipcMain.on("reload-window", (event) => {
if (MainWindow != null) { const window = getWindowForEvent(event);
MainWindow.reload(); if (window) {
window.reload();
} }
event.returnValue = true; event.returnValue = true;
}); });
@ -592,9 +607,9 @@ electron.ipcMain.on("set-nativethemesource", (event, themeSource: "system" | "li
}); });
electron.nativeTheme.on("updated", () => { electron.nativeTheme.on("updated", () => {
if (MainWindow != null) { electron.BrowserWindow.getAllWindows().forEach((win) => {
MainWindow.webContents.send("nativetheme-updated"); win.webContents.send("nativetheme-updated");
} });
}); });
function readLastLinesOfFile(filePath: string, lineCount: number) { function readLastLinesOfFile(filePath: string, lineCount: number) {
@ -658,12 +673,12 @@ async function getClientData(willRetry: boolean, retryNum: number): Promise<Clie
} }
function sendWSSC() { function sendWSSC() {
if (MainWindow != null) { if (windows["main"] != null) {
if (waveSrvProc == null) { if (waveSrvProc == null) {
MainWindow.webContents.send("wavesrv-status-change", false); windows["main"].webContents.send("wavesrv-status-change", false);
return; return;
} }
MainWindow.webContents.send("wavesrv-status-change", true, waveSrvProc.pid); windows["main"].webContents.send("wavesrv-status-change", true, waveSrvProc.pid);
} }
} }
@ -740,9 +755,9 @@ async function createMainWindowWrap() {
} catch (e) { } catch (e) {
console.log("error getting wavesrv clientdata", e.toString()); console.log("error getting wavesrv clientdata", e.toString());
} }
MainWindow = createMainWindow(clientData); createMainWindow(clientData);
if (clientData?.winsize.fullscreen) { if (clientData?.winsize.fullscreen) {
MainWindow.setFullScreen(true); windows["main"].setFullScreen(true);
} }
configureAutoUpdaterStartup(clientData); configureAutoUpdaterStartup(clientData);
} }
@ -761,7 +776,7 @@ function logActiveState() {
console.log("error logging active state", err); console.log("error logging active state", err);
}); });
// for next iteration // for next iteration
wasInFg = MainWindow?.isFocused(); wasInFg = windows["main"]?.isFocused();
wasActive = false; wasActive = false;
} }
@ -789,7 +804,7 @@ function reregisterGlobalShortcut(shortcut: string) {
} }
const ok = electron.globalShortcut.register(shortcut, () => { const ok = electron.globalShortcut.register(shortcut, () => {
console.log("global shortcut triggered, showing window"); console.log("global shortcut triggered, showing window");
MainWindow?.show(); windows["main"]?.show();
}); });
console.log("registered global shortcut", shortcut, ok ? "ok" : "failed"); console.log("registered global shortcut", shortcut, ok ? "ok" : "failed");
if (!ok) { if (!ok) {
@ -814,8 +829,8 @@ let lastUpdateCheck: Date = null;
*/ */
function setAppUpdateStatus(status: string) { function setAppUpdateStatus(status: string) {
appUpdateStatus = status; appUpdateStatus = status;
if (MainWindow != null) { if (windows["main"] != null) {
MainWindow.webContents.send("app-update-status", appUpdateStatus); windows["main"].webContents.send("app-update-status", appUpdateStatus);
} }
} }
@ -900,7 +915,7 @@ async function installAppUpdate() {
detail: "A new version has been downloaded. Restart the application to apply the updates.", detail: "A new version has been downloaded. Restart the application to apply the updates.",
}; };
await electron.dialog.showMessageBox(MainWindow, dialogOpts).then(({ response }) => { await electron.dialog.showMessageBox(windows["main"], dialogOpts).then(({ response }) => {
if (response === 0) autoUpdater.quitAndInstall(); if (response === 0) autoUpdater.quitAndInstall();
}); });
} }