summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2019-06-17 13:21:58 +0200
committerFlorian Bruhin <me@the-compiler.org>2019-06-18 11:49:51 +0200
commitf3db2c3fbef908572d4647346388b0f33d8d88e2 (patch)
tree40072767b32e7218511e42d5a6f64958a013651f
parentd5ae3a76f3ecc11508f519d3b3335fa01bcf0ffe (diff)
downloadqutebrowser-f3db2c3fbef908572d4647346388b0f33d8d88e2.tar.gz
qutebrowser-f3db2c3fbef908572d4647346388b0f33d8d88e2.zip
Nuke the cache when the Qt version changed
https://bugreports.qt.io/browse/QTBUG-72532
-rw-r--r--qutebrowser/config/configfiles.py17
-rw-r--r--qutebrowser/misc/backendproblem.py30
-rw-r--r--tests/unit/config/test_configfiles.py68
3 files changed, 105 insertions, 10 deletions
diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py
index 0d1dcb22f..402bfcf03 100644
--- a/qutebrowser/config/configfiles.py
+++ b/qutebrowser/config/configfiles.py
@@ -30,7 +30,7 @@ import contextlib
import typing
import yaml
-from PyQt5.QtCore import pyqtSignal, QObject, QSettings
+from PyQt5.QtCore import pyqtSignal, QObject, QSettings, qVersion
import qutebrowser
from qutebrowser.config import configexc, config, configdata, configutils
@@ -55,6 +55,17 @@ class StateConfig(configparser.ConfigParser):
super().__init__()
self._filename = os.path.join(standarddir.data(), 'state')
self.read(self._filename, encoding='utf-8')
+
+ qt_version = qVersion()
+ # We handle this here, so we can avoid setting qt_version_changed if
+ # the config is brand new, but can still set it when qt_version wasn't
+ # there before...
+ if 'general' in self:
+ old_qt_version = self['general'].get('qt_version', None)
+ self.qt_version_changed = old_qt_version != qt_version
+ else:
+ self.qt_version_changed = False
+
for sect in ['general', 'geometry']:
try:
self.add_section(sect)
@@ -65,6 +76,9 @@ class StateConfig(configparser.ConfigParser):
for key in deleted_keys:
self['general'].pop(key, None)
+ self['general']['qt_version'] = qt_version
+ self['general']['version'] = qutebrowser.__version__
+
def init_save_manager(self,
save_manager: 'savemanager.SaveManager') -> None:
"""Make sure the config gets saved properly.
@@ -638,7 +652,6 @@ def init() -> None:
"""Initialize config storage not related to the main config."""
global state
state = StateConfig()
- state['general']['version'] = qutebrowser.__version__
# Set the QSettings path to something like
# ~/.config/qutebrowser/qsettings/qutebrowser/qutebrowser.conf so it
diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py
index da9392f3d..796d97fea 100644
--- a/qutebrowser/misc/backendproblem.py
+++ b/qutebrowser/misc/backendproblem.py
@@ -26,6 +26,7 @@ import html
import ctypes
import ctypes.util
import enum
+import shutil
import attr
from PyQt5.QtCore import Qt
@@ -33,8 +34,9 @@ from PyQt5.QtWidgets import (QApplication, QDialog, QPushButton, QHBoxLayout,
QVBoxLayout, QLabel, QMessageBox)
from PyQt5.QtNetwork import QSslSocket
-from qutebrowser.config import config
-from qutebrowser.utils import usertypes, objreg, version, qtutils, log, utils
+from qutebrowser.config import config, configfiles
+from qutebrowser.utils import (usertypes, objreg, version, qtutils, log, utils,
+ standarddir)
from qutebrowser.misc import objects, msgbox
@@ -397,6 +399,29 @@ def _check_backend_modules():
raise utils.Unreachable
+def _handle_cache_nuking():
+ """Nuke the QtWebEngine cache if the Qt version changed.
+
+ WORKAROUND for https://bugreports.qt.io/browse/QTBUG-72532
+ """
+ if not configfiles.state.qt_version_changed:
+ return
+
+ # Only nuke the cache in cases where we know there are problems.
+ # It seems these issues started with Qt 5.12.
+ # They should be fixed with Qt 5.12.5:
+ # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/265408
+ affected = (qtutils.version_check('5.12', compiled=False) and not
+ qtutils.version_check('5.12.5', compiled=False))
+ if not affected:
+ return
+
+ log.init.info("Qt version changed, nuking QtWebEngine cache")
+ cache_dir = os.path.join(standarddir.cache(), 'webengine')
+ if os.path.exists(cache_dir):
+ shutil.rmtree(cache_dir)
+
+
def init():
"""Check for various issues related to QtWebKit/QtWebEngine."""
_check_backend_modules()
@@ -405,6 +430,7 @@ def init():
_handle_wayland()
_nvidia_shader_workaround()
_handle_nouveau_graphics()
+ _handle_cache_nuking()
else:
assert objects.backend == usertypes.Backend.QtWebKit, objects.backend
_handle_ssl_support(fatal=True)
diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py
index 9609cdafa..e7b830d93 100644
--- a/tests/unit/config/test_configfiles.py
+++ b/tests/unit/config/test_configfiles.py
@@ -76,14 +76,48 @@ def autoconfig(config_tmpdir):
@pytest.mark.parametrize('old_data, insert, new_data', [
- (None, False, '[general]\n\n[geometry]\n\n'),
- ('[general]\nfooled = true', False, '[general]\n\n[geometry]\n\n'),
- ('[general]\nfoobar = 42', False,
- '[general]\nfoobar = 42\n\n[geometry]\n\n'),
- (None, True, '[general]\nnewval = 23\n\n[geometry]\n\n'),
+ (None,
+ False,
+ '[general]\n'
+ 'qt_version = 5.6.7\n'
+ 'version = 1.2.3\n'
+ '\n'
+ '[geometry]\n'
+ '\n'),
+ ('[general]\n'
+ 'fooled = true',
+ False,
+ '[general]\n'
+ 'qt_version = 5.6.7\n'
+ 'version = 1.2.3\n'
+ '\n'
+ '[geometry]\n'
+ '\n'),
+ ('[general]\n'
+ 'foobar = 42',
+ False,
+ '[general]\n'
+ 'foobar = 42\n'
+ 'qt_version = 5.6.7\n'
+ 'version = 1.2.3\n'
+ '\n'
+ '[geometry]\n'
+ '\n'),
+ (None,
+ True,
+ '[general]\n'
+ 'qt_version = 5.6.7\n'
+ 'version = 1.2.3\n'
+ 'newval = 23\n'
+ '\n'
+ '[geometry]\n'
+ '\n'),
])
-def test_state_config(fake_save_manager, data_tmpdir,
+def test_state_config(fake_save_manager, data_tmpdir, monkeypatch,
old_data, insert, new_data):
+ monkeypatch.setattr(configfiles.qutebrowser, '__version__', '1.2.3')
+ monkeypatch.setattr(configfiles, 'qVersion', lambda: '5.6.7')
+
statefile = data_tmpdir / 'state'
if old_data is not None:
statefile.write_text(old_data, 'utf-8')
@@ -102,6 +136,28 @@ def test_state_config(fake_save_manager, data_tmpdir,
fake_save_manager.add_saveable('state-config', unittest.mock.ANY)
+@pytest.mark.parametrize('old_version, new_version, changed', [
+ (None, '5.12.1', False),
+ ('5.12.1', '5.12.1', False),
+ ('5.12.2', '5.12.1', True),
+ ('5.12.1', '5.12.2', True),
+ ('5.13.0', '5.12.2', True),
+ ('5.12.2', '5.13.0', True),
+])
+def test_qt_version_changed(data_tmpdir, monkeypatch,
+ old_version, new_version, changed):
+ monkeypatch.setattr(configfiles, 'qVersion', lambda: new_version)
+
+ statefile = data_tmpdir / 'state'
+ if old_version is not None:
+ data = ('[general]\n'
+ 'qt_version = {}'.format(old_version))
+ statefile.write_text(data, 'utf-8')
+
+ state = configfiles.StateConfig()
+ assert state.qt_version_changed == changed
+
+
class TestYaml:
pytestmark = pytest.mark.usefixtures('config_tmpdir')