Merge remote-tracking branch 'origin/pr/4185'

This commit is contained in:
Florian Bruhin 2018-09-06 16:15:16 +02:00
commit 108cc65bc6
8 changed files with 126 additions and 21 deletions

View File

@ -34,6 +34,7 @@ from qutebrowser.keyinput import keyutils
val = None val = None
instance = None instance = None
key_instance = None key_instance = None
cache = None
# Keeping track of all change filters to validate them later. # Keeping track of all change filters to validate them later.
change_filters = [] change_filters = []

View File

@ -0,0 +1,50 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2018 Jay Kamat <jaygkamat@gmail.com>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Implementation of a basic config cache."""
from qutebrowser.config import config
class ConfigCache:
"""A 'high-performance' cache for the config system.
Useful for areas which call out to the config system very frequently, DO
NOT modify the value returned, DO NOT require per-url settings, do not
change frequently, and do not require partially 'expanded' config paths.
If any of these requirements are broken, you will get incorrect or slow
behavior.
"""
def __init__(self) -> None:
self._cache = {}
config.instance.changed.connect(self._on_config_changed)
def _on_config_changed(self, attr: str) -> None:
if attr in self._cache:
self._cache[attr] = config.instance.get(attr)
def __getitem__(self, attr: str):
if attr not in self._cache:
assert not config.instance.get_opt(attr).supports_pattern
self._cache[attr] = config.instance.get(attr)
return self._cache[attr]

View File

@ -28,6 +28,7 @@ from qutebrowser.config import (config, configdata, configfiles, configtypes,
configexc, configcommands) configexc, configcommands)
from qutebrowser.utils import (objreg, usertypes, log, standarddir, message, from qutebrowser.utils import (objreg, usertypes, log, standarddir, message,
qtutils) qtutils)
from qutebrowser.config import configcache
from qutebrowser.misc import msgbox, objects from qutebrowser.misc import msgbox, objects
@ -44,6 +45,7 @@ def early_init(args):
config.instance = config.Config(yaml_config=yaml_config) config.instance = config.Config(yaml_config=yaml_config)
config.val = config.ConfigContainer(config.instance) config.val = config.ConfigContainer(config.instance)
config.key_instance = config.KeyConfig(config.instance) config.key_instance = config.KeyConfig(config.instance)
config.cache = configcache.ConfigCache()
yaml_config.setParent(config.instance) yaml_config.setParent(config.instance)
for cf in config.change_filters: for cf in config.change_filters:

View File

@ -719,9 +719,9 @@ class TabbedBrowser(QWidget):
except TabDeletedError: except TabDeletedError:
# We can get signals for tabs we already deleted... # We can get signals for tabs we already deleted...
return return
start = config.val.colors.tabs.indicator.start start = config.cache['colors.tabs.indicator.start']
stop = config.val.colors.tabs.indicator.stop stop = config.cache['colors.tabs.indicator.stop']
system = config.val.colors.tabs.indicator.system system = config.cache['colors.tabs.indicator.system']
color = utils.interpolate_color(start, stop, perc, system) color = utils.interpolate_color(start, stop, perc, system)
self.widget.set_tab_indicator_color(idx, color) self.widget.set_tab_indicator_color(idx, color)
self.widget.update_tab_title(idx) self.widget.update_tab_title(idx)

View File

@ -139,9 +139,9 @@ class TabWidget(QTabWidget):
""" """
tab = self.widget(idx) tab = self.widget(idx)
if tab.data.pinned: if tab.data.pinned:
fmt = config.val.tabs.title.format_pinned fmt = config.cache['tabs.title.format_pinned']
else: else:
fmt = config.val.tabs.title.format fmt = config.cache['tabs.title.format']
if (field is not None and if (field is not None and
(fmt is None or ('{' + field + '}') not in fmt)): (fmt is None or ('{' + field + '}') not in fmt)):
@ -604,7 +604,7 @@ class TabBar(QTabBar):
minimum_size = self.minimumTabSizeHint(index) minimum_size = self.minimumTabSizeHint(index)
height = minimum_size.height() height = minimum_size.height()
if self.vertical: if self.vertical:
confwidth = str(config.val.tabs.width) confwidth = str(config.cache['tabs.width'])
if confwidth.endswith('%'): if confwidth.endswith('%'):
main_window = objreg.get('main-window', scope='window', main_window = objreg.get('main-window', scope='window',
window=self._win_id) window=self._win_id)
@ -614,7 +614,7 @@ class TabBar(QTabBar):
width = int(confwidth) width = int(confwidth)
size = QSize(max(minimum_size.width(), width), height) size = QSize(max(minimum_size.width(), width), height)
else: else:
if config.val.tabs.pinned.shrink: if config.cache['tabs.pinned.shrink']:
pinned = self._tab_pinned(index) pinned = self._tab_pinned(index)
pinned_count, pinned_width = self._pinned_statistics() pinned_count, pinned_width = self._pinned_statistics()
else: else:
@ -652,15 +652,15 @@ class TabBar(QTabBar):
tab = QStyleOptionTab() tab = QStyleOptionTab()
self.initStyleOption(tab, idx) self.initStyleOption(tab, idx)
# pylint: disable=bad-config-option setting = 'colors.tabs'
setting = config.val.colors.tabs
# pylint: enable=bad-config-option
if idx == selected: if idx == selected:
setting = setting.selected setting += '.selected'
setting = setting.odd if (idx + 1) % 2 else setting.even setting += '.odd' if (idx + 1) % 2 else '.even'
tab.palette.setColor(QPalette.Window, setting.bg) tab.palette.setColor(QPalette.Window,
tab.palette.setColor(QPalette.WindowText, setting.fg) config.cache[setting + '.bg'])
tab.palette.setColor(QPalette.WindowText,
config.cache[setting + '.fg'])
indicator_color = self.tab_indicator_color(idx) indicator_color = self.tab_indicator_color(idx)
tab.palette.setColor(QPalette.Base, indicator_color) tab.palette.setColor(QPalette.Base, indicator_color)
@ -805,7 +805,7 @@ class TabBarStyle(QCommonStyle):
elif element == QStyle.CE_TabBarTabLabel: elif element == QStyle.CE_TabBarTabLabel:
if not opt.icon.isNull() and layouts.icon.isValid(): if not opt.icon.isNull() and layouts.icon.isValid():
self._draw_icon(layouts, opt, p) self._draw_icon(layouts, opt, p)
alignment = (config.val.tabs.title.alignment | alignment = (config.cache['tabs.title.alignment'] |
Qt.AlignVCenter | Qt.TextHideMnemonic) Qt.AlignVCenter | Qt.TextHideMnemonic)
self._style.drawItemText(p, layouts.text, alignment, opt.palette, self._style.drawItemText(p, layouts.text, alignment, opt.palette,
opt.state & QStyle.State_Enabled, opt.state & QStyle.State_Enabled,
@ -878,8 +878,8 @@ class TabBarStyle(QCommonStyle):
Return: Return:
A Layout object with two QRects. A Layout object with two QRects.
""" """
padding = config.val.tabs.padding padding = config.cache['tabs.padding']
indicator_padding = config.val.tabs.indicator.padding indicator_padding = config.cache['tabs.indicator.padding']
text_rect = QRect(opt.rect) text_rect = QRect(opt.rect)
if not text_rect.isValid(): if not text_rect.isValid():
@ -890,7 +890,7 @@ class TabBarStyle(QCommonStyle):
text_rect.adjust(padding.left, padding.top, -padding.right, text_rect.adjust(padding.left, padding.top, -padding.right,
-padding.bottom) -padding.bottom)
indicator_width = config.val.tabs.indicator.width indicator_width = config.cache['tabs.indicator.width']
if indicator_width == 0: if indicator_width == 0:
indicator_rect = QRect() indicator_rect = QRect()
else: else:
@ -933,9 +933,9 @@ class TabBarStyle(QCommonStyle):
icon_state = (QIcon.On if opt.state & QStyle.State_Selected icon_state = (QIcon.On if opt.state & QStyle.State_Selected
else QIcon.Off) else QIcon.Off)
# reserve space for favicon when tab bar is vertical (issue #1968) # reserve space for favicon when tab bar is vertical (issue #1968)
position = config.val.tabs.position position = config.cache['tabs.position']
if (position in [QTabWidget.East, QTabWidget.West] and if (position in [QTabWidget.East, QTabWidget.West] and
config.val.tabs.favicons.show != 'never'): config.cache['tabs.favicons.show'] != 'never'):
tab_icon_size = icon_size tab_icon_size = icon_size
else: else:
actual_size = opt.icon.actualSize(icon_size, icon_mode, icon_state) actual_size = opt.icon.actualSize(icon_size, icon_mode, icon_state)

View File

@ -147,6 +147,8 @@ PERFECT_FILES = [
'config/configcommands.py'), 'config/configcommands.py'),
('tests/unit/config/test_configutils.py', ('tests/unit/config/test_configutils.py',
'config/configutils.py'), 'config/configutils.py'),
('tests/unit/config/test_configcache.py',
'config/configcache.py'),
('tests/unit/utils/test_qtutils.py', ('tests/unit/utils/test_qtutils.py',
'utils/qtutils.py'), 'utils/qtutils.py'),

View File

@ -42,7 +42,7 @@ from PyQt5.QtNetwork import QNetworkCookieJar
import helpers.stubs as stubsmod import helpers.stubs as stubsmod
import helpers.utils import helpers.utils
from qutebrowser.config import (config, configdata, configtypes, configexc, from qutebrowser.config import (config, configdata, configtypes, configexc,
configfiles) configfiles, configcache)
from qutebrowser.utils import objreg, standarddir, utils, usertypes from qutebrowser.utils import objreg, standarddir, utils, usertypes
from qutebrowser.browser import greasemonkey from qutebrowser.browser import greasemonkey
from qutebrowser.browser.webkit import cookies from qutebrowser.browser.webkit import cookies
@ -253,6 +253,9 @@ def config_stub(stubs, monkeypatch, configdata_init, yaml_config_stub):
container = config.ConfigContainer(conf) container = config.ConfigContainer(conf)
monkeypatch.setattr(config, 'val', container) monkeypatch.setattr(config, 'val', container)
cache = configcache.ConfigCache()
monkeypatch.setattr(config, 'cache', cache)
try: try:
configtypes.Font.monospace_fonts = container.fonts.monospace configtypes.Font.monospace_fonts = container.fonts.monospace
except configexc.NoOptionError: except configexc.NoOptionError:

View File

@ -0,0 +1,47 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2018 Jay Kamat <jaygkamat@gmail.com>:
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Tests for qutebrowser.config.configcache."""
import pytest
from qutebrowser.config import config
def test_configcache_except_pattern(config_stub):
with pytest.raises(AssertionError):
assert config.cache['content.javascript.enabled']
def test_configcache_error_set(config_stub):
with pytest.raises(TypeError):
config.cache['content.javascript.enabled'] = True
def test_configcache_get(config_stub):
assert len(config.cache._cache) == 0
assert not config.cache['auto_save.session']
assert len(config.cache._cache) == 1
assert not config.cache['auto_save.session']
def test_configcache_get_after_set(config_stub):
assert not config.cache['auto_save.session']
config_stub.val.auto_save.session = True
assert config.cache['auto_save.session']