Crash Fix: Destroy WebView before the container.

This commit is contained in:
John Preston 2021-06-29 11:07:16 +03:00
parent c1a7332a5e
commit 8608d8aa4d
2 changed files with 23 additions and 8 deletions

View file

@ -43,6 +43,21 @@ struct Panel::Progress {
rpl::lifetime geometryLifetime; rpl::lifetime geometryLifetime;
}; };
struct Panel::WebviewWithLifetime {
WebviewWithLifetime(
QWidget *parent = nullptr,
Webview::WindowConfig config = Webview::WindowConfig());
Webview::Window window;
rpl::lifetime lifetime;
};
Panel::WebviewWithLifetime::WebviewWithLifetime(
QWidget *parent,
Webview::WindowConfig config)
: window(parent, std::move(config)) {
}
Panel::Progress::Progress(QWidget *parent, Fn<QRect()> rect) Panel::Progress::Progress(QWidget *parent, Fn<QRect()> rect)
: widget(parent) : widget(parent)
, animation( , animation(
@ -68,7 +83,7 @@ Panel::Panel(not_null<PanelDelegate*> delegate)
} }
Panel::~Panel() { Panel::~Panel() {
// Destroy _widget before _webview. _webview = nullptr;
_progress = nullptr; _progress = nullptr;
_widget = nullptr; _widget = nullptr;
} }
@ -451,7 +466,7 @@ bool Panel::showWebview(
} }
showWebviewProgress(); showWebviewProgress();
_widget->destroyLayer(); _widget->destroyLayer();
_webview->navigate(url); _webview->window.navigate(url);
_widget->setBackAllowed(allowBack); _widget->setBackAllowed(allowBack);
if (bottomText) { if (bottomText) {
const auto &padding = st::paymentsPanelPadding; const auto &padding = st::paymentsPanelPadding;
@ -490,14 +505,14 @@ bool Panel::createWebview() {
}, bottom->lifetime()); }, bottom->lifetime());
container->show(); container->show();
_webview = std::make_unique<Webview::Window>( _webview = std::make_unique<WebviewWithLifetime>(
container.get(), container.get(),
Webview::WindowConfig{ Webview::WindowConfig{
.userDataPath = _delegate->panelWebviewDataPath(), .userDataPath = _delegate->panelWebviewDataPath(),
}); });
const auto raw = _webview.get(); const auto raw = &_webview->window;
QObject::connect(container.get(), &QObject::destroyed, [=] { QObject::connect(container.get(), &QObject::destroyed, [=] {
if (_webview.get() == raw) { if (_webview && &_webview->window == raw) {
_webview = nullptr; _webview = nullptr;
if (_webviewProgress) { if (_webviewProgress) {
hideWebviewProgress(); hideWebviewProgress();
@ -517,7 +532,7 @@ bool Panel::createWebview() {
container->geometryValue( container->geometryValue(
) | rpl::start_with_next([=](QRect geometry) { ) | rpl::start_with_next([=](QRect geometry) {
raw->widget()->setGeometry(geometry); raw->widget()->setGeometry(geometry);
}, container->lifetime()); }, _webview->lifetime);
raw->setMessageHandler([=](const QJsonDocument &message) { raw->setMessageHandler([=](const QJsonDocument &message) {
const auto save = _saveWebviewInformation const auto save = _saveWebviewInformation

View file

@ -17,7 +17,6 @@ class Checkbox;
} // namespace Ui } // namespace Ui
namespace Webview { namespace Webview {
class Window;
struct Available; struct Available;
} // namespace Webview } // namespace Webview
@ -88,6 +87,7 @@ public:
private: private:
struct Progress; struct Progress;
struct WebviewWithLifetime;
bool createWebview(); bool createWebview();
void showWebviewProgress(); void showWebviewProgress();
@ -103,7 +103,7 @@ private:
const not_null<PanelDelegate*> _delegate; const not_null<PanelDelegate*> _delegate;
std::unique_ptr<SeparatePanel> _widget; std::unique_ptr<SeparatePanel> _widget;
std::unique_ptr<Webview::Window> _webview; std::unique_ptr<WebviewWithLifetime> _webview;
std::unique_ptr<RpWidget> _webviewBottom; std::unique_ptr<RpWidget> _webviewBottom;
std::unique_ptr<Progress> _progress; std::unique_ptr<Progress> _progress;
QPointer<Checkbox> _saveWebviewInformation; QPointer<Checkbox> _saveWebviewInformation;