Merge remote-tracking branch 'origin/pr/4266'
This commit is contained in:
commit
b8be4e5915
@ -21,6 +21,7 @@
|
||||
|
||||
import functools
|
||||
import enum
|
||||
import contextlib
|
||||
|
||||
import attr
|
||||
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint,
|
||||
@ -214,10 +215,35 @@ 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."""
|
||||
for idx in range(self.count()):
|
||||
self.update_tab_title(idx)
|
||||
with self._toggle_visibility():
|
||||
for idx in range(self.count()):
|
||||
self.update_tab_title(idx)
|
||||
|
||||
def tabInserted(self, idx):
|
||||
"""Update titles when a tab was inserted."""
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user