[desktop] Don't assume a particular position for the open URL arg

Ref: https://github.com/electron/electron/issues/20322
This commit is contained in:
Manav Rathi
2025-01-29 17:01:33 +05:30
parent 6217c3a8f5
commit 167807c758
4 changed files with 23 additions and 17 deletions

View File

@@ -95,10 +95,10 @@ const main = () => {
/**
* Handle an open URL request, but ensuring that we have a mainWindow.
*/
const handleOpenURLEnsuringWindow = (url: string) => {
const handleOpenEnteURLEnsuringWindow = (url: string) => {
log.info(`Attempting to handle request to open URL: ${url}`);
if (mainWindow) handleEnteLinks(mainWindow, url);
else setTimeout(() => handleOpenURLEnsuringWindow(url), 1000);
else setTimeout(() => handleOpenEnteURLEnsuringWindow(url), 1000);
};
app.on("second-instance", (_, argv: string[]) => {
@@ -109,9 +109,15 @@ const main = () => {
mainWindow.focus();
}
// On Windows and Linux, this is how we get deeplinks.
//
// See: registerForEnteLinks
const url = argv.pop();
if (url) handleOpenURLEnsuringWindow(url);
//
// Note that Chromium reserves the right to fudge with the order of the
// command line arguments, including inserting things in arbitrary
// places, so we need to go through the args to find the one that is
// pertinent to us (if any) instead of looking at a fixed position.
const url = argv.find((arg) => arg.startsWith("ente://app"));
if (url) handleOpenEnteURLEnsuringWindow(url);
});
// Emitted once, when Electron has finished initializing.
@@ -170,7 +176,7 @@ const main = () => {
});
// On macOS, this is how we get deeplinks. See: registerForEnteLinks
app.on("open-url", (_, url) => handleOpenURLEnsuringWindow(url));
app.on("open-url", (_, url) => handleOpenEnteURLEnsuringWindow(url));
};
/**
@@ -272,7 +278,7 @@ const handleEnteLinks = (mainWindow: BrowserWindow, url: string) => {
// - the protocol we're using to serve/ our bundled web app
//
// use the same scheme ("ente://"), so the URL can directly be forwarded.
mainWindow.webContents.send("openURL", url);
mainWindow.webContents.send("openEnteURL", url);
};
/** Attach handlers to the (node) process. */

View File

@@ -127,9 +127,9 @@ const onMainWindowFocus = (cb: (() => void) | undefined) => {
if (cb) ipcRenderer.on("mainWindowFocus", cb);
};
const onOpenURL = (cb: ((url: string) => void) | undefined) => {
ipcRenderer.removeAllListeners("openURL");
if (cb) ipcRenderer.on("openURL", (_, url: string) => cb(url));
const onOpenEnteURL = (cb: ((url: string) => void) | undefined) => {
ipcRenderer.removeAllListeners("openEnteURL");
if (cb) ipcRenderer.on("openEnteURL", (_, url: string) => cb(url));
};
// - App update
@@ -348,7 +348,7 @@ contextBridge.exposeInMainWorld("electron", {
lastShownChangelogVersion,
setLastShownChangelogVersion,
onMainWindowFocus,
onOpenURL,
onOpenEnteURL,
// - App update

View File

@@ -73,7 +73,7 @@ const App: React.FC<AppProps> = ({ Component, pageProps }) => {
// This is for events that we should listen for always, not just when
// the user is logged in.
const handleOpenURL = (url: string) => {
const handleOpenEnteURL = (url: string) => {
if (url.startsWith("ente://app")) router.push(url);
else log.info(`Ignoring unhandled open request for URL ${url}`);
};
@@ -96,11 +96,11 @@ const App: React.FC<AppProps> = ({ Component, pageProps }) => {
if (isMLSupported) initML();
electron.onOpenURL(handleOpenURL);
electron.onOpenEnteURL(handleOpenEnteURL);
electron.onAppUpdateAvailable(showUpdateDialog);
return () => {
electron.onOpenURL(undefined);
electron.onOpenEnteURL(undefined);
electron.onAppUpdateAvailable(undefined);
};
}, []);

View File

@@ -114,9 +114,9 @@ export interface Electron {
/**
* Set or clear the callback {@link cb} to invoke whenever the app gets
* asked to open a deeplink. This allows the Node.js layer to ask the
* renderer to handle deeplinks and redirect itself to a new location if
* needed.
* asked to open a deeplink that begins with "ente://". This allows the
* Node.js layer to ask the renderer to handle deeplinks and redirect itself
* to a new location if needed.
*
* In particular, this is necessary for handling passkey authentication.
* See: [Note: Passkey verification in the desktop app]
@@ -127,7 +127,7 @@ export interface Electron {
* "ente://" URL. The URL string (a.k.a. "deeplink") we were asked to open
* is passed to the function verbatim.
*/
onOpenURL: (cb: ((url: string) => void) | undefined) => void;
onOpenEnteURL: (cb: ((url: string) => void) | undefined) => void;
// - App update