8000 feat: add panel support for BrowserWindow by isailaandrei · Pull Request #34388 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

feat: add panel support for BrowserWindow #34388

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

Merged
merged 8 commits into from
Jun 14, 2022

Conversation

isailaandrei
Copy link
Contributor
@isailaandrei isailaandrei commented May 31, 2022

Description of Change

Created a new ElectronNSPanel window which inherits from ElectronNSWindow. This window mimics the behavior of NSPanel - visible on top of full screened apps, joins all spaces. To achieve this it adds the "NSWindowStyleMaskNonactivatingPanel" style mask, normally reserved for NSPanel, at runtime.

This is a workaround to avoid patching chromium and duplicating lots of window code.

Checklist

Release Notes

notes: Added support for panel-like behavior. Window can float over full-screened apps.

@welcome
Copy link
welcome bot commented May 31, 2022

💖 Thanks for opening this pull request! 💖

We use semantic commit messages to streamline the release process. Before your pull request can be merged, you should update your pull request title to start with a semantic prefix.

Examples of commit messages with semantic prefixes:

  • fix: don't overwrite prevent_default if default wasn't prevented
  • feat: add app.isPackaged() method
  • docs: app.isDefaultProtocolClient is now available on Linux

Things that will help get your PR across the finish line:

  • Follow the JavaScript, C++, and Python coding style.
  • Run npm run lint locally to catch formatting errors earlier.
  • Document any user-facing changes you've made following the documentation styleguide.
  • Include tests when adding/changing behavior.
  • Include screenshots and animated GIFs whenever possible.

We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened recently label May 31, 2022
@isailaandrei isailaandrei changed the title feat: add NSPanel support for BrowserWindow feat: add panel support for BrowserWindow May 31, 2022
Copy link
Member
@codebytere codebytere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for opening this PR - however, all new PRs, especially semver-minor or major PRs, must target main. Only then, when it's reviewed and merged, can it be backported to version branches.

Could you also talk a bit more in your PR body about the impetus for this PR? What use cases are you trying to address?

@codebytere codebytere added the semver/minor backwards-compatible functionality label May 31, 2022
@isailaandrei isailaandrei changed the base branch from 16-x-y to main May 31, 2022 14:54
@isailaandrei isailaandrei requested review from a team as code owners May 31, 2022 14:54
@isailaandrei isailaandrei changed the base branch from main to 16-x-y May 31, 2022 14:55
@mitchchn
Copy link
Contributor

Resolves #31538, #4939.

I really like this implementation of panels overall, as it's similar to third-party solutions but safer and cleaner.

Pros

  • Eliminates the need for a third-party native module
  • Avoids runtime swizzling
  • Does not require patching Chromium + duplicating a ton of window code
  • API would be forward compatible if the implementation ever changed to use a true NSPanel

Cons

  • This approach to emulating NSPanel may not work in future versions of macOS

Non-activating panels are such a useful and desirable part of modern apps (floating palettes are everywhere!) and I think the risk is manageable.

Still, it would be great to work toward replacing this implementation with a real NSPanel in the long term. If done right it would be a transparent change to users who adopt this API in its current form.

@isailaandrei isailaandrei force-pushed the andreiisaila/panel_support branch from c2a5559 to 6ef9d10 Compare June 2, 2022 14:11
@isailaandrei isailaandrei force-pushed the andreiisaila/panel_support branch from 6ef9d10 to 64e1e71 Compare June 2, 2022 14:32
@isailaandrei isailaandrei changed the base branch from 16-x-y to main June 2, 2022 14:33
@isailaandrei
Copy link
Contributor Author

Hey @codebytere

I changed the target branch to "main" as suggested and changed the wording in browser-window to make it more clear what this new type achieves i.e makes the window float on top of full-screened apps.

As per @mitchchn's comment, this pull request addresses a feature which has been previously requested. This is still obviously not the ideal solution, but a workaround.

Copy link
Contributor
@zcbenz zcbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8000

API LGTM

isailaandrei and others added 2 commits June 6, 2022 13:28
Co-authored-by: Cheng Zhao <github@zcbenz.com>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
@isailaandrei
Copy link
Contributor Author
isailaandrei commented Jun 6, 2022

Hey all,

We started using this patch internally and found a weird bug. If we toggle the "resizable" property on BrowserWindow with type = "panel" the height of the window increases by 28 points (which is height of titlebar on Mac).

I confirmed in Xcode that this is not a bug on the native implementation, so something is going wrong when SetCanResize and then Widget->OnSizeConstraintChanged() is called in chromium. I'm still looking into this, but wanted to share here in case anyone has experience with this and can pinpoint the issue more easily.

