From 359e70d61f073b4941f8c1d467788f204e8bae65 Mon Sep 17 00:00:00 2001 From: ExPikaPaka Date: Fri, 3 Jul 2026 13:29:00 +0200 Subject: [PATCH] Recreate web view from scratch as only URL fix seems not robust enough --- src/slic3r/GUI/PrinterWebView.cpp | 78 +++++++++++++++++++++++-------- src/slic3r/GUI/PrinterWebView.hpp | 11 +++++ 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/PrinterWebView.cpp b/src/slic3r/GUI/PrinterWebView.cpp index 9777783abe..42ab4f5fad 100644 --- a/src/slic3r/GUI/PrinterWebView.cpp +++ b/src/slic3r/GUI/PrinterWebView.cpp @@ -111,26 +111,14 @@ PrinterWebView::PrinterWebView(wxWindow *parent) wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); // Create the webview - m_browser = WebView::CreateWebView(this, ""); - if (m_browser == nullptr) { - wxLogError("Could not init m_browser"); + create_browser(); + if (m_browser == nullptr) return; - } -#ifdef __linux__ - inject_vue_resize_workaround(m_browser); - - auto cookiesPath = boost::filesystem::path(data_dir() + "/cache/cookies.db"); - auto wv = static_cast(m_browser->GetNativeBackend()); - auto wv_ctx = webkit_web_view_get_context(wv); - auto cookieManager = webkit_web_context_get_cookie_manager(wv_ctx); - webkit_cookie_manager_set_persistent_storage(cookieManager, cookiesPath.c_str(), WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); -#endif - - m_browser->Bind(wxEVT_WEBVIEW_ERROR, &PrinterWebView::OnError, this); - m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrinterWebView::OnLoaded, this); - m_browser->Bind(wxEVT_WEBVIEW_NEWWINDOW, &PrinterWebView::OnNewWindow, this); - m_browser->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &PrinterWebView::OnScriptMessage, this); + // A PrinterWebView built during a GUI rebuild (language switch) can come up + // with a wedged WebView2 backend that silently drops every navigation. Flag + // it so we recreate the backend the first time the tab is opened. + m_reset_on_show = wxGetApp().is_recreating_gui(); SetSizer(topsizer); @@ -169,6 +157,52 @@ PrinterWebView::~PrinterWebView() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " End"; } +void PrinterWebView::create_browser() +{ + m_browser = WebView::CreateWebView(this, ""); + if (m_browser == nullptr) { + wxLogError("Could not init m_browser"); + return; + } + +#ifdef __linux__ + inject_vue_resize_workaround(m_browser); + + auto cookiesPath = boost::filesystem::path(data_dir() + "/cache/cookies.db"); + auto wv = static_cast(m_browser->GetNativeBackend()); + auto wv_ctx = webkit_web_view_get_context(wv); + auto cookieManager = webkit_web_context_get_cookie_manager(wv_ctx); + webkit_cookie_manager_set_persistent_storage(cookieManager, cookiesPath.c_str(), WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); +#endif + + m_browser->Bind(wxEVT_WEBVIEW_ERROR, &PrinterWebView::OnError, this); + m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrinterWebView::OnLoaded, this); + m_browser->Bind(wxEVT_WEBVIEW_NEWWINDOW, &PrinterWebView::OnNewWindow, this); + m_browser->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &PrinterWebView::OnScriptMessage, this); +} + +void PrinterWebView::reset_browser() +{ + BOOST_LOG_TRIVIAL(info) << "DEVTAB reset_browser"; // TEMP diag + wxSizer* topsizer = GetSizer(); + if (m_browser) { + if (topsizer) + topsizer->Detach(m_browser); + m_browser->Destroy(); + m_browser = nullptr; + } + m_apikey_sent = false; + + create_browser(); + if (m_browser == nullptr) + return; + if (topsizer) { + topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); + Layout(); + } + update_mode(); +} + void PrinterWebView::load_url(wxString& url, wxString apikey) { // this->Show(); @@ -192,7 +226,13 @@ void PrinterWebView::load_url(wxString& url, wxString apikey) bool PrinterWebView::Show(bool show) { - if (show && !m_url_deferred.empty()) { + // Recover from a wedged WebView2 backend created during a GUI rebuild by + // recreating the control the first time the tab is actually opened. + if (show && m_reset_on_show) { + m_reset_on_show = false; + reset_browser(); + } + if (show && !m_url_deferred.empty() && m_browser) { m_browser->LoadURL(m_url_deferred); //ORCA: m_url_deferred will be cleared on load success //m_url_deferred.clear(); diff --git a/src/slic3r/GUI/PrinterWebView.hpp b/src/slic3r/GUI/PrinterWebView.hpp index 8a62ce70a2..e54ae130fb 100644 --- a/src/slic3r/GUI/PrinterWebView.hpp +++ b/src/slic3r/GUI/PrinterWebView.hpp @@ -55,6 +55,13 @@ private: friend class PrinterWebViewHandler; void SendAPIKey(); + // Create/configure the underlying wxWebView (m_browser) and bind its events. + void create_browser(); + // Tear down and recreate m_browser from scratch. Used to recover from a + // wedged WebView2 backend after a recreate_GUI (language switch), where a + // control created while the previous frame's active webview is still alive + // silently ignores all navigations. + void reset_browser(); wxWebView* m_browser; long m_zoomFactor; @@ -62,6 +69,10 @@ private: bool m_apikey_sent; wxString m_url_deferred; std::unique_ptr m_handler; + // When this view is constructed during a GUI rebuild, its WebView2 backend + // may come up wedged. Recreate it the first time the view is actually shown + // (by then the old frame is gone and creation is clean). + bool m_reset_on_show{false}; // DECLARE_EVENT_TABLE() };