From 75a624434cc30d445751bf45f95ef9138d0ea1a5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 24 Apr 2018 17:23:08 +0900 Subject: [PATCH] refactor: use views::Widget on macOS --- atom/browser/native_window_mac.h | 15 +++++-- atom/browser/native_window_mac.mm | 42 +++++++++++++------ .../browser/ui/cocoa/atom_native_widget_mac.h | 5 ++- .../ui/cocoa/atom_native_widget_mac.mm | 13 +++++- atom/browser/ui/cocoa/atom_ns_window.h | 2 +- .../ui/cocoa/atom_ns_window_delegate.h | 6 +-- .../ui/cocoa/atom_ns_window_delegate.mm | 12 +++++- atom/browser/ui/cocoa/views_delegate_mac.mm | 3 +- 8 files changed, 72 insertions(+), 26 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 42f24ccf169f..89bdec886d2a 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -23,7 +23,8 @@ namespace atom { -class NativeWindowMac : public NativeWindow { +class NativeWindowMac : public NativeWindow, + public views::WidgetDelegate { public: NativeWindowMac(const mate::Dictionary& options, NativeWindow* parent); ~NativeWindowMac() override; @@ -144,19 +145,25 @@ class NativeWindowMac : public NativeWindow { bool fullscreen_window_title() const { return fullscreen_window_title_; } 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: void InternalSetParentWindow(NativeWindow* parent, bool attach); void ShowWindowButton(NSWindowButton button); void SetForwardMouseMessages(bool forward); - base::scoped_nsobject window_; + std::unique_ptr widget_; + AtomNSWindow* window_; // Weak ref, managed by widget_. + base::scoped_nsobject window_delegate_; base::scoped_nsobject preview_item_; base::scoped_nsobject touch_bar_; - std::unique_ptr widget_; - // Event monitor for scroll wheel event. id wheel_event_monitor_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 35677e8c36fe..46b6da002fc1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -9,6 +9,7 @@ #include #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_delegate.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); NSRect main_screen_rect = [[[NSScreen screens] firstObject] frame]; - NSRect cocoa_bounds = NSMakeRect( - round((NSWidth(main_screen_rect) - width) / 2), - round((NSHeight(main_screen_rect) - height) / 2), width, height); + gfx::Rect bounds(round((NSWidth(main_screen_rect) - width) / 2), + round((NSHeight(main_screen_rect) - height) / 2), + width, + height); bool resizable = true; options.Get(options::kResizable, &resizable); @@ -303,10 +305,18 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options, styleMask |= NSResizableWindowMask; } - window_.reset([[AtomNSWindow alloc] initWithContentRect:cocoa_bounds - styleMask:styleMask - backing:NSBackingStoreBuffered - defer:YES]); + // Create views::Widget and assign window_ with it. + // TODO(zcbenz): Get rid of the window_ in future. + widget_.reset(new views::Widget()); + 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(widget_->GetNativeWindow()); + [window_ setShell:this]; [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 if (title_bar_style_ != NORMAL) { if (@available(macOS 10.10, *)) { @@ -384,7 +391,7 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options, bool use_content_size = false; options.Get(options::kUseContentSize, &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_); @@ -1145,7 +1152,7 @@ void NativeWindowMac::ToggleTabBar() { } bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) { - if (window_.get() == window->GetNativeWindow()) { + if (window_ == window->GetNativeWindow()) { return false; } else { 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, bool attach) { if (is_modal()) diff --git a/atom/browser/ui/cocoa/atom_native_widget_mac.h b/atom/browser/ui/cocoa/atom_native_widget_mac.h index 49250239f3b1..e5f711e80b65 100644 --- a/atom/browser/ui/cocoa/atom_native_widget_mac.h +++ b/atom/browser/ui/cocoa/atom_native_widget_mac.h @@ -11,7 +11,8 @@ namespace atom { class AtomNativeWidgetMac : public views::NativeWidgetMac { public: - explicit AtomNativeWidgetMac(views::internal::NativeWidgetDelegate* delegate); + AtomNativeWidgetMac(NSUInteger style_mask, + views::internal::NativeWidgetDelegate* delegate); ~AtomNativeWidgetMac() override; protected: @@ -20,6 +21,8 @@ class AtomNativeWidgetMac : public views::NativeWidgetMac { const views::Widget::InitParams& params) override; private: + NSUInteger style_mask_; + DISALLOW_COPY_AND_ASSIGN(AtomNativeWidgetMac); }; diff --git a/atom/browser/ui/cocoa/atom_native_widget_mac.mm b/atom/browser/ui/cocoa/atom_native_widget_mac.mm index eb7117790a69..9cb5da48bc11 100644 --- a/atom/browser/ui/cocoa/atom_native_widget_mac.mm +++ b/atom/browser/ui/cocoa/atom_native_widget_mac.mm @@ -4,17 +4,26 @@ #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 { AtomNativeWidgetMac::AtomNativeWidgetMac( + NSUInteger style_mask, views::internal::NativeWidgetDelegate* delegate) - : views::NativeWidgetMac(delegate) {} + : views::NativeWidgetMac(delegate), + style_mask_(style_mask) {} AtomNativeWidgetMac::~AtomNativeWidgetMac() {} NativeWidgetMacNSWindow* AtomNativeWidgetMac::CreateNSWindow( 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 diff --git a/atom/browser/ui/cocoa/atom_ns_window.h b/atom/browser/ui/cocoa/atom_ns_window.h index 62d690b57e31..885e19c6dcc4 100644 --- a/atom/browser/ui/cocoa/atom_ns_window.h +++ b/atom/browser/ui/cocoa/atom_ns_window.h @@ -26,7 +26,7 @@ class ScopedDisableResize { } // namespace atom -@interface AtomNSWindow : EventDispatchingWindow { +@interface AtomNSWindow : NativeWidgetMacNSWindow { @private atom::NativeWindowMac* shell_; CGFloat windowButtonsInterButtonSpacing_; diff --git a/atom/browser/ui/cocoa/atom_ns_window_delegate.h b/atom/browser/ui/cocoa/atom_ns_window_delegate.h index 0947b0392147..e86754bcf32c 100644 --- a/atom/browser/ui/cocoa/atom_ns_window_delegate.h +++ b/atom/browser/ui/cocoa/atom_ns_window_delegate.h @@ -13,9 +13,9 @@ namespace atom { class NativeWindowMac; } -@interface AtomNSWindowDelegate : NSObject { +@interface AtomNSWindowDelegate : + ViewsNSWindowDelegate { @private atom::NativeWindowMac* shell_; bool is_zooming_; diff --git a/atom/browser/ui/cocoa/atom_ns_window_delegate.mm b/atom/browser/ui/cocoa/atom_ns_window_delegate.mm index 92ab2293050f..b20a350cc7f2 100644 --- a/atom/browser/ui/cocoa/atom_ns_window_delegate.mm +++ b/atom/browser/ui/cocoa/atom_ns_window_delegate.mm @@ -9,11 +9,21 @@ #include "atom/browser/ui/cocoa/atom_preview_item.h" #include "atom/browser/ui/cocoa/atom_touch_bar.h" #include "base/mac/mac_util.h" +#include "ui/views/widget/native_widget_mac.h" @implementation AtomNSWindowDelegate - (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; is_zooming_ = false; level_ = [shell_->GetNativeWindow() level]; diff --git a/atom/browser/ui/cocoa/views_delegate_mac.mm b/atom/browser/ui/cocoa/views_delegate_mac.mm index 5e5ed6732267..25e72980367b 100644 --- a/atom/browser/ui/cocoa/views_delegate_mac.mm +++ b/atom/browser/ui/cocoa/views_delegate_mac.mm @@ -16,8 +16,7 @@ ViewsDelegateMac::~ViewsDelegateMac() {} void ViewsDelegateMac::OnBeforeWidgetInit( views::Widget::InitParams* params, views::internal::NativeWidgetDelegate* delegate) { - if (!params->native_widget) - params->native_widget = new views::NativeWidgetMac(delegate); + DCHECK(params->native_widget); } ui::ContextFactory* ViewsDelegateMac::GetContextFactory() {