Recreate web view from scratch as only URL fix seems not robust enough

This commit is contained in:
ExPikaPaka
2026-07-03 13:29:00 +02:00
parent fd72249a35
commit 359e70d61f
2 changed files with 70 additions and 19 deletions

View File

@@ -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<WebKitWebView*>(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<WebKitWebView*>(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();

View File

@@ -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<PrinterWebViewHandler> 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()
};