diff --git a/libcef/browser/native/browser_platform_delegate_native_aura.cc b/libcef/browser/native/browser_platform_delegate_native_aura.cc index 33266899d..81d3862d9 100644 --- a/libcef/browser/native/browser_platform_delegate_native_aura.cc +++ b/libcef/browser/native/browser_platform_delegate_native_aura.cc @@ -216,6 +216,12 @@ gfx::Vector2d CefBrowserPlatformDelegateNativeAura::GetUiWheelEventOffset( return gfx::Vector2d(deltaX, deltaY); } +base::OnceClosure +CefBrowserPlatformDelegateNativeAura::GetWidgetDeleteCallback() { + return base::BindOnce(&CefBrowserPlatformDelegateNativeAura::WidgetDeleted, + weak_ptr_factory_.GetWeakPtr()); +} + // static base::TimeTicks CefBrowserPlatformDelegateNativeAura::GetEventTimeStamp() { return base::TimeTicks::Now(); @@ -279,6 +285,11 @@ int CefBrowserPlatformDelegateNativeAura::TranslateUiChangedButtonFlags( return result; } +void CefBrowserPlatformDelegateNativeAura::WidgetDeleted() { + DCHECK(window_widget_); + window_widget_ = nullptr; +} + content::RenderWidgetHostViewAura* CefBrowserPlatformDelegateNativeAura::GetHostView() const { if (!web_contents_) { diff --git a/libcef/browser/native/browser_platform_delegate_native_aura.h b/libcef/browser/native/browser_platform_delegate_native_aura.h index 525d41687..a3c61fb22 100644 --- a/libcef/browser/native/browser_platform_delegate_native_aura.h +++ b/libcef/browser/native/browser_platform_delegate_native_aura.h @@ -7,6 +7,7 @@ #include "libcef/browser/native/browser_platform_delegate_native.h" +#include "base/memory/weak_ptr.h" #include "ui/events/event.h" namespace content { @@ -71,6 +72,8 @@ class CefBrowserPlatformDelegateNativeAura virtual gfx::Vector2d GetUiWheelEventOffset(int deltaX, int deltaY) const; protected: + base::OnceClosure GetWidgetDeleteCallback(); + static base::TimeTicks GetEventTimeStamp(); static int TranslateUiEventModifiers(uint32 cef_modifiers); static int TranslateUiChangedButtonFlags(uint32 cef_modifiers); @@ -80,7 +83,14 @@ class CefBrowserPlatformDelegateNativeAura views::Widget* window_widget_ = nullptr; private: + // Will only be called if the Widget is deleted before + // CefBrowserHostBase::DestroyBrowser() is called. + void WidgetDeleted(); + content::RenderWidgetHostViewAura* GetHostView() const; + + base::WeakPtrFactory weak_ptr_factory_{ + this}; }; #endif // CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_ diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.cc b/libcef/browser/native/browser_platform_delegate_native_linux.cc index 648d5a504..50e7a950c 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.cc +++ b/libcef/browser/native/browser_platform_delegate_native_linux.cc @@ -79,7 +79,7 @@ bool CefBrowserPlatformDelegateNativeLinux::CreateHostWindow() { CefWindowDelegateView* delegate_view = new CefWindowDelegateView( GetBackgroundColor(), window_x11_->TopLevelAlwaysOnTop(), - GetBoundsChangedCallback()); + GetBoundsChangedCallback(), GetWidgetDeleteCallback()); delegate_view->Init(static_cast(window_info_.window), web_contents_, gfx::Rect(gfx::Point(), rect.size())); diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index 44c3586b5..d983f532d 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -284,7 +284,8 @@ bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() { (top_level_window_ex_styles & WS_EX_TOPMOST) == WS_EX_TOPMOST; CefWindowDelegateView* delegate_view = new CefWindowDelegateView( - GetBackgroundColor(), always_on_top, GetBoundsChangedCallback()); + GetBackgroundColor(), always_on_top, GetBoundsChangedCallback(), + GetWidgetDeleteCallback()); delegate_view->Init(window_info_.window, web_contents_, gfx::Rect(0, 0, dip_rect.width(), dip_rect.height())); @@ -702,4 +703,4 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd, } return DefWindowProc(hwnd, message, wParam, lParam); -} \ No newline at end of file +} diff --git a/libcef/browser/native/window_delegate_view.cc b/libcef/browser/native/window_delegate_view.cc index c562cfce7..13b305902 100644 --- a/libcef/browser/native/window_delegate_view.cc +++ b/libcef/browser/native/window_delegate_view.cc @@ -15,11 +15,12 @@ CefWindowDelegateView::CefWindowDelegateView( SkColor background_color, bool always_on_top, - base::RepeatingClosure on_bounds_changed) + base::RepeatingClosure on_bounds_changed, + base::OnceClosure on_delete) : background_color_(background_color), - web_view_(nullptr), always_on_top_(always_on_top), - on_bounds_changed_(on_bounds_changed) {} + on_bounds_changed_(std::move(on_bounds_changed)), + on_delete_(std::move(on_delete)) {} void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget, content::WebContents* web_contents, @@ -64,6 +65,10 @@ void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget, DCHECK(widget->is_top_level()); // |widget| must be activatable for focus handling to work correctly. DCHECK(widget->widget_delegate()->CanActivate()); + + // WidgetDelegate::DeleteDelegate() will execute the registered callback. + RegisterDeleteDelegateCallback(base::BindOnce( + &CefWindowDelegateView::DeleteDelegate, base::Unretained(this))); } void CefWindowDelegateView::InitContent() { @@ -72,6 +77,12 @@ void CefWindowDelegateView::InitContent() { AddChildView(web_view_); } +void CefWindowDelegateView::DeleteDelegate() { + if (!on_delete_.is_null()) { + std::move(on_delete_).Run(); + } +} + void CefWindowDelegateView::ViewHierarchyChanged( const views::ViewHierarchyChangedDetails& details) { if (details.is_add && details.child == this) { diff --git a/libcef/browser/native/window_delegate_view.h b/libcef/browser/native/window_delegate_view.h index 1c574884a..1205aea9f 100644 --- a/libcef/browser/native/window_delegate_view.h +++ b/libcef/browser/native/window_delegate_view.h @@ -22,7 +22,8 @@ class CefWindowDelegateView : public views::WidgetDelegateView { public: CefWindowDelegateView(SkColor background_color, bool always_on_top, - base::RepeatingClosure on_bounds_changed); + base::RepeatingClosure on_bounds_changed, + base::OnceClosure on_delete); CefWindowDelegateView(const CefWindowDelegateView&) = delete; CefWindowDelegateView& operator=(const CefWindowDelegateView&) = delete; @@ -36,6 +37,8 @@ class CefWindowDelegateView : public views::WidgetDelegateView { // Initialize the Widget's content. void InitContent(); + void DeleteDelegate(); + // WidgetDelegateView methods: bool CanMaximize() const override { return true; } View* GetContentsView() override { return this; } @@ -46,10 +49,12 @@ class CefWindowDelegateView : public views::WidgetDelegateView { void OnBoundsChanged(const gfx::Rect& previous_bounds) override; private: - SkColor background_color_; - views::WebView* web_view_; - bool always_on_top_; + const SkColor background_color_; + const bool always_on_top_; base::RepeatingClosure on_bounds_changed_; + base::OnceClosure on_delete_; + + views::WebView* web_view_ = nullptr; }; #endif // CEF_LIBCEF_BROWSER_NATIVE_WINDOW_DELEGATE_VIEW_H_