diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 3842a4e2bee3..7a5ec7de18f7 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -150,9 +150,9 @@ void BrowserWindow::Init(v8::Isolate* isolate, // Creates BrowserWindow. window_.reset(NativeWindow::Create( - web_contents->managed_web_contents(), options, parent.IsEmpty() ? nullptr : parent->window_.get())); + window_->SetContentView(web_contents->managed_web_contents()); web_contents->SetOwnerWindow(window_.get()); // Tell the content module to initialize renderer widget with transparent diff --git a/atom/browser/common_web_contents_delegate_views.cc b/atom/browser/common_web_contents_delegate_views.cc index 28cac66a4c90..78009c2a8daa 100644 --- a/atom/browser/common_web_contents_delegate_views.cc +++ b/atom/browser/common_web_contents_delegate_views.cc @@ -38,7 +38,7 @@ void CommonWebContentsDelegate::ShowAutofillPopup( auto* window = static_cast(owner_window()); autofill_popup_->CreateView( - frame_host, offscreen, window->web_view(), bounds); + frame_host, offscreen, window->content_view(), bounds); autofill_popup_->SetItems(values, labels); } diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 1acf6dee4bd2..0a3db8cbf071 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -12,17 +12,14 @@ #include "atom/browser/window_list.h" #include "atom/common/color_util.h" #include "atom/common/options_switches.h" -#include "brightray/browser/inspectable_web_contents.h" #include "native_mate/dictionary.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); namespace atom { -NativeWindow::NativeWindow( - brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, - NativeWindow* parent) +NativeWindow::NativeWindow(const mate::Dictionary& options, + NativeWindow* parent) : has_frame_(true), transparent_(false), enable_larger_than_screen_(false), @@ -134,6 +131,12 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kKiosk, &kiosk) && kiosk) { SetKiosk(kiosk); } +#if defined(OS_MACOSX) + std::string type; + if (options.Get(options::kVibrancyType, &type)) { + SetVibrancy(type); + } +#endif std::string color; if (options.Get(options::kBackgroundColor, &color)) { SetBackgroundColor(ParseHexColor(color)); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 86f6f2166b07..2131574dcce6 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -11,13 +11,11 @@ #include #include "atom/browser/native_window_observer.h" -#include "atom/browser/ui/atom_menu_model.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/supports_user_data.h" #include "content/public/browser/web_contents_user_data.h" #include "extensions/browser/app_window/size_constraints.h" -#include "native_mate/persistent_dictionary.h" class SkRegion; @@ -39,10 +37,12 @@ class Size; namespace mate { class Dictionary; +class PersistentDictionary; } namespace atom { +class AtomMenuModel; class NativeBrowserView; struct DraggableRegion; @@ -53,13 +53,14 @@ class NativeWindow : public base::SupportsUserData { // Create window with existing WebContents, the caller is responsible for // managing the window's live. - static NativeWindow* Create( - brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, - NativeWindow* parent = nullptr); + static NativeWindow* Create(const mate::Dictionary& options, + NativeWindow* parent = nullptr); void InitFromOptions(const mate::Dictionary& options); + virtual void SetContentView( + brightray::InspectableWebContents* web_contents) = 0; + virtual void Close() = 0; virtual void CloseImmediately() = 0; virtual bool IsClosed() const { return is_closed_; } @@ -272,8 +273,7 @@ class NativeWindow : public base::SupportsUserData { bool is_modal() const { return is_modal_; } protected: - NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, + NativeWindow(const mate::Dictionary& options, NativeWindow* parent); void set_browser_view(NativeBrowserView* browser_view) { diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index cb89aa24c13d..9e4edaa2c0cc 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -21,12 +21,12 @@ namespace atom { class NativeWindowMac : public NativeWindow { public: - NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, + NativeWindowMac(const mate::Dictionary& options, NativeWindow* parent); ~NativeWindowMac() override; // NativeWindow: + void SetContentView(brightray::InspectableWebContents* web_contents) override; void Close() override; void CloseImmediately() override; void Focus(bool focus) override; @@ -141,8 +141,6 @@ class NativeWindowMac : public NativeWindow { void InternalSetParentWindow(NativeWindow* parent, bool attach); void ShowWindowButton(NSWindowButton button); - void InstallView(NSView* view); - void SetForwardMouseMessages(bool forward); base::scoped_nsobject window_; @@ -152,7 +150,10 @@ class NativeWindowMac : public NativeWindow { id wheel_event_monitor_; // The view that will fill the whole frameless window. - base::scoped_nsobject content_view_; + base::scoped_nsobject container_view_; + + // The content view passed by SetContentView, weak ref. + NSView* content_view_; bool is_kiosk_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 844bde3e0954..dfe5c2e360b9 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -776,11 +776,10 @@ struct Converter { namespace atom { -NativeWindowMac::NativeWindowMac( - brightray::InspectableWebContents* web_contents, - const mate::Dictionary& options, - NativeWindow* parent) - : NativeWindow(web_contents, options, parent), +NativeWindowMac::NativeWindowMac(const mate::Dictionary& options, + NativeWindow* parent) + : NativeWindow(options, parent), + content_view_(nil), is_kiosk_(false), was_fullscreen_(false), zoom_to_page_width_(false), @@ -952,9 +951,6 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); [window_ setDisableAutoHideCursor:disableAutoHideCursor]; - NSView* view = web_contents->GetView()->GetNativeView(); - [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - // Use an NSEvent monitor to listen for the wheel event. BOOL __block began = NO; wheel_event_monitor_ = [NSEvent @@ -975,13 +971,6 @@ NativeWindowMac::NativeWindowMac( return event; }]; - InstallView(web_contents->GetView()->GetNativeView()); - - std::string type; - if (options.Get(options::kVibrancyType, &type)) { - SetVibrancy(type); - } - // Set maximizable state last to ensure zoom button does not get reset // by calls to other APIs. SetMaximizable(maximizable); @@ -991,6 +980,76 @@ NativeWindowMac::~NativeWindowMac() { [NSEvent removeMonitor:wheel_event_monitor_]; } +void NativeWindowMac::SetContentView( + brightray::InspectableWebContents* web_contents) { + if (content_view_) + [content_view_ removeFromSuperview]; + + content_view_ = web_contents->GetView()->GetNativeView(); + [content_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + + // Make sure the bottom corner is rounded for non-modal windows: http://crbug.com/396264. + // But do not enable it on OS X 10.9 for transparent window, otherwise a + // semi-transparent frame would show. + if (!(transparent() && base::mac::IsOS10_9()) && !is_modal()) + [[window_ contentView] setWantsLayer:YES]; + + if (has_frame()) { + [content_view_ setFrame:[[window_ contentView] bounds]]; + [[window_ contentView] addSubview:content_view_]; + } else { + // In OSX 10.10, adding subviews to the root view for the NSView hierarchy + // produces warnings. To eliminate the warnings, we resize the contentView + // to fill the window, and add subviews to that. + // http://crbug.com/380412 + container_view_.reset([[FullSizeContentView alloc] init]); + [container_view_ + setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [container_view_ setFrame:[[[window_ contentView] superview] bounds]]; + + // Move the vibrantView from the old content view. + if ([window_ vibrantView]) { + [[window_ vibrantView] removeFromSuperview]; + [container_view_ addSubview:[window_ vibrantView] + positioned:NSWindowBelow + relativeTo:nil]; + } + + [window_ setContentView:container_view_]; + + [content_view_ setFrame:[container_view_ bounds]]; + [container_view_ addSubview:content_view_]; + + // The fullscreen button should always be hidden for frameless window. + [[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES]; + + if (title_bar_style_ == CUSTOM_BUTTONS_ON_HOVER) { + NSView* window_button_view = [[[CustomWindowButtonView alloc] + initWithFrame:NSZeroRect] autorelease]; + [container_view_ addSubview:window_button_view]; + } else { + if (title_bar_style_ != NORMAL) { + if (base::mac::IsOS10_9()) { + ShowWindowButton(NSWindowZoomButton); + ShowWindowButton(NSWindowMiniaturizeButton); + ShowWindowButton(NSWindowCloseButton); + } + return; + } + + // Hide the window buttons. + [[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES]; + [[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; + [[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES]; + } + + // Some third-party macOS utilities check the zoom button's enabled state to + // determine whether to show custom UI on hover, so we disable it here to + // prevent them from doing so in a frameless app window. + [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + } +} + void NativeWindowMac::Close() { // When this is a sheet showing, performClose won't work. if (is_modal() && parent() && IsVisible()) { @@ -1649,7 +1708,7 @@ void NativeWindowMac::SetVibrancy(const std::string& type) { return; } - background_color_before_vibrancy_.reset([window_ backgroundColor]); + background_color_before_vibrancy_.reset([[window_ backgroundColor] retain]); transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent]; ui::GpuSwitchingManager::SetTransparent(true); @@ -1775,60 +1834,6 @@ void NativeWindowMac::ShowWindowButton(NSWindowButton button) { [view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil]; } -void NativeWindowMac::InstallView(NSView* view) { - // Make sure the bottom corner is rounded for non-modal windows: http://crbug.com/396264. - // But do not enable it on OS X 10.9 for transparent window, otherwise a - // semi-transparent frame would show. - if (!(transparent() && base::mac::IsOS10_9()) && !is_modal()) - [[window_ contentView] setWantsLayer:YES]; - - if (has_frame()) { - [view setFrame:[[window_ contentView] bounds]]; - [[window_ contentView] addSubview:view]; - } else { - // In OSX 10.10, adding subviews to the root view for the NSView hierarchy - // produces warnings. To eliminate the warnings, we resize the contentView - // to fill the window, and add subviews to that. - // http://crbug.com/380412 - content_view_.reset([[FullSizeContentView alloc] init]); - [content_view_ - setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [content_view_ setFrame:[[[window_ contentView] superview] bounds]]; - [window_ setContentView:content_view_]; - - [view setFrame:[content_view_ bounds]]; - [content_view_ addSubview:view]; - - // The fullscreen button should always be hidden for frameless window. - [[window_ standardWindowButton:NSWindowFullScreenButton] setHidden:YES]; - - if (title_bar_style_ == CUSTOM_BUTTONS_ON_HOVER) { - NSView* window_button_view = [[[CustomWindowButtonView alloc] - initWithFrame:NSZeroRect] autorelease]; - [content_view_ addSubview:window_button_view]; - } else { - if (title_bar_style_ != NORMAL) { - if (base::mac::IsOS10_9()) { - ShowWindowButton(NSWindowZoomButton); - ShowWindowButton(NSWindowMiniaturizeButton); - ShowWindowButton(NSWindowCloseButton); - } - return; - } - - // Hide the window buttons. - [[window_ standardWindowButton:NSWindowZoomButton] setHidden:YES]; - [[window_ standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; - [[window_ standardWindowButton:NSWindowCloseButton] setHidden:YES]; - } - - // Some third-party macOS utilities check the zoom button's enabled state to - // determine whether to show custom UI on hover, so we disable it here to - // prevent them from doing so in a frameless app window. - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; - } -} - void NativeWindowMac::SetForwardMouseMessages(bool forward) { [window_ setAcceptsMouseMovedEvents:forward]; } @@ -1860,11 +1865,9 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) { } // static -NativeWindow* NativeWindow::Create( - brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, - NativeWindow* parent) { - return new NativeWindowMac(inspectable_web_contents, options, parent); +NativeWindow* NativeWindow::Create(const mate::Dictionary& options, + NativeWindow* parent) { + return new NativeWindowMac(options, parent); } } // namespace atom diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index b1f7c3ee1063..6aa2dca3aff3 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -118,14 +118,12 @@ class NativeWindowClientView : public views::ClientView { } // namespace -NativeWindowViews::NativeWindowViews( - brightray::InspectableWebContents* web_contents, - const mate::Dictionary& options, - NativeWindow* parent) - : NativeWindow(web_contents, options, parent), +NativeWindowViews::NativeWindowViews(const mate::Dictionary& options, + NativeWindow* parent) + : NativeWindow(options, parent), window_(new views::Widget), - web_view_(web_contents->GetView()->GetView()), - focused_view_(web_contents->GetView()->GetWebView()), + content_view_(nullptr), + focused_view_(nullptr), menu_bar_autohide_(false), menu_bar_visible_(false), menu_bar_alt_pressed_(false), @@ -266,8 +264,6 @@ NativeWindowViews::NativeWindowViews( SetWindowType(GetAcceleratedWidget(), window_type); #endif - AddChildView(web_view_); - #if defined(OS_WIN) if (!has_frame()) { // Set Window style so that we get a minimize and maximize animation when @@ -310,7 +306,6 @@ NativeWindowViews::NativeWindowViews( size = ContentBoundsToWindowBounds(gfx::Rect(size)).size(); window_->CenterWindow(size); - Layout(); #if defined(OS_WIN) // Save initial window state. @@ -331,6 +326,22 @@ NativeWindowViews::~NativeWindowViews() { #endif } +void NativeWindowViews::SetContentView( + brightray::InspectableWebContents* web_contents) { + if (content_view_) { + RemoveChildView(content_view_); + if (browser_view()) { + content_view_->RemoveChildView( + browser_view()->GetInspectableWebContentsView()->GetView()); + set_browser_view(nullptr); + } + } + content_view_ = web_contents->GetView()->GetView(); + focused_view_ = web_contents->GetView()->GetWebView(); + AddChildView(content_view_); + Layout(); +} + void NativeWindowViews::Close() { if (!IsClosable()) { WindowList::WindowCloseCancelled(this); @@ -412,6 +423,33 @@ bool NativeWindowViews::IsEnabled() { #endif } +void NativeWindowViews::SetEnabled(bool enable) { + // Handle multiple calls of SetEnabled correctly. + if (enable) { + --disable_count_; + if (disable_count_ != 0) + return; + } else { + ++disable_count_; + if (disable_count_ != 1) + return; + } + +#if defined(OS_WIN) + ::EnableWindow(GetAcceleratedWidget(), enable); +#elif defined(USE_X11) + views::DesktopWindowTreeHostX11* tree_host = + views::DesktopWindowTreeHostX11::GetHostForXID(GetAcceleratedWidget()); + if (enable) { + tree_host->RemoveEventRewriter(event_disabler_.get()); + event_disabler_.reset(); + } else { + event_disabler_.reset(new EventDisabler); + tree_host->AddEventRewriter(event_disabler_.get()); + } +#endif +} + void NativeWindowViews::Maximize() { #if defined(OS_WIN) // For window without WS_THICKFRAME style, we can not call Maximize(). @@ -544,7 +582,7 @@ gfx::Rect NativeWindowViews::GetBounds() { } gfx::Rect NativeWindowViews::GetContentBounds() { - return web_view_->GetBoundsInScreen(); + return content_view_ ? content_view_->GetBoundsInScreen() : gfx::Rect(); } gfx::Size NativeWindowViews::GetContentSize() { @@ -553,7 +591,7 @@ gfx::Size NativeWindowViews::GetContentSize() { return NativeWindow::GetContentSize(); #endif - return web_view_->size(); + return content_view_ ? content_view_->size() : gfx::Size(); } void NativeWindowViews::SetContentSizeConstraints( @@ -933,8 +971,11 @@ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) { } void NativeWindowViews::SetBrowserView(NativeBrowserView* view) { + if (!content_view_) + return; + if (browser_view()) { - web_view_->RemoveChildView( + content_view_->RemoveChildView( browser_view()->GetInspectableWebContentsView()->GetView()); set_browser_view(nullptr); } @@ -946,7 +987,7 @@ void NativeWindowViews::SetBrowserView(NativeBrowserView* view) { // Add as child of the main web view to avoid (0, 0) origin from overlapping // with menu bar. set_browser_view(view); - web_view_->AddChildView(view->GetInspectableWebContentsView()->GetView()); + content_view_->AddChildView(view->GetInspectableWebContentsView()->GetView()); } void NativeWindowViews::SetParentWindow(NativeWindow* parent) { @@ -1129,33 +1170,6 @@ void NativeWindowViews::SetIcon(const gfx::ImageSkia& icon) { } #endif -void NativeWindowViews::SetEnabled(bool enable) { - // Handle multiple calls of SetEnabled correctly. - if (enable) { - --disable_count_; - if (disable_count_ != 0) - return; - } else { - ++disable_count_; - if (disable_count_ != 1) - return; - } - -#if defined(OS_WIN) - ::EnableWindow(GetAcceleratedWidget(), enable); -#elif defined(USE_X11) - views::DesktopWindowTreeHostX11* tree_host = - views::DesktopWindowTreeHostX11::GetHostForXID(GetAcceleratedWidget()); - if (enable) { - tree_host->RemoveEventRewriter(event_disabler_.get()); - event_disabler_.reset(); - } else { - event_disabler_.reset(new EventDisabler); - tree_host->AddEventRewriter(event_disabler_.get()); - } -#endif -} - void NativeWindowViews::OnWidgetActivationChanged( views::Widget* widget, bool active) { if (widget != window_.get()) @@ -1346,6 +1360,9 @@ void NativeWindowViews::HandleKeyboardEvent( } void NativeWindowViews::Layout() { + if (!content_view_) // Not ready yet. + return; + const auto size = GetContentsBounds().size(); const auto menu_bar_bounds = menu_bar_visible_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) @@ -1354,11 +1371,9 @@ void NativeWindowViews::Layout() { menu_bar_->SetBoundsRect(menu_bar_bounds); } - if (web_view_) { - web_view_->SetBoundsRect( - gfx::Rect(0, menu_bar_bounds.height(), size.width(), - size.height() - menu_bar_bounds.height())); - } + content_view_->SetBoundsRect( + gfx::Rect(0, menu_bar_bounds.height(), size.width(), + size.height() - menu_bar_bounds.height())); } gfx::Size NativeWindowViews::GetMinimumSize() const { @@ -1398,11 +1413,9 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() { } // static -NativeWindow* NativeWindow::Create( - brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, - NativeWindow* parent) { - return new NativeWindowViews(inspectable_web_contents, options, parent); +NativeWindow* NativeWindow::Create(const mate::Dictionary& options, + NativeWindow* parent) { + return new NativeWindowViews(options, parent); } } // namespace atom diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index ac97f7238b2b..dfb9016af971 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -46,12 +46,12 @@ class NativeWindowViews : public NativeWindow, public views::WidgetDelegateView, public views::WidgetObserver { public: - NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options, + NativeWindowViews(const mate::Dictionary& options, NativeWindow* parent); ~NativeWindowViews() override; // NativeWindow: + void SetContentView(brightray::InspectableWebContents* web_contents) override; void Close() override; void CloseImmediately() override; void Focus(bool focus) override; @@ -61,6 +61,7 @@ class NativeWindowViews : public NativeWindow, void Hide() override; bool IsVisible() override; bool IsEnabled() override; + void SetEnabled(bool enable) override; void Maximize() override; void Unmaximize() override; bool IsMaximized() override; @@ -139,10 +140,8 @@ class NativeWindowViews : public NativeWindow, void SetIcon(const gfx::ImageSkia& icon); #endif - void SetEnabled(bool enable) override; - views::Widget* widget() const { return window_.get(); } - views::View* web_view() const { return web_view_; } + views::View* content_view() const { return content_view_; } SkRegion* draggable_region() const { return draggable_region_.get(); } #if defined(OS_WIN) @@ -209,7 +208,7 @@ class NativeWindowViews : public NativeWindow, ui::WindowShowState GetRestoredState(); std::unique_ptr window_; - views::View* web_view_; // Managed by inspectable_web_contents_. + views::View* content_view_; // Weak ref. views::View* focused_view_; // The view should be focused by default. std::unique_ptr menu_bar_; diff --git a/atom/browser/ui/message_box_gtk.cc b/atom/browser/ui/message_box_gtk.cc index 76fd5eb89b47..5b94ee8ee652 100644 --- a/atom/browser/ui/message_box_gtk.cc +++ b/atom/browser/ui/message_box_gtk.cc @@ -16,6 +16,7 @@ #include "chrome/browser/ui/libgtkui/gtk_signal.h" #include "chrome/browser/ui/libgtkui/gtk_util.h" #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" +#include "ui/gfx/image/image_skia.h" #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" #define ANSI_FOREGROUND_RED "\x1b[31m" diff --git a/atom/browser/ui/message_box_mac.mm b/atom/browser/ui/message_box_mac.mm index 5c3802464c6b..9a3b6c7ae0df 100644 --- a/atom/browser/ui/message_box_mac.mm +++ b/atom/browser/ui/message_box_mac.mm @@ -11,6 +11,7 @@ #include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" #include "skia/ext/skia_utils_mac.h" +#include "ui/gfx/image/image_skia.h" @interface ModalDelegate : NSObject { @private diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index 844a057ae6fd..6983138a0087 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -21,6 +21,7 @@ #include "base/win/scoped_gdi_object.h" #include "content/public/browser/browser_thread.h" #include "ui/gfx/icon_util.h" +#include "ui/gfx/image/image_skia.h" namespace atom {