feat(desktop): add trilium:// URL protocol support#9707
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for the trilium:// protocol, allowing the desktop application to open specific notes via external links. The implementation includes logic for registering the protocol handler, parsing note IDs from command-line arguments, and handling both initial application launches and subsequent instances. A logic issue was identified in the second-instance handler where notes would incorrectly open in the previously focused window even when the --new-window flag was provided; a code suggestion was offered to ensure the note is correctly routed to the new window via a URL hash.
| app.on("second-instance", (event, commandLine) => { | ||
| const noteId = extractNoteIdFromArgs(commandLine); | ||
| const lastFocusedWindow = windowService.getLastFocusedWindow(); | ||
|
|
||
| if (commandLine.includes("--new-window")) { | ||
| windowService.createExtraWindow(""); | ||
| } else if (lastFocusedWindow) { | ||
| if (lastFocusedWindow.isMinimized()) { | ||
| lastFocusedWindow.restore(); | ||
| } | ||
| if (lastFocusedWindow.isMinimized()) lastFocusedWindow.restore(); | ||
| lastFocusedWindow.show(); | ||
| lastFocusedWindow.focus(); | ||
| } | ||
|
|
||
| if (noteId && lastFocusedWindow) { | ||
| lastFocusedWindow.webContents.send("open-note-by-id", noteId); | ||
| } | ||
| }); |
There was a problem hiding this comment.
There's a logic issue in how a second instance with a protocol URL and the --new-window flag is handled. The current implementation creates a new window but then opens the note from the URL in the previously focused window, which is likely not the desired behavior.
The note should be opened in the new window. This can be achieved by passing the note ID in the URL hash when creating the new window, as the logic to open a note from a hash on window creation already exists.
Here is a suggested improvement to handle this case correctly:
| app.on("second-instance", (event, commandLine) => { | |
| const noteId = extractNoteIdFromArgs(commandLine); | |
| const lastFocusedWindow = windowService.getLastFocusedWindow(); | |
| if (commandLine.includes("--new-window")) { | |
| windowService.createExtraWindow(""); | |
| } else if (lastFocusedWindow) { | |
| if (lastFocusedWindow.isMinimized()) { | |
| lastFocusedWindow.restore(); | |
| } | |
| if (lastFocusedWindow.isMinimized()) lastFocusedWindow.restore(); | |
| lastFocusedWindow.show(); | |
| lastFocusedWindow.focus(); | |
| } | |
| if (noteId && lastFocusedWindow) { | |
| lastFocusedWindow.webContents.send("open-note-by-id", noteId); | |
| } | |
| }); | |
| app.on("second-instance", (event, commandLine) => { | |
| const noteId = extractNoteIdFromArgs(commandLine); | |
| if (commandLine.includes("--new-window")) { | |
| const hash = noteId ? `#/notes/${noteId}` : ""; | |
| windowService.createExtraWindow(hash); | |
| } else { | |
| const lastFocusedWindow = windowService.getLastFocusedWindow(); | |
| if (lastFocusedWindow) { | |
| if (lastFocusedWindow.isMinimized()) lastFocusedWindow.restore(); | |
| lastFocusedWindow.show(); | |
| lastFocusedWindow.focus(); | |
| if (noteId) { | |
| lastFocusedWindow.webContents.send("open-note-by-id", noteId); | |
| } | |
| } | |
| } | |
| }); |
|
Hi, Thank you for the contribution but we'd like to implement this feature on our own since it needs to be done on an agreed-upon plan. |
Closes #649
Changes
trilium://as default protocol client on app startupextractNoteIdFromArgs()helper to avoid duplicated URL parsing logicpendingNoteIdvariable instead ofglobalfor type safetysetTimeoutwithwebContents.once("did-finish-load")to eliminate race conditionrequestSingleInstanceLock()callopen-note-by-idIPC listener in renderer to open note by IDFixes from previous attempt (#9248)
new URL()— handlestrilium:///noteIdcorrectlyglobalobject usageIssueHunt Summary
Referenced issues
This pull request has been submitted to: