refactor: use views::Widget on macOS

This commit is contained in:
Cheng Zhao 2018-04-24 17:23:08 +09:00
parent 7c4964fae6
commit 75a624434c
8 changed files with 72 additions and 26 deletions

View file

@ -23,7 +23,8 @@
namespace atom { namespace atom {
class NativeWindowMac : public NativeWindow { class NativeWindowMac : public NativeWindow,
public views::WidgetDelegate {
public: public:
NativeWindowMac(const mate::Dictionary& options, NativeWindow* parent); NativeWindowMac(const mate::Dictionary& options, NativeWindow* parent);
~NativeWindowMac() override; ~NativeWindowMac() override;
@ -144,19 +145,25 @@ class NativeWindowMac : public NativeWindow {
bool fullscreen_window_title() const { return fullscreen_window_title_; } bool fullscreen_window_title() const { return fullscreen_window_title_; }
bool simple_fullscreen() const { return always_simple_fullscreen_; } bool simple_fullscreen() const { return always_simple_fullscreen_; }
protected:
// views::WidgetDelegate:
void DeleteDelegate() override;
views::Widget* GetWidget() override;
const views::Widget* GetWidget() const override;
private: private:
void InternalSetParentWindow(NativeWindow* parent, bool attach); void InternalSetParentWindow(NativeWindow* parent, bool attach);
void ShowWindowButton(NSWindowButton button); void ShowWindowButton(NSWindowButton button);
void SetForwardMouseMessages(bool forward); void SetForwardMouseMessages(bool forward);
base::scoped_nsobject<AtomNSWindow> window_; std::unique_ptr<views::Widget> widget_;
AtomNSWindow* window_; // Weak ref, managed by widget_.
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_; base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
base::scoped_nsobject<AtomPreviewItem> preview_item_; base::scoped_nsobject<AtomPreviewItem> preview_item_;
base::scoped_nsobject<AtomTouchBar> touch_bar_; base::scoped_nsobject<AtomTouchBar> touch_bar_;
std::unique_ptr<views::Widget> widget_;
// Event monitor for scroll wheel event. // Event monitor for scroll wheel event.
id wheel_event_monitor_; id wheel_event_monitor_;

View file

@ -9,6 +9,7 @@
#include <string> #include <string>
#include "atom/browser/native_browser_view_mac.h" #include "atom/browser/native_browser_view_mac.h"
#include "atom/browser/ui/cocoa/atom_native_widget_mac.h"
#include "atom/browser/ui/cocoa/atom_ns_window.h" #include "atom/browser/ui/cocoa/atom_ns_window.h"
#include "atom/browser/ui/cocoa/atom_ns_window_delegate.h" #include "atom/browser/ui/cocoa/atom_ns_window_delegate.h"
#include "atom/browser/ui/cocoa/atom_preview_item.h" #include "atom/browser/ui/cocoa/atom_preview_item.h"
@ -247,9 +248,10 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
options.Get(options::kHeight, &height); options.Get(options::kHeight, &height);
NSRect main_screen_rect = [[[NSScreen screens] firstObject] frame]; NSRect main_screen_rect = [[[NSScreen screens] firstObject] frame];
NSRect cocoa_bounds = NSMakeRect( gfx::Rect bounds(round((NSWidth(main_screen_rect) - width) / 2),
round((NSWidth(main_screen_rect) - width) / 2), round((NSHeight(main_screen_rect) - height) / 2),
round((NSHeight(main_screen_rect) - height) / 2), width, height); width,
height);
bool resizable = true; bool resizable = true;
options.Get(options::kResizable, &resizable); options.Get(options::kResizable, &resizable);
@ -303,10 +305,18 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
styleMask |= NSResizableWindowMask; styleMask |= NSResizableWindowMask;
} }
window_.reset([[AtomNSWindow alloc] initWithContentRect:cocoa_bounds // Create views::Widget and assign window_ with it.
styleMask:styleMask // TODO(zcbenz): Get rid of the window_ in future.
backing:NSBackingStoreBuffered widget_.reset(new views::Widget());
defer:YES]); views::Widget::InitParams params;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = bounds;
params.delegate = this;
params.type = views::Widget::InitParams::TYPE_WINDOW;
params.native_widget = new AtomNativeWidgetMac(styleMask, widget_.get());
widget_->Init(params);
window_ = static_cast<AtomNSWindow*>(widget_->GetNativeWindow());
[window_ setShell:this]; [window_ setShell:this];
[window_ setEnableLargerThanScreen:enable_larger_than_screen()]; [window_ setEnableLargerThanScreen:enable_larger_than_screen()];
@ -357,9 +367,6 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
} }
} }
// We will manage window's lifetime ourselves.
[window_ setReleasedWhenClosed:NO];
// Hide the title bar background // Hide the title bar background
if (title_bar_style_ != NORMAL) { if (title_bar_style_ != NORMAL) {
if (@available(macOS 10.10, *)) { if (@available(macOS 10.10, *)) {
@ -384,7 +391,7 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
bool use_content_size = false; bool use_content_size = false;
options.Get(options::kUseContentSize, &use_content_size); options.Get(options::kUseContentSize, &use_content_size);
if (!has_frame() || !use_content_size) if (!has_frame() || !use_content_size)
SetSize(gfx::Size(width, height)); NativeWindow::SetSize(gfx::Size(width, height));
options.Get(options::kZoomToPageWidth, &zoom_to_page_width_); options.Get(options::kZoomToPageWidth, &zoom_to_page_width_);
@ -1145,7 +1152,7 @@ void NativeWindowMac::ToggleTabBar() {
} }
bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) { bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
if (window_.get() == window->GetNativeWindow()) { if (window_ == window->GetNativeWindow()) {
return false; return false;
} else { } else {
if (@available(macOS 10.12, *)) if (@available(macOS 10.12, *))
@ -1289,6 +1296,17 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
} }
} }
void NativeWindowMac::DeleteDelegate() {
}
views::Widget* NativeWindowMac::GetWidget() {
return widget_.get();
}
const views::Widget* NativeWindowMac::GetWidget() const {
return widget_.get();
}
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent, void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
bool attach) { bool attach) {
if (is_modal()) if (is_modal())

View file

@ -11,7 +11,8 @@ namespace atom {
class AtomNativeWidgetMac : public views::NativeWidgetMac { class AtomNativeWidgetMac : public views::NativeWidgetMac {
public: public:
explicit AtomNativeWidgetMac(views::internal::NativeWidgetDelegate* delegate); AtomNativeWidgetMac(NSUInteger style_mask,
views::internal::NativeWidgetDelegate* delegate);
~AtomNativeWidgetMac() override; ~AtomNativeWidgetMac() override;
protected: protected:
@ -20,6 +21,8 @@ class AtomNativeWidgetMac : public views::NativeWidgetMac {
const views::Widget::InitParams& params) override; const views::Widget::InitParams& params) override;
private: private:
NSUInteger style_mask_;
DISALLOW_COPY_AND_ASSIGN(AtomNativeWidgetMac); DISALLOW_COPY_AND_ASSIGN(AtomNativeWidgetMac);
}; };

View file

@ -4,17 +4,26 @@
#include "atom/browser/ui/cocoa/atom_native_widget_mac.h" #include "atom/browser/ui/cocoa/atom_native_widget_mac.h"
#include "atom/browser/ui/cocoa/atom_ns_window.h"
#include "ui/base/cocoa/window_size_constants.h"
namespace atom { namespace atom {
AtomNativeWidgetMac::AtomNativeWidgetMac( AtomNativeWidgetMac::AtomNativeWidgetMac(
NSUInteger style_mask,
views::internal::NativeWidgetDelegate* delegate) views::internal::NativeWidgetDelegate* delegate)
: views::NativeWidgetMac(delegate) {} : views::NativeWidgetMac(delegate),
style_mask_(style_mask) {}
AtomNativeWidgetMac::~AtomNativeWidgetMac() {} AtomNativeWidgetMac::~AtomNativeWidgetMac() {}
NativeWidgetMacNSWindow* AtomNativeWidgetMac::CreateNSWindow( NativeWidgetMacNSWindow* AtomNativeWidgetMac::CreateNSWindow(
const views::Widget::InitParams& params) { const views::Widget::InitParams& params) {
return views::NativeWidgetMac::CreateNSWindow(params); return [[[AtomNSWindow alloc]
initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:style_mask_
backing:NSBackingStoreBuffered
defer:YES] autorelease];
} }
} // namespace atom } // namespace atom

View file

@ -26,7 +26,7 @@ class ScopedDisableResize {
} // namespace atom } // namespace atom
@interface AtomNSWindow : EventDispatchingWindow { @interface AtomNSWindow : NativeWidgetMacNSWindow {
@private @private
atom::NativeWindowMac* shell_; atom::NativeWindowMac* shell_;
CGFloat windowButtonsInterButtonSpacing_; CGFloat windowButtonsInterButtonSpacing_;

View file

@ -13,9 +13,9 @@ namespace atom {
class NativeWindowMac; class NativeWindowMac;
} }
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate, @interface AtomNSWindowDelegate :
NSTouchBarDelegate, ViewsNSWindowDelegate<NSTouchBarDelegate,
QLPreviewPanelDataSource> { QLPreviewPanelDataSource> {
@private @private
atom::NativeWindowMac* shell_; atom::NativeWindowMac* shell_;
bool is_zooming_; bool is_zooming_;

View file

@ -9,11 +9,21 @@
#include "atom/browser/ui/cocoa/atom_preview_item.h" #include "atom/browser/ui/cocoa/atom_preview_item.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.h" #include "atom/browser/ui/cocoa/atom_touch_bar.h"
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#include "ui/views/widget/native_widget_mac.h"
@implementation AtomNSWindowDelegate @implementation AtomNSWindowDelegate
- (id)initWithShell:(atom::NativeWindowMac*)shell { - (id)initWithShell:(atom::NativeWindowMac*)shell {
if ((self = [super init])) { // The views library assumes the window delegate must be an instance of
// ViewsNSWindowDelegate, since we don't have a way to override the creation
// of NSWindowDelegate, we have to dynamically replace the window delegate
// on the fly.
// TODO(zcbenz): Add interface in NativeWidgetMac to allow overriding creating
// window delegate.
views::BridgedNativeWidget* bridget_view =
views::NativeWidgetMac::GetBridgeForNativeWindow(
shell->GetNativeWindow());
if ((self = [super initWithBridgedNativeWidget:bridget_view])) {
shell_ = shell; shell_ = shell;
is_zooming_ = false; is_zooming_ = false;
level_ = [shell_->GetNativeWindow() level]; level_ = [shell_->GetNativeWindow() level];

View file

@ -16,8 +16,7 @@ ViewsDelegateMac::~ViewsDelegateMac() {}
void ViewsDelegateMac::OnBeforeWidgetInit( void ViewsDelegateMac::OnBeforeWidgetInit(
views::Widget::InitParams* params, views::Widget::InitParams* params,
views::internal::NativeWidgetDelegate* delegate) { views::internal::NativeWidgetDelegate* delegate) {
if (!params->native_widget) DCHECK(params->native_widget);
params->native_widget = new views::NativeWidgetMac(delegate);
} }
ui::ContextFactory* ViewsDelegateMac::GetContextFactory() { ui::ContextFactory* ViewsDelegateMac::GetContextFactory() {