@@ -311,30 +311,31 @@ class WebViewWidgetWin : public WebViewWidget
311311 }
312312 }
313313
314+ // Drop cached COM pointers before Close. Close can pump, and a
315+ // resize or the emulation timer must not call into a dying view.
316+ if (m_emulationTimer)
317+ m_emulationTimer->stop ();
318+ m_touchView = nullptr ;
319+ m_touchOn = false ;
320+ m_metricsView = nullptr ;
321+ m_metricsOn = false ;
314322 if (m_pages.isEmpty ()) {
315- if (m_controller) {
316- m_controller->Close ();
317- m_controller->Release ();
318- }
319- if (m_webView)
320- m_webView->Release ();
323+ ICoreWebView2Controller *controller = m_controller;
324+ ICoreWebView2 *webView = m_webView;
321325 m_controller = nullptr ;
322326 m_webView = nullptr ;
327+ releaseOwnedView (controller, webView);
323328 } else {
329+ m_controller = nullptr ;
330+ m_webView = nullptr ;
324331 for (Page &page : m_pages) {
325- if (page.controller ) {
326- page.controller ->Close ();
327- page.controller ->Release ();
328- page.controller = nullptr ;
329- }
330- if (page.webView ) {
331- page.webView ->Release ();
332- page.webView = nullptr ;
333- }
332+ ICoreWebView2Controller *controller = page.controller ;
333+ ICoreWebView2 *webView = page.webView ;
334+ page.controller = nullptr ;
335+ page.webView = nullptr ;
336+ releaseOwnedView (controller, webView);
334337 }
335338 m_pages.clear ();
336- m_controller = nullptr ;
337- m_webView = nullptr ;
338339 }
339340 m_inflightPages.clear ();
340341 m_initialControllerPending = false ;
@@ -373,6 +374,35 @@ class WebViewWidgetWin : public WebViewWidget
373374 }
374375
375376protected:
377+ // Null live aliases first. Close pumps the message loop, and a resize or
378+ // the emulation timer must not call into the view being destroyed.
379+ void releaseOwnedView (ICoreWebView2Controller *controller, ICoreWebView2 *webView)
380+ {
381+ if (webView) {
382+ if (webView == m_touchView) {
383+ m_touchView = nullptr ;
384+ m_touchOn = false ;
385+ }
386+ if (webView == m_metricsView) {
387+ m_metricsView = nullptr ;
388+ m_metricsOn = false ;
389+ }
390+ if (webView == m_webView) {
391+ m_webView = nullptr ;
392+ if (m_emulationTimer)
393+ m_emulationTimer->stop ();
394+ }
395+ }
396+ if (controller && controller == m_controller)
397+ m_controller = nullptr ;
398+ if (controller) {
399+ controller->Close ();
400+ controller->Release ();
401+ }
402+ if (webView)
403+ webView->Release ();
404+ }
405+
376406 void applyControllerBounds (ICoreWebView2Controller *controller, QWidget *host)
377407 {
378408 if (!controller || !host)
@@ -417,8 +447,9 @@ class WebViewWidgetWin : public WebViewWidget
417447 " AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Mobile/15E148 Safari/604.1\" ,"
418448 " \" platform\" :\" iPad\" }" );
419449 }
450+ const std::wstring ua = uaJson.toStdWString ();
420451 webView->CallDevToolsProtocolMethod (
421- L" Emulation.setUserAgentOverride" , uaJson. toStdWString () .c_str (), nullptr );
452+ L" Emulation.setUserAgentOverride" , ua .c_str (), nullptr );
422453 }
423454
424455 const QRect r = m_hostWidget
@@ -449,8 +480,9 @@ class WebViewWidgetWin : public WebViewWidget
449480 .arg (w)
450481 .arg (h)
451482 .arg (dpr);
483+ const std::wstring metricsW = metrics.toStdWString ();
452484 webView->CallDevToolsProtocolMethod (
453- L" Emulation.setDeviceMetricsOverride" , metrics. toStdWString () .c_str (), nullptr );
485+ L" Emulation.setDeviceMetricsOverride" , metricsW .c_str (), nullptr );
454486 }
455487
456488 void applyViewport () override
@@ -468,6 +500,8 @@ class WebViewWidgetWin : public WebViewWidget
468500 m_emulationTimer->setSingleShot (true );
469501 m_emulationTimer->setInterval (50 );
470502 connect (m_emulationTimer, &QTimer::timeout, this , [this ]() {
503+ if (!m_alive->load (std::memory_order_acquire))
504+ return ;
471505 applyTouchEmulation (m_webView);
472506 });
473507 }
@@ -1405,12 +1439,13 @@ class WebViewWidgetWin : public WebViewWidget
14051439 m_tabBar->removeTab (index);
14061440 m_switching = false ;
14071441 releasePending (takePending (id));
1408- if (page.controller ) {
1409- page.controller ->Close ();
1410- page.controller ->Release ();
1442+ if (page.controller || page.webView ) {
1443+ ICoreWebView2Controller *controller = page.controller ;
1444+ ICoreWebView2 *webView = page.webView ;
1445+ page.controller = nullptr ;
1446+ page.webView = nullptr ;
1447+ releaseOwnedView (controller, webView);
14111448 }
1412- if (page.webView )
1413- page.webView ->Release ();
14141449 if (awaitingController && m_inflightPages.contains (id) && page.host ) {
14151450 page.host ->hide ();
14161451 m_deferredHosts.insert (id, page.host );
@@ -1444,12 +1479,13 @@ class WebViewWidgetWin : public WebViewWidget
14441479 if (m_tabBar && index < m_tabBar->count ())
14451480 m_tabBar->removeTab (index);
14461481 m_switching = false ;
1447- if (page.controller ) {
1448- page.controller ->Close ();
1449- page.controller ->Release ();
1482+ if (page.controller || page.webView ) {
1483+ ICoreWebView2Controller *controller = page.controller ;
1484+ ICoreWebView2 *webView = page.webView ;
1485+ page.controller = nullptr ;
1486+ page.webView = nullptr ;
1487+ releaseOwnedView (controller, webView);
14501488 }
1451- if (page.webView )
1452- page.webView ->Release ();
14531489 if (page.host )
14541490 page.host ->deleteLater ();
14551491 if (m_pages.size () < 2 && m_tabBar)
0 commit comments