Notes can be opened in a separate window by double-clicking them, which is great for multitasking. Plugin panels (the views created via joplin.views.panels) don't have this option β they're locked into the sidebar/docked area of the main window.
For panel-heavy plugins (dashboards, task boards, kanban views, custom editors, etc.) this is limiting. The panel competes for space with the note list and editor, and it can't be moved to a second monitor or kept visible while working in a different note.
Proposed solution
Add a "Detach into its own window" option for plugin panels, mirroring the existing detached-note-window behaviour:
A way for the user to pop a panel out into a standalone OS window (e.g. a context-menu item on the panel, or a window control), and dock it back.
Optionally, an API flag/method so plugins can declare a panel as detachable and/or request detaching programmatically, e.g. joplin.views.panels.setDetachable(handle, true) or a detach() call.
The detached window should keep the panel's webview state and continue receiving the normal message/update lifecycle.
Alternatives considered
Rendering the panel in the sidebar only β works, but can't be moved to a second monitor or kept open independently of the main layout.
Opening a plugin dialog as a stand-in for a window β dialogs are modal/transient and not a substitute for a persistent, resizable, independent window.
Additional context
Desktop already supports detached note windows, so much of the windowing infrastructure presumably exists; this request is to extend that capability to plugin panel views.
I already made two plugins that I want to share soon but without being able to detach them (especially on bigger or multiple displays) it becomes quite useless. As it is too narrow with the current panels.
When a plugin needs a full window it's usually because it's an alternative rendering for the note, such as indeed a kanban view, task board, etc.
For that usage, we have support for the joplin.views.editors API - when used it replaces the complete note with your own custom viewer. It's used for example the YesYouKan plugin, and it can be made to take the whole window in the sense that you can hide the note list and sidebar. Would that API help with your use case?
Thanks both. A concrete example of why neither option fits:
My Task Dashboard plugin pulls every open to-do from all notebooks into one panel: complete or reschedule from the panel, click a title to open the note, filter by notebook. It works across notes and leans on the native UI around it: openNote selects the note in the note list and editor, and the panel refreshes on onNoteSelectionChange / onNoteChange. Its only problem is space: it competes with the note list and editor, and on a second monitor it can't go anywhere.
joplin.views.editors renders one note. This panel isn't a note view; it must stay open next to the editor while I move between notes.
window.open from a webview: on current dev only about:blank gets through (the file:// URL from the example returns null), and the plugin then has to rebuild theme, message bridge and window lifecycle itself, with no way for the user to dock it back.
Proposal: any existing panel can be opened in its own window and moved back, with no plugin changes. Right-click the panel > "Open in new window" (also in the View menu); closing the window or "Move to main window" puts it back. It reuses the same secondary-window path as "Open note in new window", panels.show/hide/visible keep working, detached panels come back on the next start, and the panel window never becomes the active window, so workspace.selectedNote() and openNote keep following the main window. Two commands expose the same to plugins.
Locally, I let Fable 5.1 propose the change and just tested a working PoC on the Windows Joplin Desktop app with tests. Ready for PR if you're interested.
The thing with right-click is that it means we would take over that action, while the plugin might want to support right-click too. Programmatic support for something like joplin.views.panels.detach() / attach() could be easier probably.
Anything with UI I think would involve adding some kind of small header bar on each panel which would allow detaching and attaching back the bar, but that's a big change
@JaneX8 Maybe you can use the trick I used in Excalidraw plugin? I have an option to open drawing in a separate window - I first open a new note window, then take all space of this window for Excalidraw plugin. It works relatively well - opens new window with Excalidraw on the full window size in one second.
@laurent Indeed, that's a cleaner shape. I let Claude rework the PoC to an API only, no app UI; short demo video below.
await joplin.views.panels.detach(handle); // show the panel in its own window
await joplin.views.panels.attach(handle); // move it back
await joplin.views.panels.isDetached(handle); // boolean
The plugin owns the button or command, and if it wants the window back after a restart it stores that itself and calls detach() in onStart. Behaviour: the window is titled after the plugin, closing it moves the panel back, show/hide/visible keep working, and the panel window never becomes the active window, so selectedNote() and openNote keep following the main window. Wired like views.dialogs through the platform implementation, desktop only. Also has unit tests and a Playwright test that drives the API from a test plugin.
Ready to fork and open the PR if this works for you.
@pmslava Thanks, nice trick, and it makes sense for Excalidraw where the drawing belongs to one note. I looked at how it's done (openNoteInNewWindow, wait for onNoteSelectionChange, then open a dialog in the focused window) and I think it doesn't fit a cross-note panel like the Task Dashboard:
It needs a note to open the window, so a dashboard would need a placeholder note in every notebook set-up, synced along.
The note window becomes the active window, so workspace.selectedNote() returns the placeholder note and openNote from the dashboard opens notes in the dashboard window, not the main one. The detach() PoC keeps the panel window out of focus tracking for exactly this reason.
It's a dialog, not the panel: panels.*, show/hide/visible and the panel's scripts don't carry over, and, as your README says, Joplin gives no notice when the window is closed. With detach() the panel simply goes back to the main window.
So I still think a small API is the right place for this.
By the way, I don't necessarily need a fullscreen window but a separate window. I have a setup where I use three displays. And I dont want the panels 'notebook > notes > editor > preview > plugin' in one window. But move the plugin window to a different display. While they still interact. So when I select a note the plugin windows act on it too and vise versa when I click something in the plugin window there might be some changes in the notes panel.