Skip to content
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

feat: add panel support for BrowserWindow #34388

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 in the last 24 hours 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 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
Member

@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.

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 in the last 24 hours label Jun 7, 2022
@zcbenz
Copy link
Member

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

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.

None yet

8 participants