Skip to content

Commit 6d1d7a4

Browse files
committed
chore(app): add waitWindowMarkedReady
Signed-off-by: Grigorii K. Shartsev <[email protected]>
1 parent 88eb825 commit 6d1d7a4

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

src/app/utils.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import { screen } from 'electron'
6+
import type { IpcMainEvent } from 'electron'
7+
import { BrowserWindow, ipcMain, screen } from 'electron'
78
import { getAppConfig } from './AppConfig.ts'
89

910
/**
@@ -47,3 +48,48 @@ export function getScaledWindowMinSize({ minWidth, minHeight }: { minWidth: numb
4748
minHeight: height,
4849
}
4950
}
51+
52+
/**
53+
* Memoized promises of waitWindowMarkedReady.
54+
* Using WeakMap so that the promises are garbage collected when the window is destroyed.
55+
*/
56+
const windowMarkedReadyPromises = new WeakMap<BrowserWindow, Promise<void>>()
57+
58+
/**
59+
* Wait for the window to be marked as ready to show by its renderer process
60+
* @param window - BrowserWindow
61+
*/
62+
export function waitWindowMarkedReady(window: BrowserWindow): Promise<void> {
63+
// As a window is marked ready only once.
64+
// Awaiting promise is memoized to allow multiple calls and calls on a ready window.
65+
66+
if (windowMarkedReadyPromises.has(window)) {
67+
return windowMarkedReadyPromises.get(window)!
68+
}
69+
70+
const promise: Promise<void> = new Promise((resolve) => {
71+
const handleMarkWindowReady = (event: IpcMainEvent) => {
72+
if (event.sender === window.webContents) {
73+
ipcMain.removeListener('app:markWindowReady', handleMarkWindowReady)
74+
resolve()
75+
}
76+
}
77+
ipcMain.on('app:markWindowReady', handleMarkWindowReady)
78+
})
79+
80+
windowMarkedReadyPromises.set(window, promise)
81+
82+
return promise
83+
}
84+
85+
/**
86+
* Show the window when it is marked as ready to show its renderer process
87+
* @param window - The BrowserWindow
88+
*/
89+
export async function showWhenWindowMarkedReady(window: BrowserWindow): Promise<void> {
90+
if (window.isVisible()) {
91+
return
92+
}
93+
await waitWindowMarkedReady(window)
94+
window.show()
95+
}

src/preload.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ const TALK_DESKTOP = {
3232
* @type {typeof packageInfo} packageInfo
3333
*/
3434
packageInfo,
35+
/**
36+
* Mark the window as ready to show
37+
*/
38+
markWindowReady: () => ipcRenderer.send('app:markWindowReady'),
3539
/**
3640
* Get app name
3741
*

src/shared/markWindowReady.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
/**
7+
* Mark the window as ready to show
8+
*/
9+
export function markWindowReady() {
10+
// Wait for the next frame to ensure the window content is actually rendered
11+
requestAnimationFrame(() => {
12+
window.TALK_DESKTOP.markWindowReady()
13+
})
14+
}

0 commit comments

Comments
 (0)