mirror of
https://github.com/aphrody-labs/cef.git
synced 2026-10-13 21:07:07 +00:00
views: Preserve overlay contents during Chrome window teardown
ChromeBrowserWidget closes owned widgets before the parent WindowClosing callback can detach overlay contents. Closing an overlay widget with CloseNow therefore deletes its contents View and invalidates the CefView retained by the client. Extract CefWindowView::CloseOverlayViews and call it from both WindowClosing and ChromeBrowserWidget::CloseOwnedWidgets. This detaches overlay contents and restores CEF ownership before owned widgets are destroyed. Direct overlay widget closure retains its destruction behavior, which Alloy overlay browsers need to complete browser shutdown. Add an explicit IsValid assertion to the overlay destruction tests. To test: ceftests --gtest_filter=ChromeChildWindowTest.*:OwnedWidgetShutdownTest.*:ViewsBrowserViewTest.*
This commit is contained in:
1 parent
33624e6bc2
commit
2d3ce7f943
5 files changed
+25
-12
No files matched your search
@@ -219,6 +219,12 @@ void ChromeBrowserWidget::CloseOwnedWidgets() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Preserve overlay contents before CloseNow bypasses the normal overlay
|
||||
// cleanup in CefWindowView::WindowClosing.
|
||||
if (window_view_) {
|
||||
window_view_->CloseOverlayViews();
|
||||
}
|
||||
|
||||
views::Widget::ForEachOwnedWidget(GetNativeView(),
|
||||
[this](views::Widget* widget) {
|
||||
if (widget != this) {
|
||||
|
||||
@@ -350,12 +350,10 @@ gfx::Rect CefOverlayViewHost::ComputeBounds() const {
|
||||
void CefOverlayViewHost::Cleanup() {
|
||||
// This method may be called multiple times. For example, explicitly after the
|
||||
// client calls CefOverlayController::Destroy or implicitly when the host
|
||||
// Widget is being closed or destroyed. In most implicit cases
|
||||
// CefWindowView::WindowClosing will call this before the host Widget is
|
||||
// destroyed, allowing the client to optionally reuse the child View. However,
|
||||
// if CefWindowView::WindowClosing is not called, DeleteDelegate will call
|
||||
// this after the host Widget and all associated Widgets/Views have been
|
||||
// destroyed. In the DeleteDelegate case |widget_| will return nullptr.
|
||||
// Widget is being closed or destroyed. CefWindowView::CloseOverlayViews calls
|
||||
// this before the host Widget is destroyed, allowing the client to reuse the
|
||||
// child View. If the overlay Widget is closed directly instead, its contents
|
||||
// are destroyed and WidgetIsZombie calls this after resetting |widget_|.
|
||||
if (view_ && widget_) {
|
||||
// Remove the child View immediately. It may be reused by the client.
|
||||
auto view = view_util::GetFor(view_, /*find_known_parent=*/false);
|
||||
|
||||
@@ -763,12 +763,7 @@ bool CefWindowView::CanMaximize() const {
|
||||
|
||||
void CefWindowView::WindowClosing() {
|
||||
// Close any overlays now, before the Widget is destroyed.
|
||||
// Use a copy of the array because the original may be modified while
|
||||
// iterating.
|
||||
std::vector<raw_ptr<CefOverlayViewHost>> overlay_hosts = overlay_hosts_;
|
||||
for (auto& overlay_host : overlay_hosts) {
|
||||
overlay_host->Close();
|
||||
}
|
||||
CloseOverlayViews();
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
#if BUILDFLAG(SUPPORTS_OZONE_X11)
|
||||
@@ -961,6 +956,15 @@ void CefWindowView::RemoveOverlayView(CefOverlayViewHost* host,
|
||||
overlay_hosts_.erase(it);
|
||||
}
|
||||
|
||||
void CefWindowView::CloseOverlayViews() {
|
||||
// Use a copy of the array because the original may be modified while
|
||||
// iterating.
|
||||
std::vector<raw_ptr<CefOverlayViewHost>> overlay_hosts = overlay_hosts_;
|
||||
for (auto& overlay_host : overlay_hosts) {
|
||||
overlay_host->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowView::MoveOverlaysIfNecessary() {
|
||||
if (overlay_hosts_.empty()) {
|
||||
return;
|
||||
|
||||
@@ -108,6 +108,10 @@ class CefWindowView : public CefPanelView<views::View, CefWindowDelegate>,
|
||||
// Called from CefOverlayViewHost::Cleanup().
|
||||
void RemoveOverlayView(CefOverlayViewHost* host, views::View* host_view);
|
||||
|
||||
// Close overlays before owned Widgets are destroyed, preserving their
|
||||
// contents Views for reuse by the client.
|
||||
void CloseOverlayViews();
|
||||
|
||||
// Set/get the draggable regions.
|
||||
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
|
||||
@@ -739,6 +739,7 @@ class OverlayTestWindowDelegate : public TestWindowDelegate {
|
||||
|
||||
// View is still visible but no longer drawn (because it no longer belongs
|
||||
// to the controller).
|
||||
EXPECT_TRUE(view_->IsValid());
|
||||
EXPECT_EQ(nullptr, view_->GetWindow());
|
||||
EXPECT_TRUE(view_->IsVisible());
|
||||
EXPECT_FALSE(view_->IsDrawn());
|
||||
|
||||
Reference in new issue
Block a user