diff --git a/atom/browser/api/atom_api_web_contents_view.cc b/atom/browser/api/atom_api_web_contents_view.cc index ef6d951e9e6..e8ed06b8aec 100644 --- a/atom/browser/api/atom_api_web_contents_view.cc +++ b/atom/browser/api/atom_api_web_contents_view.cc @@ -7,7 +7,10 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "brightray/browser/inspectable_web_contents_view.h" #include "native_mate/dictionary.h" -#include "ui/views/controls/native/native_view_host.h" + +#if defined(OS_MACOSX) +#include "atom/browser/ui/cocoa/delayed_native_view_host.h" +#endif #include "atom/common/node_includes.h" @@ -20,7 +23,7 @@ WebContentsView::WebContentsView( v8::Local web_contents_wrapper, brightray::InspectableWebContents* web_contents) #if defined(OS_MACOSX) - : View(new views::NativeViewHost()), + : View(new DelayedNativeViewHost(web_contents->GetView()->GetNativeView())), #else : View(web_contents->GetView()->GetView()), #endif @@ -28,9 +31,7 @@ WebContentsView::WebContentsView( #if defined(OS_MACOSX) // On macOS a View is created to wrap the NSView, and its lifetime is managed // by us. - auto* host = static_cast(view()); - host->set_owned_by_client(); - host->Attach(web_contents->GetView()->GetNativeView()); + view()->set_owned_by_client(); #else // On other platforms the View is managed by InspectableWebContents. set_delete_view(false); diff --git a/atom/browser/ui/cocoa/delayed_native_view_host.cc b/atom/browser/ui/cocoa/delayed_native_view_host.cc new file mode 100644 index 00000000000..0d48668895d --- /dev/null +++ b/atom/browser/ui/cocoa/delayed_native_view_host.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/cocoa/delayed_native_view_host.h" + +namespace atom { + +DelayedNativeViewHost::DelayedNativeViewHost(gfx::NativeView native_view) + : native_view_(native_view) {} + +DelayedNativeViewHost::~DelayedNativeViewHost() {} + +void DelayedNativeViewHost::ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) { + NativeViewHost::ViewHierarchyChanged(details); + if (details.is_add) + Attach(native_view_); +} + +} // namespace atom diff --git a/atom/browser/ui/cocoa/delayed_native_view_host.h b/atom/browser/ui/cocoa/delayed_native_view_host.h new file mode 100644 index 00000000000..2dfca1f964e --- /dev/null +++ b/atom/browser/ui/cocoa/delayed_native_view_host.h @@ -0,0 +1,31 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_COCOA_DELAYED_NATIVE_VIEW_HOST_H_ +#define ATOM_BROWSER_UI_COCOA_DELAYED_NATIVE_VIEW_HOST_H_ + +#include "ui/views/controls/native/native_view_host.h" + +namespace atom { + +// Automatically attach the native view after the NativeViewHost is attached to +// a widget. (Attaching it directly would cause crash.) +class DelayedNativeViewHost : public views::NativeViewHost { + public: + explicit DelayedNativeViewHost(gfx::NativeView native_view); + ~DelayedNativeViewHost() override; + + // views::View: + void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) override; + + private: + gfx::NativeView native_view_; + + DISALLOW_COPY_AND_ASSIGN(DelayedNativeViewHost); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_UI_COCOA_DELAYED_NATIVE_VIEW_HOST_H_ diff --git a/filenames.gypi b/filenames.gypi index bfb2967c3bc..ec0c59f0a02 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -335,6 +335,8 @@ 'atom/browser/ui/cocoa/atom_preview_item.mm', 'atom/browser/ui/cocoa/atom_touch_bar.h', 'atom/browser/ui/cocoa/atom_touch_bar.mm', + 'atom/browser/ui/cocoa/delayed_native_view_host.cc', + 'atom/browser/ui/cocoa/delayed_native_view_host.h', 'atom/browser/ui/cocoa/views_delegate_mac.h', 'atom/browser/ui/cocoa/views_delegate_mac.mm', 'atom/browser/ui/cocoa/root_view_mac.mm',