Skip to content

Commit

Permalink
chore(app): add waitWindowMarkedReady
Browse files Browse the repository at this point in the history
Signed-off-by: Grigorii K. Shartsev <[email protected]>
  • Loading branch information
ShGKme committed Nov 20, 2024
1 parent 281a7bf commit aabc3ae
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
48 changes: 47 additions & 1 deletion src/app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { screen } from 'electron'
import type { IpcMainEvent } from 'electron'
import { BrowserWindow, ipcMain, screen } from 'electron'
import { getAppConfig } from './AppConfig.ts'

/**
Expand Down Expand Up @@ -47,3 +48,48 @@ export function getScaledWindowMinSize({ minWidth, minHeight }: { minWidth: numb
minHeight: height,
}
}

/**
* Memoized promises of waitWindowMarkedReady.
* Using WeakMap so that the promises are garbage collected when the window is destroyed.
*/
const windowMarkedReadyPromises = new WeakMap<BrowserWindow, Promise<void>>()

/**
* Wait for the window to be marked as ready to show by its renderer process
* @param window - BrowserWindow
*/
export function waitWindowMarkedReady(window: BrowserWindow): Promise<void> {
// As a window is marked ready only once.
// Awaiting promise is memoized to allow multiple calls and calls on a ready window.

if (windowMarkedReadyPromises.has(window)) {
return windowMarkedReadyPromises.get(window)!
}

const promise: Promise<void> = new Promise((resolve) => {
const handleMarkWindowReady = (event: IpcMainEvent) => {
if (event.sender === window.webContents) {
ipcMain.removeListener('app:markWindowReady', handleMarkWindowReady)
resolve()
}
}
ipcMain.on('app:markWindowReady', handleMarkWindowReady)
})

windowMarkedReadyPromises.set(window, promise)

return promise
}

/**
* Show the window when it is marked as ready to show its renderer process
* @param window - The BrowserWindow
*/
export async function showWhenWindowMarkedReady(window: BrowserWindow): Promise<void> {
if (window.isVisible()) {
return
}
await waitWindowMarkedReady(window)
window.show()
}
4 changes: 4 additions & 0 deletions src/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const TALK_DESKTOP = {
* @type {typeof packageInfo} packageInfo
*/
packageInfo,
/**
* Mark the window as ready to show
*/
markWindowReady: () => ipcRenderer.send('app:markWindowReady'),
/**
* Get app name
*
Expand Down
14 changes: 14 additions & 0 deletions src/shared/markWindowReady.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

/**
* Mark the window as ready to show
*/
export function markWindowReady() {
// Wait for the next frame to ensure the window content is actually rendered
requestAnimationFrame(() => {
window.TALK_DESKTOP.markWindowReady()
})
}

0 comments on commit aabc3ae

Please sign in to comment.