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

This commit is contained in:
Florian Bruhin 2018-09-30 21:52:35 +02:00
commit b8be4e5915
2 changed files with 43 additions and 20 deletions

View File

@ -21,6 +21,7 @@
import functools
import enum
import contextlib
import attr
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint,
@ -214,8 +215,33 @@ class TabWidget(QTabWidget):
fields['scroll_pos'] = scroll_pos
return fields
@contextlib.contextmanager
def _toggle_visibility(self, force_toggle=False):
"""Toggle visibility while running.
Every single call to setTabText calls the size hinting functions for
every single tab, which are slow. Since we know we are updating all
the tab's titles, we can delay this processing by making the tab
non-visible. To avoid flickering, disable repaint updates whlie we
work.
Args:
force_toggle: Whether to always force the toggle, or only do it
if we have enough tabs for it to matter
"""
if self.count() > 10:
force_toggle = True
if force_toggle:
self.setUpdatesEnabled(False)
self.setVisible(False)
yield
if force_toggle:
self.setVisible(True)
self.setUpdatesEnabled(True)
def update_tab_titles(self):
"""Update all texts."""
with self._toggle_visibility():
for idx in range(self.count()):
self.update_tab_title(idx)

View File

@ -24,7 +24,7 @@ import functools
import pytest
from PyQt5.QtGui import QIcon, QPixmap
from qutebrowser.mainwindow import tabwidget, tabbedbrowser
from qutebrowser.mainwindow import tabwidget
from qutebrowser.utils import usertypes
@ -41,14 +41,6 @@ class TestTabWidget:
w.show()
return w
@pytest.fixture
def browser(self, qtbot, monkeypatch, config_stub):
w = tabbedbrowser.TabbedBrowser(win_id=0, private=False)
qtbot.addWidget(w)
monkeypatch.setattr(tabwidget.objects, 'backend',
usertypes.Backend.QtWebKit)
return w
def test_small_icon_doesnt_crash(self, widget, qtbot, fake_web_tab):
"""Test that setting a small icon doesn't produce a crash.
@ -117,7 +109,7 @@ class TestTabWidget:
assert first_size == widget.tabBar().tabSizeHint(i)
assert first_size_min == widget.tabBar().minimumTabSizeHint(i)
@pytest.mark.parametrize("num_tabs", [4, 10])
@pytest.mark.parametrize("num_tabs", [4, 10, 50, 100])
def test_update_tab_titles_benchmark(self, benchmark, widget,
qtbot, fake_web_tab, num_tabs):
"""Benchmark for update_tab_titles."""
@ -142,18 +134,23 @@ class TestTabWidget:
config_stub.val.tabs.max_width = max_size
assert widget.tabBar().tabRect(0).width() == max_size
@pytest.mark.parametrize("num_tabs", [4, 10])
def test_add_remove_tab_benchmark(self, benchmark, browser,
qtbot, fake_web_tab, num_tabs):
@pytest.mark.parametrize("num_tabs", [4, 100])
@pytest.mark.parametrize("rev", [True, False])
def test_add_remove_tab_benchmark(self, benchmark, widget,
qtbot, fake_web_tab, num_tabs, rev):
"""Benchmark for addTab and removeTab."""
def _run_bench():
with qtbot.wait_exposed(widget):
widget.show()
for i in range(num_tabs):
browser.widget.addTab(fake_web_tab(), 'foobar' + str(i))
idx = i if rev else 0
widget.insertTab(idx, fake_web_tab(), 'foobar' + str(i))
with qtbot.waitExposed(browser):
browser.show()
browser.shutdown()
to_del = range(num_tabs)
if rev:
to_del = reversed(to_del)
for i in to_del:
widget.removeTab(i)
benchmark(_run_bench)