Don't use stylesheets anymore for QTabWidget.
When using stylesheets there, all children (i.e. the QWebView) use QStyleSheetStyle as well, which means the bug at [1] will annoy us. We had to write our own font parsing as we can't use stylesheets, but at least the bug is gone... https://bugreports.qt-project.org/browse/QTBUG-40263
This commit is contained in:
parent
ee1b136807
commit
95df8a045c
@ -940,7 +940,7 @@ DATA = OrderedDict([
|
|||||||
"Font used in the completion widget."),
|
"Font used in the completion widget."),
|
||||||
|
|
||||||
('tabbar',
|
('tabbar',
|
||||||
SettingValue(types.Font(), '8pt ${_monospace}'),
|
SettingValue(types.QtFont(), '8pt ${_monospace}'),
|
||||||
"Font used in the tabbar."),
|
"Font used in the tabbar."),
|
||||||
|
|
||||||
('statusbar',
|
('statusbar',
|
||||||
|
@ -25,13 +25,30 @@ import os.path
|
|||||||
from sre_constants import error as RegexError
|
from sre_constants import error as RegexError
|
||||||
|
|
||||||
from PyQt5.QtCore import QUrl, QStandardPaths
|
from PyQt5.QtCore import QUrl, QStandardPaths
|
||||||
from PyQt5.QtGui import QColor
|
from PyQt5.QtGui import QColor, QFont
|
||||||
from PyQt5.QtNetwork import QNetworkProxy
|
from PyQt5.QtNetwork import QNetworkProxy
|
||||||
|
|
||||||
import qutebrowser.commands.utils as cmdutils
|
import qutebrowser.commands.utils as cmdutils
|
||||||
from qutebrowser.utils.misc import get_standard_dir
|
from qutebrowser.utils.misc import get_standard_dir
|
||||||
|
|
||||||
|
|
||||||
|
QSS_FONT_REGEX = re.compile(r"""
|
||||||
|
^(
|
||||||
|
(
|
||||||
|
# style
|
||||||
|
(?P<style>normal|italic|oblique) |
|
||||||
|
# weight (named | 100..900)
|
||||||
|
(
|
||||||
|
(?P<weight>[123456789]00) |
|
||||||
|
(?P<namedweight>normal|bold)
|
||||||
|
) |
|
||||||
|
# size (<float>pt | <int>px)
|
||||||
|
(?P<size>[0-9]+((\.[0-9]+)?[pP][tT]|[pP][xX]))
|
||||||
|
)\ # size/weight/style are space-separated
|
||||||
|
)* # 0-inf size/weight/style tags
|
||||||
|
(?P<family>[A-Za-z, "]*)$ # mandatory font family""", re.VERBOSE)
|
||||||
|
|
||||||
|
|
||||||
class ValidationError(ValueError):
|
class ValidationError(ValueError):
|
||||||
|
|
||||||
"""Exception raised when a value for a config type was invalid.
|
"""Exception raised when a value for a config type was invalid.
|
||||||
@ -530,8 +547,45 @@ class Font(BaseType):
|
|||||||
typestr = 'font'
|
typestr = 'font'
|
||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
# We can't really validate anything here
|
if not QSS_FONT_REGEX.match(value):
|
||||||
pass
|
raise ValidationError(value, "must be a valid font")
|
||||||
|
|
||||||
|
|
||||||
|
class QtFont(Font):
|
||||||
|
|
||||||
|
"""A Font which gets converted to q QFont."""
|
||||||
|
|
||||||
|
def transform(self, value):
|
||||||
|
style_map = {
|
||||||
|
'normal': QFont.StyleNormal,
|
||||||
|
'italic': QFont.StyleItalic,
|
||||||
|
'oblique': QFont.StyleOblique,
|
||||||
|
}
|
||||||
|
weight_map = {
|
||||||
|
'normal': QFont.Normal,
|
||||||
|
'bold': QFont.Bold,
|
||||||
|
}
|
||||||
|
font = QFont()
|
||||||
|
match = QSS_FONT_REGEX.match(value)
|
||||||
|
style = match.group('style')
|
||||||
|
weight = match.group('weight')
|
||||||
|
namedweight = match.group('weight')
|
||||||
|
size = match.group('size')
|
||||||
|
family = match.group('family')
|
||||||
|
if style:
|
||||||
|
font.setStyle(style_map[style])
|
||||||
|
if namedweight:
|
||||||
|
font.setWeight(weight_map[namedweight])
|
||||||
|
if weight:
|
||||||
|
# based on qcssparser.cpp:setFontWeightFromValue
|
||||||
|
font.setWeight(min(int(weight) / 8, 99))
|
||||||
|
if size:
|
||||||
|
if size.lower().endswith('pt'):
|
||||||
|
font.setPointSizeF(float(size[:-2]))
|
||||||
|
elif size.lower().endswith('px'):
|
||||||
|
font.setPointSizeF(int(size[:-2]))
|
||||||
|
font.setFamily(family)
|
||||||
|
return font
|
||||||
|
|
||||||
|
|
||||||
class Regex(BaseType):
|
class Regex(BaseType):
|
||||||
|
@ -32,7 +32,6 @@ from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
|||||||
QApplication)
|
QApplication)
|
||||||
from PyQt5.QtGui import QIcon, QPalette, QColor
|
from PyQt5.QtGui import QIcon, QPalette, QColor
|
||||||
|
|
||||||
from qutebrowser.config.style import set_register_stylesheet
|
|
||||||
from qutebrowser.utils.qt import qt_ensure_valid
|
from qutebrowser.utils.qt import qt_ensure_valid
|
||||||
import qutebrowser.config.config as config
|
import qutebrowser.config.config as config
|
||||||
|
|
||||||
@ -42,23 +41,7 @@ PM_TabBarPadding = QStyle.PM_CustomBase
|
|||||||
|
|
||||||
class TabWidget(QTabWidget):
|
class TabWidget(QTabWidget):
|
||||||
|
|
||||||
"""The tabwidget used for TabbedBrowser.
|
"""The tabwidget used for TabbedBrowser."""
|
||||||
|
|
||||||
Class attributes:
|
|
||||||
STYLESHEET: The stylesheet template to be used.
|
|
||||||
"""
|
|
||||||
|
|
||||||
STYLESHEET = """
|
|
||||||
QTabWidget::pane {{
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
}}
|
|
||||||
|
|
||||||
QTabBar {{
|
|
||||||
{font[tabbar]}
|
|
||||||
{color[tab.bg.bar]}
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -66,7 +49,6 @@ class TabWidget(QTabWidget):
|
|||||||
self.setTabBar(bar)
|
self.setTabBar(bar)
|
||||||
bar.tabCloseRequested.connect(self.tabCloseRequested)
|
bar.tabCloseRequested.connect(self.tabCloseRequested)
|
||||||
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
set_register_stylesheet(self)
|
|
||||||
self.setDocumentMode(True)
|
self.setDocumentMode(True)
|
||||||
self.setElideMode(Qt.ElideRight)
|
self.setElideMode(Qt.ElideRight)
|
||||||
self.setUsesScrollButtons(True)
|
self.setUsesScrollButtons(True)
|
||||||
@ -98,8 +80,9 @@ class TabWidget(QTabWidget):
|
|||||||
tabbar.refresh()
|
tabbar.refresh()
|
||||||
|
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str)
|
||||||
def on_config_changed(self, section, _option):
|
def on_config_changed(self, section, option):
|
||||||
"""Update attributes when config changed."""
|
"""Update attributes when config changed."""
|
||||||
|
self.tabBar().on_config_changed(section, option)
|
||||||
if section == 'tabbar':
|
if section == 'tabbar':
|
||||||
self._init_config()
|
self._init_config()
|
||||||
|
|
||||||
@ -119,6 +102,7 @@ class TabBar(QTabBar):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setStyle(TabBarStyle(self.style()))
|
self.setStyle(TabBarStyle(self.style()))
|
||||||
|
self.setFont(config.get('fonts', 'tabbar'))
|
||||||
self.vertical = False
|
self.vertical = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -141,6 +125,12 @@ class TabBar(QTabBar):
|
|||||||
self.setTabData(idx, color)
|
self.setTabData(idx, color)
|
||||||
self.update(self.tabRect(idx))
|
self.update(self.tabRect(idx))
|
||||||
|
|
||||||
|
@pyqtSlot(str, str)
|
||||||
|
def on_config_changed(self, section, option):
|
||||||
|
"""Update attributes when config changed."""
|
||||||
|
if section == 'fonts' and option == 'tabbar':
|
||||||
|
self.setFont(config.get('fonts', 'tabbar'))
|
||||||
|
|
||||||
def mousePressEvent(self, e):
|
def mousePressEvent(self, e):
|
||||||
"""Override mousePressEvent to close tabs if configured."""
|
"""Override mousePressEvent to close tabs if configured."""
|
||||||
button = config.get('tabbar', 'close-mouse-button')
|
button = config.get('tabbar', 'close-mouse-button')
|
||||||
|
Loading…
Reference in New Issue
Block a user