mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
closetab / tab destroy fixes (#1424)
This commit is contained in:
parent
72ea58267d
commit
9f6cdfdbf6
@ -4,11 +4,11 @@
|
|||||||
import { FileService } from "@/app/store/services";
|
import { FileService } from "@/app/store/services";
|
||||||
import { adaptFromElectronKeyEvent } from "@/util/keyutil";
|
import { adaptFromElectronKeyEvent } from "@/util/keyutil";
|
||||||
import { Rectangle, shell, WebContentsView } from "electron";
|
import { Rectangle, shell, WebContentsView } from "electron";
|
||||||
|
import { getWaveWindowById } from "emain/emain-window";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { configureAuthKeyRequestInjection } from "./authkey";
|
import { configureAuthKeyRequestInjection } from "./authkey";
|
||||||
import { setWasActive } from "./emain-activity";
|
import { setWasActive } from "./emain-activity";
|
||||||
import { handleCtrlShiftFocus, handleCtrlShiftState, shFrameNavHandler, shNavHandler } from "./emain-util";
|
import { handleCtrlShiftFocus, handleCtrlShiftState, shFrameNavHandler, shNavHandler } from "./emain-util";
|
||||||
import { waveWindowMap } from "./emain-window";
|
|
||||||
import { getElectronAppBasePath, isDevVite } from "./platform";
|
import { getElectronAppBasePath, isDevVite } from "./platform";
|
||||||
|
|
||||||
function computeBgColor(fullConfig: FullConfigType): string {
|
function computeBgColor(fullConfig: FullConfigType): string {
|
||||||
@ -31,8 +31,8 @@ export function getWaveTabViewByWebContentsId(webContentsId: number): WaveTabVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class WaveTabView extends WebContentsView {
|
export class WaveTabView extends WebContentsView {
|
||||||
|
waveWindowId: string; // this will be set for any tabviews that are initialized. (unset for the hot spare)
|
||||||
isActiveTab: boolean;
|
isActiveTab: boolean;
|
||||||
waveWindowId: string; // set when showing in an active window
|
|
||||||
private _waveTabId: string; // always set, WaveTabViews are unique per tab
|
private _waveTabId: string; // always set, WaveTabViews are unique per tab
|
||||||
lastUsedTs: number; // ts milliseconds
|
lastUsedTs: number; // ts milliseconds
|
||||||
createdTs: number; // ts milliseconds
|
createdTs: number; // ts milliseconds
|
||||||
@ -43,9 +43,7 @@ export class WaveTabView extends WebContentsView {
|
|||||||
waveReadyResolve: () => void;
|
waveReadyResolve: () => void;
|
||||||
isInitialized: boolean = false;
|
isInitialized: boolean = false;
|
||||||
isWaveReady: boolean = false;
|
isWaveReady: boolean = false;
|
||||||
|
isDestroyed: boolean = false;
|
||||||
// used to destroy the tab if it is not initialized within a certain time after being assigned a tabId
|
|
||||||
private destroyTabTimeout: NodeJS.Timeout;
|
|
||||||
|
|
||||||
constructor(fullConfig: FullConfigType) {
|
constructor(fullConfig: FullConfigType) {
|
||||||
console.log("createBareTabView");
|
console.log("createBareTabView");
|
||||||
@ -67,13 +65,8 @@ export class WaveTabView extends WebContentsView {
|
|||||||
this.waveReadyPromise = new Promise((resolve, _) => {
|
this.waveReadyPromise = new Promise((resolve, _) => {
|
||||||
this.waveReadyResolve = resolve;
|
this.waveReadyResolve = resolve;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Once the frontend is ready, we can cancel the destroyTabTimeout, assuming the tab hasn't been destroyed yet
|
|
||||||
// Only after a tab is ready will we add it to the wcvCache
|
|
||||||
this.waveReadyPromise.then(() => {
|
this.waveReadyPromise.then(() => {
|
||||||
this.isWaveReady = true;
|
this.isWaveReady = true;
|
||||||
clearTimeout(this.destroyTabTimeout);
|
|
||||||
setWaveTabView(this.waveTabId, this);
|
|
||||||
});
|
});
|
||||||
wcIdToWaveTabMap.set(this.webContents.id, this);
|
wcIdToWaveTabMap.set(this.webContents.id, this);
|
||||||
if (isDevVite) {
|
if (isDevVite) {
|
||||||
@ -84,6 +77,7 @@ export class WaveTabView extends WebContentsView {
|
|||||||
this.webContents.on("destroyed", () => {
|
this.webContents.on("destroyed", () => {
|
||||||
wcIdToWaveTabMap.delete(this.webContents.id);
|
wcIdToWaveTabMap.delete(this.webContents.id);
|
||||||
removeWaveTabView(this.waveTabId);
|
removeWaveTabView(this.waveTabId);
|
||||||
|
this.isDestroyed = true;
|
||||||
});
|
});
|
||||||
this.setBackgroundColor(computeBgColor(fullConfig));
|
this.setBackgroundColor(computeBgColor(fullConfig));
|
||||||
}
|
}
|
||||||
@ -94,9 +88,6 @@ export class WaveTabView extends WebContentsView {
|
|||||||
|
|
||||||
set waveTabId(waveTabId: string) {
|
set waveTabId(waveTabId: string) {
|
||||||
this._waveTabId = waveTabId;
|
this._waveTabId = waveTabId;
|
||||||
this.destroyTabTimeout = setTimeout(() => {
|
|
||||||
this.destroy();
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
positionTabOnScreen(winBounds: Rectangle) {
|
positionTabOnScreen(winBounds: Rectangle) {
|
||||||
@ -128,14 +119,11 @@ export class WaveTabView extends WebContentsView {
|
|||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
console.log("destroy tab", this.waveTabId);
|
console.log("destroy tab", this.waveTabId);
|
||||||
this.webContents?.close();
|
|
||||||
removeWaveTabView(this.waveTabId);
|
removeWaveTabView(this.waveTabId);
|
||||||
|
if (!this.isDestroyed) {
|
||||||
// TODO: circuitous
|
this.webContents?.close();
|
||||||
const waveWindow = waveWindowMap.get(this.waveWindowId);
|
|
||||||
if (waveWindow) {
|
|
||||||
waveWindow.allLoadedTabViews.delete(this.waveTabId);
|
|
||||||
}
|
}
|
||||||
|
this.isDestroyed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +143,31 @@ export function getWaveTabView(waveTabId: string): WaveTabView | undefined {
|
|||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function tryEvictEntry(waveTabId: string): boolean {
|
||||||
|
const tabView = wcvCache.get(waveTabId);
|
||||||
|
if (!tabView) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tabView.isActiveTab) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const lastUsedDiff = Date.now() - tabView.lastUsedTs;
|
||||||
|
if (lastUsedDiff < 1000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const ww = getWaveWindowById(tabView.waveWindowId);
|
||||||
|
if (!ww) {
|
||||||
|
// this shouldn't happen, but if it does, just destroy the tabview
|
||||||
|
console.log("[error] WaveWindow not found for WaveTabView", tabView.waveTabId);
|
||||||
|
tabView.destroy();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// will trigger a destroy on the tabview
|
||||||
|
ww.removeTabView(tabView.waveTabId, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkAndEvictCache(): void {
|
function checkAndEvictCache(): void {
|
||||||
if (wcvCache.size <= MaxCacheSize) {
|
if (wcvCache.size <= MaxCacheSize) {
|
||||||
return;
|
return;
|
||||||
@ -167,13 +180,9 @@ function checkAndEvictCache(): void {
|
|||||||
// Otherwise, sort by lastUsedTs
|
// Otherwise, sort by lastUsedTs
|
||||||
return a.lastUsedTs - b.lastUsedTs;
|
return a.lastUsedTs - b.lastUsedTs;
|
||||||
});
|
});
|
||||||
|
const now = Date.now();
|
||||||
for (let i = 0; i < sorted.length - MaxCacheSize; i++) {
|
for (let i = 0; i < sorted.length - MaxCacheSize; i++) {
|
||||||
if (sorted[i].isActiveTab) {
|
tryEvictEntry(sorted[i].waveTabId);
|
||||||
// don't evict WaveTabViews that are currently showing in a window
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const tabView = sorted[i];
|
|
||||||
tabView?.destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,22 +190,21 @@ export function clearTabCache() {
|
|||||||
const wcVals = Array.from(wcvCache.values());
|
const wcVals = Array.from(wcvCache.values());
|
||||||
for (let i = 0; i < wcVals.length; i++) {
|
for (let i = 0; i < wcVals.length; i++) {
|
||||||
const tabView = wcVals[i];
|
const tabView = wcVals[i];
|
||||||
if (tabView.isActiveTab) {
|
tryEvictEntry(tabView.waveTabId);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tabView?.destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns [tabview, initialized]
|
// returns [tabview, initialized]
|
||||||
export async function getOrCreateWebViewForTab(tabId: string): Promise<[WaveTabView, boolean]> {
|
export async function getOrCreateWebViewForTab(waveWindowId: string, tabId: string): Promise<[WaveTabView, boolean]> {
|
||||||
let tabView = getWaveTabView(tabId);
|
let tabView = getWaveTabView(tabId);
|
||||||
if (tabView) {
|
if (tabView) {
|
||||||
return [tabView, true];
|
return [tabView, true];
|
||||||
}
|
}
|
||||||
const fullConfig = await FileService.GetFullConfig();
|
const fullConfig = await FileService.GetFullConfig();
|
||||||
tabView = getSpareTab(fullConfig);
|
tabView = getSpareTab(fullConfig);
|
||||||
|
tabView.waveWindowId = waveWindowId;
|
||||||
tabView.lastUsedTs = Date.now();
|
tabView.lastUsedTs = Date.now();
|
||||||
|
setWaveTabView(tabId, tabView);
|
||||||
tabView.waveTabId = tabId;
|
tabView.waveTabId = tabId;
|
||||||
tabView.webContents.on("will-navigate", shNavHandler);
|
tabView.webContents.on("will-navigate", shNavHandler);
|
||||||
tabView.webContents.on("will-frame-navigate", shFrameNavHandler);
|
tabView.webContents.on("will-frame-navigate", shFrameNavHandler);
|
||||||
@ -231,11 +239,17 @@ export async function getOrCreateWebViewForTab(tabId: string): Promise<[WaveTabV
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setWaveTabView(waveTabId: string, wcv: WaveTabView): void {
|
export function setWaveTabView(waveTabId: string, wcv: WaveTabView): void {
|
||||||
|
if (waveTabId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
wcvCache.set(waveTabId, wcv);
|
wcvCache.set(waveTabId, wcv);
|
||||||
checkAndEvictCache();
|
checkAndEvictCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeWaveTabView(waveTabId: string): void {
|
function removeWaveTabView(waveTabId: string): void {
|
||||||
|
if (waveTabId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
wcvCache.delete(waveTabId);
|
wcvCache.delete(waveTabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,13 +38,17 @@ async function getClientId() {
|
|||||||
|
|
||||||
type TabSwitchQueueEntry =
|
type TabSwitchQueueEntry =
|
||||||
| {
|
| {
|
||||||
createTab: false;
|
op: "switch";
|
||||||
tabId: string;
|
tabId: string;
|
||||||
setInBackend: boolean;
|
setInBackend: boolean;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
createTab: true;
|
op: "create";
|
||||||
pinned: boolean;
|
pinned: boolean;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
op: "close";
|
||||||
|
tabId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class WaveBrowserWindow extends BaseWindow {
|
export class WaveBrowserWindow extends BaseWindow {
|
||||||
@ -252,6 +256,11 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
console.log("win quitting or updating", this.waveWindowId);
|
console.log("win quitting or updating", this.waveWindowId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
waveWindowMap.delete(this.waveWindowId);
|
||||||
|
if (focusedWaveWindow == this) {
|
||||||
|
focusedWaveWindow = null;
|
||||||
|
}
|
||||||
|
this.removeAllChildViews();
|
||||||
if (getGlobalIsRelaunching()) {
|
if (getGlobalIsRelaunching()) {
|
||||||
console.log("win relaunching", this.waveWindowId);
|
console.log("win relaunching", this.waveWindowId);
|
||||||
this.destroy();
|
this.destroy();
|
||||||
@ -266,17 +275,19 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
console.log("win removing window from backend DB", this.waveWindowId);
|
console.log("win removing window from backend DB", this.waveWindowId);
|
||||||
fireAndForget(() => WindowService.CloseWindow(this.waveWindowId, true));
|
fireAndForget(() => WindowService.CloseWindow(this.waveWindowId, true));
|
||||||
}
|
}
|
||||||
for (const tabView of this.allLoadedTabViews.values()) {
|
|
||||||
tabView?.destroy();
|
|
||||||
}
|
|
||||||
waveWindowMap.delete(this.waveWindowId);
|
|
||||||
if (focusedWaveWindow == this) {
|
|
||||||
focusedWaveWindow = null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
waveWindowMap.set(waveWindow.oid, this);
|
waveWindowMap.set(waveWindow.oid, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeAllChildViews() {
|
||||||
|
for (const tabView of this.allLoadedTabViews.values()) {
|
||||||
|
if (!this.isDestroyed()) {
|
||||||
|
this.contentView.removeChildView(tabView);
|
||||||
|
}
|
||||||
|
tabView?.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async switchWorkspace(workspaceId: string) {
|
async switchWorkspace(workspaceId: string) {
|
||||||
console.log("switchWorkspace", workspaceId, this.waveWindowId);
|
console.log("switchWorkspace", workspaceId, this.waveWindowId);
|
||||||
if (workspaceId == this.workspaceId) {
|
if (workspaceId == this.workspaceId) {
|
||||||
@ -311,12 +322,7 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("switchWorkspace newWs", newWs);
|
console.log("switchWorkspace newWs", newWs);
|
||||||
if (this.allLoadedTabViews.size) {
|
this.removeAllChildViews();
|
||||||
for (const tab of this.allLoadedTabViews.values()) {
|
|
||||||
this.contentView.removeChildView(tab);
|
|
||||||
tab?.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("destroyed all tabs", this.waveWindowId);
|
console.log("destroyed all tabs", this.waveWindowId);
|
||||||
this.workspaceId = workspaceId;
|
this.workspaceId = workspaceId;
|
||||||
this.allLoadedTabViews = new Map();
|
this.allLoadedTabViews = new Map();
|
||||||
@ -329,22 +335,7 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async closeTab(tabId: string) {
|
async closeTab(tabId: string) {
|
||||||
console.log(`closeTab tabid=${tabId} ws=${this.workspaceId} window=${this.waveWindowId}`);
|
await this.queueCloseTab(tabId);
|
||||||
const rtn = await WorkspaceService.CloseTab(this.workspaceId, tabId, true);
|
|
||||||
if (rtn == null) {
|
|
||||||
console.log("[error] closeTab: no return value", tabId, this.workspaceId, this.waveWindowId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (rtn.closewindow) {
|
|
||||||
this.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!rtn.newactivetabid) {
|
|
||||||
console.log("[error] closeTab, no new active tab", tabId, this.workspaceId, this.waveWindowId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.setActiveTab(rtn.newactivetabid, false);
|
|
||||||
this.allLoadedTabViews.delete(tabId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async initializeTab(tabView: WaveTabView) {
|
async initializeTab(tabView: WaveTabView) {
|
||||||
@ -447,11 +438,15 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async queueTabSwitch(tabId: string, setInBackend: boolean) {
|
async queueTabSwitch(tabId: string, setInBackend: boolean) {
|
||||||
await this._queueTabSwitchInternal({ createTab: false, tabId, setInBackend });
|
await this._queueTabSwitchInternal({ op: "switch", tabId, setInBackend });
|
||||||
}
|
}
|
||||||
|
|
||||||
async queueCreateTab(pinned = false) {
|
async queueCreateTab(pinned = false) {
|
||||||
await this._queueTabSwitchInternal({ createTab: true, pinned });
|
await this._queueTabSwitchInternal({ op: "create", pinned });
|
||||||
|
}
|
||||||
|
|
||||||
|
async queueCloseTab(tabId: string) {
|
||||||
|
await this._queueTabSwitchInternal({ op: "close", tabId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async _queueTabSwitchInternal(entry: TabSwitchQueueEntry) {
|
async _queueTabSwitchInternal(entry: TabSwitchQueueEntry) {
|
||||||
@ -466,6 +461,12 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeTabViewLater(tabId: string, delayMs: number) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.removeTabView(tabId, false);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
// the queue and this function are used to serialize tab switches
|
// the queue and this function are used to serialize tab switches
|
||||||
// [0] => the tab that is currently being switched to
|
// [0] => the tab that is currently being switched to
|
||||||
// [1] => the tab that will be switched to next
|
// [1] => the tab that will be switched to next
|
||||||
@ -478,10 +479,10 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
const entry = this.tabSwitchQueue[0];
|
const entry = this.tabSwitchQueue[0];
|
||||||
let tabId: string = null;
|
let tabId: string = null;
|
||||||
// have to use "===" here to get the typechecker to work :/
|
// have to use "===" here to get the typechecker to work :/
|
||||||
if (entry.createTab === true) {
|
if (entry.op === "create") {
|
||||||
const { pinned } = entry;
|
const { pinned } = entry;
|
||||||
tabId = await WorkspaceService.CreateTab(this.workspaceId, null, true, pinned);
|
tabId = await WorkspaceService.CreateTab(this.workspaceId, null, true, pinned);
|
||||||
} else if (entry.createTab === false) {
|
} else if (entry.op === "switch") {
|
||||||
let setInBackend: boolean = false;
|
let setInBackend: boolean = false;
|
||||||
({ tabId, setInBackend } = entry);
|
({ tabId, setInBackend } = entry);
|
||||||
if (this.activeTabView?.waveTabId == tabId) {
|
if (this.activeTabView?.waveTabId == tabId) {
|
||||||
@ -490,11 +491,28 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
if (setInBackend) {
|
if (setInBackend) {
|
||||||
await WorkspaceService.SetActiveTab(this.workspaceId, tabId);
|
await WorkspaceService.SetActiveTab(this.workspaceId, tabId);
|
||||||
}
|
}
|
||||||
|
} else if (entry.op === "close") {
|
||||||
|
console.log("processTabSwitchQueue closeTab", entry.tabId);
|
||||||
|
tabId = entry.tabId;
|
||||||
|
const rtn = await WorkspaceService.CloseTab(this.workspaceId, tabId, true);
|
||||||
|
if (rtn == null) {
|
||||||
|
console.log("[error] closeTab: no return value", tabId, this.workspaceId, this.waveWindowId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.removeTabViewLater(tabId, 1000);
|
||||||
|
if (rtn.closewindow) {
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!rtn.newactivetabid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tabId = rtn.newactivetabid;
|
||||||
}
|
}
|
||||||
if (tabId == null) {
|
if (tabId == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [tabView, tabInitialized] = await getOrCreateWebViewForTab(tabId);
|
const [tabView, tabInitialized] = await getOrCreateWebViewForTab(this.waveWindowId, tabId);
|
||||||
await this.setTabViewIntoWindow(tabView, tabInitialized);
|
await this.setTabViewIntoWindow(tabView, tabInitialized);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("error caught in processTabSwitchQueue", e);
|
console.log("error caught in processTabSwitchQueue", e);
|
||||||
@ -520,6 +538,22 @@ export class WaveBrowserWindow extends BaseWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeTabView(tabId: string, force: boolean) {
|
||||||
|
if (!force && this.activeTabView?.waveTabId == tabId) {
|
||||||
|
console.log("cannot remove active tab", tabId, this.waveWindowId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tabView = this.allLoadedTabViews.get(tabId);
|
||||||
|
if (tabView == null) {
|
||||||
|
console.log("removeTabView -- tabView not found", tabId, this.waveWindowId);
|
||||||
|
// the tab was never loaded, so just return
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.contentView.removeChildView(tabView);
|
||||||
|
this.allLoadedTabViews.delete(tabId);
|
||||||
|
tabView.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
console.log("destroy win", this.waveWindowId);
|
console.log("destroy win", this.waveWindowId);
|
||||||
this.deleteAllowed = true;
|
this.deleteAllowed = true;
|
||||||
@ -607,9 +641,7 @@ ipcMain.on("close-tab", async (event, workspaceId, tabId) => {
|
|||||||
console.log(`close-tab: no window found for workspace ws=${workspaceId} tab=${tabId}`);
|
console.log(`close-tab: no window found for workspace ws=${workspaceId} tab=${tabId}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ww != null) {
|
await ww.queueCloseTab(tabId);
|
||||||
await ww.closeTab(tabId);
|
|
||||||
}
|
|
||||||
event.returnValue = true;
|
event.returnValue = true;
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@ -685,10 +717,13 @@ export async function relaunchBrowserWindows() {
|
|||||||
console.log("relaunchBrowserWindows");
|
console.log("relaunchBrowserWindows");
|
||||||
setGlobalIsRelaunching(true);
|
setGlobalIsRelaunching(true);
|
||||||
const windows = getAllWaveWindows();
|
const windows = getAllWaveWindows();
|
||||||
|
if (windows.length > 0) {
|
||||||
for (const window of windows) {
|
for (const window of windows) {
|
||||||
console.log("relaunch -- closing window", window.waveWindowId);
|
console.log("relaunch -- closing window", window.waveWindowId);
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
await delay(1200);
|
||||||
|
}
|
||||||
setGlobalIsRelaunching(false);
|
setGlobalIsRelaunching(false);
|
||||||
|
|
||||||
const clientData = await ClientService.GetClientData();
|
const clientData = await ClientService.GetClientData();
|
||||||
|
Loading…
Reference in New Issue
Block a user