Nuke the cache when the Qt version changed

https://bugreports.qt.io/browse/QTBUG-72532
This commit is contained in:
Florian Bruhin 2019-06-17 13:21:58 +02:00
parent d5ae3a76f3
commit f3db2c3fbe
3 changed files with 105 additions and 10 deletions

View File

@ -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

View File

@ -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)

View File

@ -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')