New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request]: Create panel windows (NSPanel) on macOS #31538
Comments
Hello @mitchchn, at Akiflow we have built a package to convert nswindow to nspanel: https://github.com/akiflow/electron-panel-window We are currently using it with electron 13 (but it should work on electron 15 as well) and macOS Big Sur (I haven't yet tested it on Monterey yet). If you have any issue with it feel free to report it. |
@oltreseba electron-panel-window crashed with |
@oltreseba Unfortunately, your solution for Big Sur is still limited by what is possible with NSWindow. It can't appear over a fullscreen window without hiding the Dock, and it can't appear without activating its own app and showing other windows. I do not see a solution other than patching Chromium on the Electron side. I don't think such a patch would be accepted upstream, since Chromium has no need to create panel windows. |
To us is actually working 100%, you can check our app, and we don't have any of these limitations. |
@oltreseba I did check it out! Your solution is pretty close but it's not all the way there. For example, the Akiflow panel still has an invisible titlebar area at the top, and clicking it activates the app. I've been doing some explorations here with different techniques: The best combination I've found so far is:
An alternative to 2) is to remove the titlebar area, but it's not as straightforward or safe. But after all that experimentation I still believe the best solution is for Electron to create a real NSPanel. Otherwise we are just working with undefined behaviour. We are tantalizingly close; changing one line of code in Chromium produces flawless panel windows. From:
to
But of course this turns every window into panel. If there is a simple way to duplicate the class definition (at runtime?) without creating a giant patch, this would be the way to go. |
I'm closing this as it was implemented in #34388 👍 |
Preflight Checklist
Problem Description
Panel windows on macOS (NSPanel) are used to create floating command palettes (like Spotlight), menu bar apps, and other ephemeral UIs.
Panels support unique interactions with the OS which are important to these kinds of user interfaces. Most importantly, they can be the key window without becoming the main window, which means they receive keyboard input without otherwise stealing focus. Panels can also float over full screen apps.
It is not possible to create panel windows in Electron or fully emulate these behaviours by other means.
Proposed Solution
An API to create panel windows on macOS, e.g.:
That's pretty straightforward. The hard part is creating a renderer within an
NSPanel
instead ofNSWindow
. This would likely require a Chromium patch, as proposed by @proxi in this PoC: #26596 (comment). It's a lot of code, but most of it is duplicating functionality shared by the two classes.Perhaps there is a cleaner way to delegate the shared methods, or a better method altogether. I'd love to know what the API working group thinks.
Alternatives Considered
Previously, libraries could create panel windows by swizzling the
NSWindow
instance at runtime. This is no longer possible in macOS Big Sur (#26596).As of Electron 15 and Big Sur, the closest way to approximate a panel window is to create a frameless window that can appear over fullscreen apps on all workspaces:
But this window grabs focus from other windows, unlike a panel, and
visibleOnFullScreen
has the additional consequence of hiding the Dock icon (#26350) and creating window management issues when other application windows are open at the same time.The text was updated successfully, but these errors were encountered: