Skip to content

Commit

Permalink
feat: add panel support for BrowserWindow (#34665)
Browse files Browse the repository at this point in the history
* 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: isailaandrei <isailaandrei.i@gmail.com>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
  • Loading branch information
4 people committed Jun 22, 2022
1 parent 46d609f commit c48e0b8
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 9 deletions.
6 changes: 5 additions & 1 deletion docs/api/browser-window.md
Expand Up @@ -425,13 +425,17 @@ Possible values are:

* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
`notification`.
* On macOS, possible types are `desktop`, `textured`.
* On macOS, possible types are `desktop`, `textured`, `panel`.
* The `textured` type adds metal gradient appearance
(`NSWindowStyleMaskTexturedBackground`).
* The `desktop` type places the window at the desktop background window level
(`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
focus, keyboard or mouse events, but you can use `globalShortcut` to receive
input sparingly.
* The `panel` type enables the window to float on top of full-screened apps
by adding the `NSWindowStyleMaskNonactivatingPanel` style mask,normally
reserved for NSPanel, at runtime. Also, the window will appear on all
spaces (desktops).
* On Windows, possible type is `toolbar`.

### Instance Events
Expand Down
2 changes: 2 additions & 0 deletions filenames.gni
Expand Up @@ -167,6 +167,8 @@ filenames = {
"shell/browser/ui/cocoa/electron_native_widget_mac.mm",
"shell/browser/ui/cocoa/electron_ns_window_delegate.h",
"shell/browser/ui/cocoa/electron_ns_window_delegate.mm",
"shell/browser/ui/cocoa/electron_ns_panel.h",
"shell/browser/ui/cocoa/electron_ns_panel.mm",
"shell/browser/ui/cocoa/electron_ns_window.h",
"shell/browser/ui/cocoa/electron_ns_window.mm",
"shell/browser/ui/cocoa/electron_preview_item.h",
Expand Down
8 changes: 7 additions & 1 deletion shell/browser/native_window_mac.mm
Expand Up @@ -317,7 +317,8 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
params.bounds = bounds;
params.delegate = this;
params.type = views::Widget::InitParams::TYPE_WINDOW;
params.native_widget = new ElectronNativeWidgetMac(this, styleMask, widget());
params.native_widget =
new ElectronNativeWidgetMac(this, windowType, styleMask, widget());
widget()->Init(std::move(params));
SetCanResize(resizable);
window_ = static_cast<ElectronNSWindow*>(
Expand Down Expand Up @@ -355,6 +356,10 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
NSWindowCollectionBehaviorIgnoresCycle)];
}

if (windowType == "panel") {
[window_ setLevel:NSFloatingWindowLevel];
}

bool focusable;
if (options.Get(options::kFocusable, &focusable) && !focusable)
[window_ setDisableKeyOrMainWindow:YES];
Expand Down Expand Up @@ -811,6 +816,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

void NativeWindowMac::SetResizable(bool resizable) {
ScopedDisableResize disable_resize;
SetStyleMask(resizable, NSWindowStyleMaskResizable);
SetCanResize(resizable);
}
Expand Down
4 changes: 4 additions & 0 deletions shell/browser/ui/cocoa/electron_native_widget_mac.h
Expand Up @@ -5,6 +5,8 @@
#ifndef ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NATIVE_WIDGET_MAC_H_
#define ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NATIVE_WIDGET_MAC_H_

#include <string>

#include "ui/views/widget/native_widget_mac.h"

namespace electron {
Expand All @@ -14,6 +16,7 @@ class NativeWindowMac;
class ElectronNativeWidgetMac : public views::NativeWidgetMac {
public:
ElectronNativeWidgetMac(NativeWindowMac* shell,
const std::string& window_type,
NSUInteger style_mask,
views::internal::NativeWidgetDelegate* delegate);
~ElectronNativeWidgetMac() override;
Expand All @@ -29,6 +32,7 @@ class ElectronNativeWidgetMac : public views::NativeWidgetMac {

private:
NativeWindowMac* shell_;
std::string window_type_;
NSUInteger style_mask_;
};

Expand Down
14 changes: 12 additions & 2 deletions shell/browser/ui/cocoa/electron_native_widget_mac.mm
Expand Up @@ -4,24 +4,34 @@

#include "shell/browser/ui/cocoa/electron_native_widget_mac.h"

#include <string>

#include "shell/browser/ui/cocoa/electron_ns_panel.h"
#include "shell/browser/ui/cocoa/electron_ns_window.h"

namespace electron {

ElectronNativeWidgetMac::ElectronNativeWidgetMac(
NativeWindowMac* shell,
const std::string& window_type,
NSUInteger style_mask,
views::internal::NativeWidgetDelegate* delegate)
: views::NativeWidgetMac(delegate),
shell_(shell),
window_type_(window_type),
style_mask_(style_mask) {}

ElectronNativeWidgetMac::~ElectronNativeWidgetMac() = default;

NativeWidgetMacNSWindow* ElectronNativeWidgetMac::CreateNSWindow(
const remote_cocoa::mojom::CreateWindowParams* params) {
return [[[ElectronNSWindow alloc] initWithShell:shell_
styleMask:style_mask_] autorelease];
if (window_type_ == "panel") {
return [[[ElectronNSPanel alloc] initWithShell:shell_
styleMask:style_mask_] autorelease];
} else {
return [[[ElectronNSWindow alloc] initWithShell:shell_
styleMask:style_mask_] autorelease];
}
}

} // namespace electron
17 changes: 17 additions & 0 deletions shell/browser/ui/cocoa/electron_ns_panel.h
@@ -0,0 +1,17 @@
// Copyright (c) 2022 Microsoft, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#ifndef ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NS_PANEL_H_
#define ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NS_PANEL_H_

#include "shell/browser/ui/cocoa/electron_ns_window.h"

@interface ElectronNSPanel : ElectronNSWindow
@property NSWindowStyleMask styleMask;
@property NSWindowStyleMask originalStyleMask;
- (id)initWithShell:(electron::NativeWindowMac*)shell
styleMask:(NSUInteger)styleMask;
@end

#endif // ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NS_PANEL_H_
39 changes: 39 additions & 0 deletions shell/browser/ui/cocoa/electron_ns_panel.mm
@@ -0,0 +1,39 @@
// Copyright (c) 2022 Microsoft, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/browser/ui/cocoa/electron_ns_panel.h"

@implementation ElectronNSPanel

@synthesize originalStyleMask;

- (id)initWithShell:(electron::NativeWindowMac*)shell
styleMask:(NSUInteger)styleMask {
if (self = [super initWithShell:shell styleMask:styleMask]) {
originalStyleMask = styleMask;
}
return self;
}

@dynamic styleMask;
// The Nonactivating mask is reserverd for NSPanel,
// but we can use this workaround to add it at runtime
- (NSWindowStyleMask)styleMask {
return originalStyleMask | NSWindowStyleMaskNonactivatingPanel;
}

- (void)setStyleMask:(NSWindowStyleMask)styleMask {
originalStyleMask = styleMask;
// Notify change of style mask.
[super setStyleMask:styleMask];
}

- (void)setCollectionBehavior:(NSWindowCollectionBehavior)collectionBehavior {
NSWindowCollectionBehavior panelBehavior =
(NSWindowCollectionBehaviorCanJoinAllSpaces |
NSWindowCollectionBehaviorFullScreenAuxiliary);
[super setCollectionBehavior:collectionBehavior | panelBehavior];
}

@end
9 changes: 5 additions & 4 deletions shell/browser/ui/cocoa/electron_ns_window.h
Expand Up @@ -16,13 +16,14 @@ class NativeWindowMac;
// Prevents window from resizing during the scope.
class ScopedDisableResize {
public:
ScopedDisableResize() { disable_resize_ = true; }
~ScopedDisableResize() { disable_resize_ = false; }
ScopedDisableResize() { disable_resize_++; }
~ScopedDisableResize() { disable_resize_--; }

static bool IsResizeDisabled() { return disable_resize_; }
// True if there are 1+ nested ScopedDisableResize objects in the scope
static bool IsResizeDisabled() { return disable_resize_ > 0; }

private:
static bool disable_resize_;
static int disable_resize_;
};

} // namespace electron
Expand Down
2 changes: 1 addition & 1 deletion shell/browser/ui/cocoa/electron_ns_window.mm
Expand Up @@ -13,7 +13,7 @@

namespace electron {

bool ScopedDisableResize::disable_resize_ = false;
int ScopedDisableResize::disable_resize_ = 0;

} // namespace electron

Expand Down

0 comments on commit c48e0b8

Please sign in to comment.