update window close logic for windows/linux (#268)

Co-authored-by: Sylvia Crowe
This commit is contained in:
Mike Sawka 2024-08-26 22:03:43 -07:00 committed by GitHub
parent c2d2ad9136
commit ab5a9ec749
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 207 additions and 179 deletions

View File

@ -18,6 +18,7 @@ import { WSServerEndpointVarName, WebServerEndpointVarName, getWebServerEndpoint
import { fetch } from "../frontend/util/fetchutil"; import { fetch } from "../frontend/util/fetchutil";
import { fireAndForget } from "../frontend/util/util"; import { fireAndForget } from "../frontend/util/util";
import { AuthKey, AuthKeyEnv, configureAuthKeyRequestInjection } from "./authkey"; import { AuthKey, AuthKeyEnv, configureAuthKeyRequestInjection } from "./authkey";
import { getAppMenu } from "./menu";
import { import {
getElectronAppBasePath, getElectronAppBasePath,
getGoAppBasePath, getGoAppBasePath,
@ -404,6 +405,10 @@ function createBrowserWindow(
if (globalIsQuitting || updater?.status == "installing") { if (globalIsQuitting || updater?.status == "installing") {
return; return;
} }
const numWindows = electron.BrowserWindow.getAllWindows().length;
if ((unamePlatform == "win32" || unamePlatform == "linux") && numWindows == 1) {
return;
}
const choice = electron.dialog.showMessageBoxSync(win, { const choice = electron.dialog.showMessageBoxSync(win, {
type: "question", type: "question",
buttons: ["Cancel", "Yes"], buttons: ["Cancel", "Yes"],
@ -418,6 +423,10 @@ function createBrowserWindow(
if (globalIsQuitting || updater?.status == "installing") { if (globalIsQuitting || updater?.status == "installing") {
return; return;
} }
const numWindows = electron.BrowserWindow.getAllWindows().length;
if ((unamePlatform == "win32" || unamePlatform == "linux") && numWindows == 0) {
return;
}
services.WindowService.CloseWindow(waveWindow.oid); services.WindowService.CloseWindow(waveWindow.oid);
}); });
win.webContents.on("zoom-changed", (e) => { win.webContents.on("zoom-changed", (e) => {
@ -570,7 +579,7 @@ if (unamePlatform !== "darwin") {
}); });
} }
async function createNewWaveWindow() { async function createNewWaveWindow(): Promise<void> {
const clientData = await services.ClientService.GetClientData(); const clientData = await services.ClientService.GetClientData();
const newWindow = await services.ClientService.MakeWindow(); const newWindow = await services.ClientService.MakeWindow();
const settings = await services.FileService.GetSettingsConfig(); const settings = await services.FileService.GetSettingsConfig();
@ -585,7 +594,7 @@ electron.ipcMain.on("contextmenu-show", (event, menuDefArr?: ElectronContextMenu
if (menuDefArr?.length === 0) { if (menuDefArr?.length === 0) {
return; return;
} }
const menu = menuDefArr ? convertMenuDefArrToMenu(menuDefArr) : getAppMenu(); const menu = menuDefArr ? convertMenuDefArrToMenu(menuDefArr) : instantiateAppMenu();
const { x, y } = electron.screen.getCursorScreenPoint(); const { x, y } = electron.screen.getCursorScreenPoint();
const windowPos = window.getPosition(); const windowPos = window.getPosition();
@ -637,185 +646,13 @@ function convertMenuDefArrToMenu(menuDefArr: ElectronContextMenuItem[]): electro
return electron.Menu.buildFromTemplate(menuItems); return electron.Menu.buildFromTemplate(menuItems);
} }
function getAppMenu() { function instantiateAppMenu(): electron.Menu {
const fileMenu: Electron.MenuItemConstructorOptions[] = [ return getAppMenu({ createNewWaveWindow, relaunchBrowserWindows });
{
label: "New Window",
accelerator: "CommandOrControl+Shift+N",
click: () => fireAndForget(createNewWaveWindow),
},
{
role: "close",
accelerator: "", // clear the accelerator
click: () => {
electron.BrowserWindow.getFocusedWindow()?.close();
},
},
];
const appMenu: Electron.MenuItemConstructorOptions[] = [
{
label: "About Wave Terminal",
click: (_, window) => {
window?.webContents.send("menu-item-about");
},
},
{
label: "Check for Updates",
click: () => {
fireAndForget(() => updater?.checkForUpdates(true));
},
},
{
type: "separator",
},
];
if (unamePlatform === "darwin") {
appMenu.push(
{
role: "services",
},
{
type: "separator",
},
{
role: "hide",
},
{
role: "hideOthers",
},
{
type: "separator",
}
);
}
appMenu.push({
role: "quit",
});
const editMenu: Electron.MenuItemConstructorOptions[] = [
{
role: "undo",
accelerator: unamePlatform === "darwin" ? "Command+Z" : "",
},
{
role: "redo",
accelerator: unamePlatform === "darwin" ? "Command+Shift+Z" : "",
},
{
type: "separator",
},
{
role: "cut",
accelerator: unamePlatform === "darwin" ? "Command+X" : "",
},
{
role: "copy",
accelerator: unamePlatform === "darwin" ? "Command+C" : "",
},
{
role: "paste",
accelerator: unamePlatform === "darwin" ? "Command+V" : "",
},
{
role: "pasteAndMatchStyle",
accelerator: unamePlatform === "darwin" ? "Command+Shift+V" : "",
},
{
role: "delete",
},
{
role: "selectAll",
accelerator: unamePlatform === "darwin" ? "Command+A" : "",
},
];
const viewMenu: Electron.MenuItemConstructorOptions[] = [
{
role: "forceReload",
},
{
label: "Relaunch All Windows",
click: () => {
relaunchBrowserWindows();
},
},
{
role: "toggleDevTools",
},
{
type: "separator",
},
{
label: "Actual Size",
accelerator: "CommandOrControl+0",
click: (_, window) => {
window.webContents.setZoomFactor(1);
},
},
{
label: "Zoom In",
accelerator: "CommandOrControl+=",
click: (_, window) => {
window.webContents.setZoomFactor(window.webContents.getZoomFactor() + 0.2);
},
},
{
label: "Zoom In (hidden)",
accelerator: "CommandOrControl+Shift+=",
click: (_, window) => {
window.webContents.setZoomFactor(window.webContents.getZoomFactor() + 0.2);
},
visible: false,
acceleratorWorksWhenHidden: true,
},
{
label: "Zoom Out",
accelerator: "CommandOrControl+-",
click: (_, window) => {
window.webContents.setZoomFactor(window.webContents.getZoomFactor() - 0.2);
},
},
{
type: "separator",
},
{
role: "togglefullscreen",
},
];
const windowMenu: Electron.MenuItemConstructorOptions[] = [
{ role: "minimize", accelerator: "" },
{ role: "zoom" },
{ type: "separator" },
{ role: "front" },
{ type: "separator" },
{ role: "window" },
];
const menuTemplate: Electron.MenuItemConstructorOptions[] = [
{
role: "appMenu",
submenu: appMenu,
},
{
role: "fileMenu",
submenu: fileMenu,
},
{
role: "editMenu",
submenu: editMenu,
},
{
role: "viewMenu",
submenu: viewMenu,
},
{
role: "windowMenu",
submenu: windowMenu,
},
];
return electron.Menu.buildFromTemplate(menuTemplate);
} }
function makeAppMenu() { function makeAppMenu() {
electron.Menu.setApplicationMenu(getAppMenu()); const menu = instantiateAppMenu();
electron.Menu.setApplicationMenu(menu);
} }
electronApp.on("window-all-closed", () => { electronApp.on("window-all-closed", () => {
@ -853,7 +690,7 @@ process.on("uncaughtException", (error) => {
electronApp.quit(); electronApp.quit();
}); });
async function relaunchBrowserWindows() { async function relaunchBrowserWindows(): Promise<void> {
globalIsRelaunching = true; globalIsRelaunching = true;
const windows = electron.BrowserWindow.getAllWindows(); const windows = electron.BrowserWindow.getAllWindows();
for (const window of windows) { for (const window of windows) {

191
emain/menu.ts Normal file
View File

@ -0,0 +1,191 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import * as electron from "electron";
import { fireAndForget } from "../frontend/util/util";
import { unamePlatform } from "./platform";
import { updater } from "./updater";
type AppMenuCallbacks = {
createNewWaveWindow: () => Promise<void>;
relaunchBrowserWindows: () => Promise<void>;
};
function getAppMenu(callbacks: AppMenuCallbacks): Electron.Menu {
const fileMenu: Electron.MenuItemConstructorOptions[] = [
{
label: "New Window",
accelerator: "CommandOrControl+Shift+N",
click: () => fireAndForget(callbacks.createNewWaveWindow),
},
{
role: "close",
accelerator: "", // clear the accelerator
click: () => {
electron.BrowserWindow.getFocusedWindow()?.close();
},
},
];
const appMenu: Electron.MenuItemConstructorOptions[] = [
{
label: "About Wave Terminal",
click: (_, window) => {
window?.webContents.send("menu-item-about");
},
},
{
label: "Check for Updates",
click: () => {
fireAndForget(() => updater?.checkForUpdates(true));
},
},
{
type: "separator",
},
];
if (unamePlatform === "darwin") {
appMenu.push(
{
role: "services",
},
{
type: "separator",
},
{
role: "hide",
},
{
role: "hideOthers",
},
{
type: "separator",
}
);
}
appMenu.push({
role: "quit",
});
const editMenu: Electron.MenuItemConstructorOptions[] = [
{
role: "undo",
accelerator: unamePlatform === "darwin" ? "Command+Z" : "",
},
{
role: "redo",
accelerator: unamePlatform === "darwin" ? "Command+Shift+Z" : "",
},
{
type: "separator",
},
{
role: "cut",
accelerator: unamePlatform === "darwin" ? "Command+X" : "",
},
{
role: "copy",
accelerator: unamePlatform === "darwin" ? "Command+C" : "",
},
{
role: "paste",
accelerator: unamePlatform === "darwin" ? "Command+V" : "",
},
{
role: "pasteAndMatchStyle",
accelerator: unamePlatform === "darwin" ? "Command+Shift+V" : "",
},
{
role: "delete",
},
{
role: "selectAll",
accelerator: unamePlatform === "darwin" ? "Command+A" : "",
},
];
const viewMenu: Electron.MenuItemConstructorOptions[] = [
{
role: "forceReload",
},
{
label: "Relaunch All Windows",
click: () => {
callbacks.relaunchBrowserWindows();
},
},
{
role: "toggleDevTools",
},
{
type: "separator",
},
{
label: "Actual Size",
accelerator: "CommandOrControl+0",
click: (_, window) => {
window.webContents.setZoomFactor(1);
},
},
{
label: "Zoom In",
accelerator: "CommandOrControl+=",
click: (_, window) => {
window.webContents.setZoomFactor(window.webContents.getZoomFactor() + 0.2);
},
},
{
label: "Zoom In (hidden)",
accelerator: "CommandOrControl+Shift+=",
click: (_, window) => {
window.webContents.setZoomFactor(window.webContents.getZoomFactor() + 0.2);
},
visible: false,
acceleratorWorksWhenHidden: true,
},
{
label: "Zoom Out",
accelerator: "CommandOrControl+-",
click: (_, window) => {
window.webContents.setZoomFactor(window.webContents.getZoomFactor() - 0.2);
},
},
{
type: "separator",
},
{
role: "togglefullscreen",
},
];
const windowMenu: Electron.MenuItemConstructorOptions[] = [
{ role: "minimize", accelerator: "" },
{ role: "zoom" },
{ type: "separator" },
{ role: "front" },
{ type: "separator" },
{ role: "window" },
];
const menuTemplate: Electron.MenuItemConstructorOptions[] = [
{
role: "appMenu",
submenu: appMenu,
},
{
role: "fileMenu",
submenu: fileMenu,
},
{
role: "editMenu",
submenu: editMenu,
},
{
role: "viewMenu",
submenu: viewMenu,
},
{
role: "windowMenu",
submenu: windowMenu,
},
];
return electron.Menu.buildFromTemplate(menuTemplate);
}
export { getAppMenu };