feat: add panel support for BrowserWindow (#34388)
* 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 6f3f80f94a7040e1d612a2a65952753bbafd437d. * 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>
This commit is contained in:
parent
bed38e0985
commit
21ef8501e7
9 changed files with 92 additions and 9 deletions
|
@ -425,13 +425,17 @@ Possible values are:
|
||||||
|
|
||||||
* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
|
* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
|
||||||
`notification`.
|
`notification`.
|
||||||
* On macOS, possible types are `desktop`, `textured`.
|
* On macOS, possible types are `desktop`, `textured`, `panel`.
|
||||||
* The `textured` type adds metal gradient appearance
|
* The `textured` type adds metal gradient appearance
|
||||||
(`NSWindowStyleMaskTexturedBackground`).
|
(`NSWindowStyleMaskTexturedBackground`).
|
||||||
* The `desktop` type places the window at the desktop background window level
|
* The `desktop` type places the window at the desktop background window level
|
||||||
(`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
|
(`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
|
||||||
focus, keyboard or mouse events, but you can use `globalShortcut` to receive
|
focus, keyboard or mouse events, but you can use `globalShortcut` to receive
|
||||||
input sparingly.
|
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`.
|
* On Windows, possible type is `toolbar`.
|
||||||
|
|
||||||
### Instance Events
|
### Instance Events
|
||||||
|
|
|
@ -165,6 +165,8 @@ filenames = {
|
||||||
"shell/browser/ui/cocoa/electron_native_widget_mac.mm",
|
"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.h",
|
||||||
"shell/browser/ui/cocoa/electron_ns_window_delegate.mm",
|
"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.h",
|
||||||
"shell/browser/ui/cocoa/electron_ns_window.mm",
|
"shell/browser/ui/cocoa/electron_ns_window.mm",
|
||||||
"shell/browser/ui/cocoa/electron_preview_item.h",
|
"shell/browser/ui/cocoa/electron_preview_item.h",
|
||||||
|
|
|
@ -317,7 +317,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
params.bounds = bounds;
|
params.bounds = bounds;
|
||||||
params.delegate = this;
|
params.delegate = this;
|
||||||
params.type = views::Widget::InitParams::TYPE_WINDOW;
|
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));
|
widget()->Init(std::move(params));
|
||||||
SetCanResize(resizable);
|
SetCanResize(resizable);
|
||||||
window_ = static_cast<ElectronNSWindow*>(
|
window_ = static_cast<ElectronNSWindow*>(
|
||||||
|
@ -355,6 +356,10 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
||||||
NSWindowCollectionBehaviorIgnoresCycle)];
|
NSWindowCollectionBehaviorIgnoresCycle)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (windowType == "panel") {
|
||||||
|
[window_ setLevel:NSFloatingWindowLevel];
|
||||||
|
}
|
||||||
|
|
||||||
bool focusable;
|
bool focusable;
|
||||||
if (options.Get(options::kFocusable, &focusable) && !focusable)
|
if (options.Get(options::kFocusable, &focusable) && !focusable)
|
||||||
[window_ setDisableKeyOrMainWindow:YES];
|
[window_ setDisableKeyOrMainWindow:YES];
|
||||||
|
@ -807,6 +812,7 @@ void NativeWindowMac::MoveTop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetResizable(bool resizable) {
|
void NativeWindowMac::SetResizable(bool resizable) {
|
||||||
|
ScopedDisableResize disable_resize;
|
||||||
SetStyleMask(resizable, NSWindowStyleMaskResizable);
|
SetStyleMask(resizable, NSWindowStyleMaskResizable);
|
||||||
SetCanResize(resizable);
|
SetCanResize(resizable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#ifndef ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NATIVE_WIDGET_MAC_H_
|
#ifndef ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_NATIVE_WIDGET_MAC_H_
|
||||||
#define 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"
|
#include "ui/views/widget/native_widget_mac.h"
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
@ -14,6 +16,7 @@ class NativeWindowMac;
|
||||||
class ElectronNativeWidgetMac : public views::NativeWidgetMac {
|
class ElectronNativeWidgetMac : public views::NativeWidgetMac {
|
||||||
public:
|
public:
|
||||||
ElectronNativeWidgetMac(NativeWindowMac* shell,
|
ElectronNativeWidgetMac(NativeWindowMac* shell,
|
||||||
|
const std::string& window_type,
|
||||||
NSUInteger style_mask,
|
NSUInteger style_mask,
|
||||||
views::internal::NativeWidgetDelegate* delegate);
|
views::internal::NativeWidgetDelegate* delegate);
|
||||||
~ElectronNativeWidgetMac() override;
|
~ElectronNativeWidgetMac() override;
|
||||||
|
@ -29,6 +32,7 @@ class ElectronNativeWidgetMac : public views::NativeWidgetMac {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NativeWindowMac* shell_;
|
NativeWindowMac* shell_;
|
||||||
|
std::string window_type_;
|
||||||
NSUInteger style_mask_;
|
NSUInteger style_mask_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,24 +4,34 @@
|
||||||
|
|
||||||
#include "shell/browser/ui/cocoa/electron_native_widget_mac.h"
|
#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"
|
#include "shell/browser/ui/cocoa/electron_ns_window.h"
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
ElectronNativeWidgetMac::ElectronNativeWidgetMac(
|
ElectronNativeWidgetMac::ElectronNativeWidgetMac(
|
||||||
NativeWindowMac* shell,
|
NativeWindowMac* shell,
|
||||||
|
const std::string& window_type,
|
||||||
NSUInteger style_mask,
|
NSUInteger style_mask,
|
||||||
views::internal::NativeWidgetDelegate* delegate)
|
views::internal::NativeWidgetDelegate* delegate)
|
||||||
: views::NativeWidgetMac(delegate),
|
: views::NativeWidgetMac(delegate),
|
||||||
shell_(shell),
|
shell_(shell),
|
||||||
|
window_type_(window_type),
|
||||||
style_mask_(style_mask) {}
|
style_mask_(style_mask) {}
|
||||||
|
|
||||||
ElectronNativeWidgetMac::~ElectronNativeWidgetMac() = default;
|
ElectronNativeWidgetMac::~ElectronNativeWidgetMac() = default;
|
||||||
|
|
||||||
NativeWidgetMacNSWindow* ElectronNativeWidgetMac::CreateNSWindow(
|
NativeWidgetMacNSWindow* ElectronNativeWidgetMac::CreateNSWindow(
|
||||||
const remote_cocoa::mojom::CreateWindowParams* params) {
|
const remote_cocoa::mojom::CreateWindowParams* params) {
|
||||||
return [[[ElectronNSWindow alloc] initWithShell:shell_
|
if (window_type_ == "panel") {
|
||||||
styleMask:style_mask_] autorelease];
|
return [[[ElectronNSPanel alloc] initWithShell:shell_
|
||||||
|
styleMask:style_mask_] autorelease];
|
||||||
|
} else {
|
||||||
|
return [[[ElectronNSWindow alloc] initWithShell:shell_
|
||||||
|
styleMask:style_mask_] autorelease];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
17
shell/browser/ui/cocoa/electron_ns_panel.h
Normal file
17
shell/browser/ui/cocoa/electron_ns_panel.h
Normal file
|
@ -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
shell/browser/ui/cocoa/electron_ns_panel.mm
Normal file
39
shell/browser/ui/cocoa/electron_ns_panel.mm
Normal file
|
@ -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
|
|
@ -16,13 +16,14 @@ class NativeWindowMac;
|
||||||
// Prevents window from resizing during the scope.
|
// Prevents window from resizing during the scope.
|
||||||
class ScopedDisableResize {
|
class ScopedDisableResize {
|
||||||
public:
|
public:
|
||||||
ScopedDisableResize() { disable_resize_ = true; }
|
ScopedDisableResize() { disable_resize_++; }
|
||||||
~ScopedDisableResize() { disable_resize_ = false; }
|
~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:
|
private:
|
||||||
static bool disable_resize_;
|
static int disable_resize_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
bool ScopedDisableResize::disable_resize_ = false;
|
int ScopedDisableResize::disable_resize_ = 0;
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue