Don't access stale settings object after hinting

When QtWebEngine shuts down, it calls pending callbacks, which means we access
an invalid 'settings' object when that happens. The stack would look something
like this:

0  QtWebEngineCore::WebEngineSettings::setAttribute(QtWebEngineCore::WebEngineSettings::Attribute, bool)
12 QtWebEngineCore::CallbackDirectory::invokeEmptyInternal<QVariant const&>(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<QVariant const&>*)
14 QtWebEngineCore::CallbackDirectory::~CallbackDirectory()
19 QWebEnginePage::~QWebEnginePage()

If we instead get the settings from the view freshly, we get a RuntimeError from
PyQt telling us that it's dead. Not sure why it doesn't know about settings
being dead...

With that, we'd get a RuntimeError, which we can simply ignore as it doesn't
matter anyways if the tab is gone.

Fixes #3399
This commit is contained in:
Florian Bruhin 2017-12-14 22:56:44 +01:00
parent 76db8d6f81
commit 8173a48b8a
2 changed files with 10 additions and 4 deletions

View File

@ -130,6 +130,7 @@ Fixed
results being found is shown anymore.
- Fix :click-element with an ID containing non-alphanumeric characters.
- Fix crash when a subprocess outputs data which is not decodable as UTF-8.
- Fix crash when closing a tab immediately after hinting.
Deprecated
~~~~~~~~~~

View File

@ -211,11 +211,11 @@ class WebEngineElement(webelem.AbstractWebElement):
def _click_js(self, _click_target):
# FIXME:qtwebengine Have a proper API for this
# pylint: disable=protected-access
settings = self._tab._widget.settings()
view = self._tab._widget
# pylint: enable=protected-access
attribute = QWebEngineSettings.JavascriptCanOpenWindows
could_open_windows = settings.testAttribute(attribute)
settings.setAttribute(attribute, True)
could_open_windows = view.settings().testAttribute(attribute)
view.settings().setAttribute(attribute, True)
# Get QtWebEngine do apply the settings
# (it does so with a 0ms QTimer...)
@ -226,6 +226,11 @@ class WebEngineElement(webelem.AbstractWebElement):
QEventLoop.ExcludeUserInputEvents)
def reset_setting(_arg):
settings.setAttribute(attribute, could_open_windows)
try:
view.settings().setAttribute(attribute, could_open_windows)
except RuntimeError:
# Happens if this callback gets called during QWebEnginePage
# destruction, i.e. if the tab was closed in the meantime.
pass
self._js_call('click', callback=reset_setting)