From 6fe99cd2b6cab2412956981be6893113693fcf43 Mon Sep 17 00:00:00 2001 From: ExPikaPaka Date: Fri, 3 Jul 2026 14:04:40 +0200 Subject: [PATCH] Add the same robust browser recreation for WebViewDialog It should eliminate possible issue with blank Home and other pages in the same way as Printer page --- src/slic3r/GUI/PrinterWebView.cpp | 1 - src/slic3r/GUI/Project.cpp | 50 +++++++++++++++++++++++++------ src/slic3r/GUI/Project.hpp | 7 +++++ src/slic3r/GUI/WebViewDialog.cpp | 50 +++++++++++++++++++++++++++---- src/slic3r/GUI/WebViewDialog.hpp | 12 ++++++++ 5 files changed, 105 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/PrinterWebView.cpp b/src/slic3r/GUI/PrinterWebView.cpp index 42ab4f5fad..5c6a66cfd0 100644 --- a/src/slic3r/GUI/PrinterWebView.cpp +++ b/src/slic3r/GUI/PrinterWebView.cpp @@ -183,7 +183,6 @@ void PrinterWebView::create_browser() void PrinterWebView::reset_browser() { - BOOST_LOG_TRIVIAL(info) << "DEVTAB reset_browser"; // TEMP diag wxSizer* topsizer = GetSizer(); if (m_browser) { if (topsizer) diff --git a/src/slic3r/GUI/Project.cpp b/src/slic3r/GUI/Project.cpp index 57410b1202..93f566d005 100644 --- a/src/slic3r/GUI/Project.cpp +++ b/src/slic3r/GUI/Project.cpp @@ -51,16 +51,12 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); - m_browser = WebView::CreateWebView(this, m_project_home_url); - if (m_browser == nullptr) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("load web view of project page failed"); + create_browser(); + if (m_browser == nullptr) return; - } + m_reset_on_show = wxGetApp().is_recreating_gui(); //m_browser->Hide(); main_sizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); - m_browser->Bind(wxEVT_WEBVIEW_NAVIGATED, &ProjectPanel::on_navigated, this); - m_browser->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &ProjectPanel::OnScriptMessage, this, m_browser->GetId()); - Bind(wxEVT_WEBVIEW_NAVIGATING, &ProjectPanel::onWebNavigating, this, m_browser->GetId()); Bind(EVT_PROJECT_RELOAD, &ProjectPanel::on_reload, this); @@ -76,6 +72,36 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, ProjectPanel::~ProjectPanel() {} +void ProjectPanel::create_browser() +{ + m_browser = WebView::CreateWebView(this, m_project_home_url); + if (m_browser == nullptr) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("load web view of project page failed"); + return; + } + m_browser->Bind(wxEVT_WEBVIEW_NAVIGATED, &ProjectPanel::on_navigated, this); + m_browser->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &ProjectPanel::OnScriptMessage, this, m_browser->GetId()); + Bind(wxEVT_WEBVIEW_NAVIGATING, &ProjectPanel::onWebNavigating, this, m_browser->GetId()); +} + +void ProjectPanel::reset_browser() +{ + wxSizer* sizer = GetSizer(); + if (m_browser) { + if (sizer) + sizer->Detach(m_browser); + m_browser->Destroy(); + m_browser = nullptr; + } + create_browser(); + if (m_browser == nullptr) + return; + if (sizer) { + sizer->Insert(0, m_browser, wxSizerFlags().Expand().Proportion(1)); + Layout(); + } +} + // Helper to convert newlines to
static std::string convert_newlines_to_br(const std::string& text) { std::string result = text; @@ -454,10 +480,16 @@ void ProjectPanel::RunScript(std::string content) WebView::RunScript(m_browser, content); } -bool ProjectPanel::Show(bool show) +bool ProjectPanel::Show(bool show) { + // Recover from a wedged WebView2 backend created during a GUI rebuild by + // recreating the control the first time the panel is actually shown. + if (show && m_reset_on_show) { + m_reset_on_show = false; + reset_browser(); + } if (show) update_model_data(); - return wxPanel::Show(show); + return wxPanel::Show(show); } }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Project.hpp b/src/slic3r/GUI/Project.hpp index 0071685e7d..57e8e04ca1 100644 --- a/src/slic3r/GUI/Project.hpp +++ b/src/slic3r/GUI/Project.hpp @@ -68,8 +68,15 @@ private: wxString m_project_home_url; wxString m_root_dir; static inline int m_sequence_id = 8000; + // Set when this panel is built during a GUI rebuild (language switch), where + // the WebView2 backend can come up wedged. Recreate it on first show. + bool m_reset_on_show = {false}; void show_info_editor(bool show); + // Create/configure m_browser (create + bind events + load the home url). + void create_browser(); + // Tear down and recreate m_browser to recover from a wedged backend. + void reset_browser(); public: diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 20ed70e799..3878b673fe 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -40,6 +40,7 @@ WebViewPanel::WebViewPanel(wxWindow *parent) wxString strlang = wxGetApp().current_language_code_safe(); if (strlang != "") url = wxString::Format("file://%s/web/homepage/index.html?lang=%s", from_u8(resources_dir()), strlang); + m_home_url = url; wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); @@ -83,12 +84,10 @@ WebViewPanel::WebViewPanel(wxWindow *parent) m_info = new wxInfoBar(this); topsizer->Add(m_info, wxSizerFlags().Expand()); // Create the webview - m_browser = WebView::CreateWebView(this, url); - if (m_browser == nullptr) { - wxLogError("Could not init m_browser"); + create_browser(); + if (m_browser == nullptr) return; - } - m_browser->Hide(); + m_reset_on_show = wxGetApp().is_recreating_gui(); SetSizer(topsizer); topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); @@ -237,6 +236,47 @@ WebViewPanel::~WebViewPanel() } +void WebViewPanel::create_browser() +{ + m_browser = WebView::CreateWebView(this, m_home_url); + if (m_browser == nullptr) { + wxLogError("Could not init m_browser"); + return; + } + m_browser->Hide(); +} + +void WebViewPanel::reset_browser() +{ + wxSizer* topsizer = GetSizer(); + if (m_browser) { + if (topsizer) + topsizer->Detach(m_browser); + m_browser->Destroy(); + m_browser = nullptr; + } + create_browser(); + if (m_browser == nullptr) + return; + if (topsizer) { + topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); + Layout(); + } +} + +bool WebViewPanel::Show(bool show) +{ + // Recover from a wedged WebView2 backend created during a GUI rebuild by + // recreating the control the first time the Home tab is actually shown. + if (show && m_reset_on_show) { + m_reset_on_show = false; + reset_browser(); + if (m_browser != nullptr) + m_browser->LoadURL(m_home_url); + } + return wxPanel::Show(show); +} + void WebViewPanel::load_url(wxString& url) { this->Show(); diff --git a/src/slic3r/GUI/WebViewDialog.hpp b/src/slic3r/GUI/WebViewDialog.hpp index 23b3c711a1..d1b1915cf8 100644 --- a/src/slic3r/GUI/WebViewDialog.hpp +++ b/src/slic3r/GUI/WebViewDialog.hpp @@ -105,9 +105,21 @@ public: int get_model_mall_detail_url(std::string *url, std::string id); void update_mode(); + + bool Show(bool show = true) override; private: + // Create/configure m_browser (create the webview, hidden until loaded). + void create_browser(); + // Tear down and recreate m_browser to recover from a wedged WebView2 backend + // after a GUI rebuild (language switch), then reload the home page. + void reset_browser(); wxWebView* m_browser; + // Home page url (kept so the browser can be reloaded after a reset). + wxString m_home_url; + // Set when this panel is built during a GUI rebuild; recreate the backend on + // first show to recover from a wedged control. + bool m_reset_on_show{false}; wxBoxSizer *bSizer_toolbar; wxButton * m_button_back; wxButton * m_button_forward;