Screen recording showing the issue - google drive link

Fiddle code to repro:

const mainWindow = new BrowserWindow({
width: 200,
height: 200,
frame: false,
type: "panel"
});

let resizable = true;
setInterval(() => {
resizable = !resizable;
mainWindow.setResizable(resizable);
console.log(mainWindow.getBounds());
}, 2000);

@electron-cation electron-cation bot removed the new-pr 🌱 PR opened recently label Jun 7, 2022
@zcbenz
Copy link
Contributor
zcbenz commented Jun 9, 2022

@isailaandrei Can you try placing ScopedDisableResize disable_resize; in the beginning of NativeWindowMac::SetResizable?

@zcbenz zcbenz requested a review from codebytere June 13, 2022 06:56
Copy link
Member
@codebytere codebytere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API LGTM

@jkleinsc jkleinsc merged commit 21ef850 into electron:main Jun 14, 2022
@welcome
Copy link
welcome bot commented Jun 14, 2022

Congrats on merging your first pull request! 🎉🎉🎉

@release-clerk
Copy link
release-clerk bot commented Jun 14, 2022

Release Notes Persisted

Added support for panel-like behavior. Window can float over full-screened apps.

@miniak
Copy link
Contributor
miniak commented Jun 20, 2022

/trop run backport-to 20-x-y

@trop
Copy link
Contributor
trop bot commented Jun 20, 2022

The backport process for this PR has been manually initiated - sending your PR to 20-x-y!

@trop
Copy link
Contributor
trop bot commented Jun 20, 2022

I have automatically backported this PR to "20-x-y", please check out #34665

@Hupka
Copy link
Hupka commented Sep 28, 2022

Hey folks!

A question: this implementation indeed makes the window/panel appear without taking focus. But it now also can't react to hover events anymore... 🤔 Would you know which additional properties would do this?

Best,
Adrian

khalwa pushed a commit to solarwindscloud/electron that referenced this pull request Feb 22, 2023
* feat: add NSPanel support for BrowserWindow

* change header guard to satisfy linter

* change panel wording in browser-window

* Revert "change panel wording in browser-window"

This reverts commit 6f3f80f.

* change wording in browser-window

* Update shell/browser/ui/cocoa/electron_native_widget_mac.mm

Co-authored-by: Cheng Zhao <github@zcbenz.com>

* Update shell/browser/ui/cocoa/electron_native_widget_mac.h

Co-authored-by: Cheng Zhao <github@zcbenz.com>

* Changed ScopedDisableResize class to allow for nesting

Co-authored-by: andreiisaila <andreiisaila@microsoft.com>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
@mp-jarvie
Copy link

NSWindow does not support nonactivating panel styleMask 0x80

1 similar comment
@OmarHedeya95
Copy link

NSWindow does not support nonactivating panel styleMask 0x80

@acemtp
Copy link
acemtp commented May 24, 2024

Hello,

Is it normal that the official doc has no information about type: "panel" ?

I spent lot of time figuring how to do that :-)

@jbriales
Copy link

Hello,

Is it normal that the official doc has no information about type: "panel" ?

I spent lot of time figuring how to do that :-)

Agree. It seems it's documented in https://www.electronjs.org/docs/latest/api/structures/base-window-options and even then it's hard to find, since one wouldn't know up-front this kind of window is a "panel".

Maybe adding a corresponding section within https://www.electronjs.org/docs/latest/tutorial/window-customization would help with discoverability here?
If that's deemed valuable I can try and add it myself :)

jbriales added a commit to jbriales/electron that referenced this pull request Aug 21, 2024
@jbriales
Copy link
jbriales commented Aug 21, 2024

Also @isailaandrei what's the expected behavior of this type="panel" option wrt others like frame: false or resizable: false.
Are they incompatible/overriden/ignored?

@jbriales
Copy link

On close inspection this does not seem to be working for me (I was confused because I still had other options that made the window look like a panel ON).

I'm seeing this when running a toy example:

Electron[56400:9037088] NSWindow does not support nonactivating panel styleMask 0x80

Any hints? I'm on Sonoma 14.5

@acemtp
Copy link
acemtp commented Aug 21, 2024

We also have this message and it works fine, it's just informative.

@jbriales
Copy link

After some days using this, it seems it generally works although still it has some rough edges.
E.g. (it seems) by using a normal window vs actual panel under the hood it doesn't get transparent to tools using the Accessibility API such as the Yabai WM: koekeishiya/yabai#2397
This causes some edge-cases and problems in there.

@isailaandrei are there any ideas in the horizon from initial discussions on how to achieve a more panel-like identity...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver/minor backwards-compatible functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0