diff options
-rw-r--r-- | qutebrowser/mainwindow/tabwidget.py | 26 | ||||
-rw-r--r-- | tests/unit/mainwindow/test_tabwidget.py | 35 |
2 files changed, 59 insertions, 2 deletions
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 5e4f519fa..580da64b4 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -405,7 +405,8 @@ class TabBar(QTabBar): def __init__(self, win_id, parent=None): super().__init__(parent) self._win_id = win_id - self.setStyle(TabBarStyle()) + self._our_style = TabBarStyle() + self.setStyle(self._our_style) self.vertical = False self._auto_hide_timer = QTimer() self._auto_hide_timer.setSingleShot(True) @@ -696,6 +697,29 @@ class TabBar(QTabBar): qtutils.ensure_valid(size) return size + def initStyleOption(self, opt, idx): + """Override QTabBar.initStyleOption(). + + Used to calculate styling clues from a widget for the GUI layer. + """ + super().initStyleOption(opt, idx) + + # Re-do the text elision that the base QTabBar does, but using a text + # rectangle computed by out TabBarStyle. With Qt6 the base class ends + # up using QCommonStyle directly for that which has a different opinon + # of how vertical tabs should work. + text_rect = self._our_style.subElementRect( + QStyle.SubElement.SE_TabBarTabText, + opt, + self, + ) + opt.text = self.fontMetrics().elidedText( + self.tabText(idx), + self.elideMode(), + text_rect.width(), + Qt.TextFlag.TextShowMnemonic, + ) + def paintEvent(self, event): """Override paintEvent to draw the tabs like we want to.""" p = QStylePainter(self) diff --git a/tests/unit/mainwindow/test_tabwidget.py b/tests/unit/mainwindow/test_tabwidget.py index db300d7a6..d6289dac6 100644 --- a/tests/unit/mainwindow/test_tabwidget.py +++ b/tests/unit/mainwindow/test_tabwidget.py @@ -23,8 +23,9 @@ import functools import pytest -from qutebrowser.qt.gui import QIcon, QPixmap +from unittest.mock import Mock +from qutebrowser.qt.gui import QIcon, QPixmap from qutebrowser.mainwindow import tabwidget from qutebrowser.utils import usertypes @@ -71,6 +72,38 @@ class TestTabWidget: assert first_size == widget.tabBar().tabSizeHint(i) assert first_size_min == widget.tabBar().minimumTabSizeHint(i) + @pytest.fixture + def paint_spy(self, monkeypatch): + spy = Mock() + monkeypatch.setattr(tabwidget, "QStylePainter", spy) + return spy + + def test_tab_text_edlided_for_narrow_tabs(self, paint_spy, widget, fake_web_tab): + """Make sure text gets elided for narrow tabs.""" + widget.setMaximumWidth(100) + widget.addTab(fake_web_tab(), "one two three four") + + fake_paint_event = Mock() + fake_paint_event.region.return_value.intersects.return_value = True + widget.tabBar().paintEvent(fake_paint_event) + + style_opt = paint_spy.return_value.drawControl.call_args_list[0][0][1] + assert len(style_opt.text) < len(widget.tabBar().tabText(0)) + assert style_opt.text.endswith("…") + assert len(style_opt.text) > len("…") + + def test_tab_text_not_edlided_for_wide_tabs(self, paint_spy, widget, fake_web_tab): + """Make sure text doesn't get elided for wide tabs.""" + widget.setMaximumWidth(200) + widget.addTab(fake_web_tab(), "one two three four") + + fake_paint_event = Mock() + fake_paint_event.region.return_value.intersects.return_value = True + widget.tabBar().paintEvent(fake_paint_event) + + style_opt = paint_spy.return_value.drawControl.call_args_list[0][0][1] + assert style_opt.text.endswith(widget.tabBar().tabText(0)) + @pytest.mark.parametrize("shrink_pinned", [True, False]) @pytest.mark.parametrize("vertical", [True, False]) def test_pinned_size(self, widget, fake_web_tab, config_stub, |