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

This commit is contained in:
Florian Bruhin 2017-10-31 07:05:38 +01:00
commit e9483bc485
3 changed files with 61 additions and 25 deletions

View File

@ -336,7 +336,7 @@ class TabBar(QTabBar):
return self.parent().currentWidget()
@pyqtSlot(str)
def _on_config_changed(self, option):
def _on_config_changed(self, option: str):
if option == 'fonts.tabs':
self._set_font()
elif option == 'tabs.favicons.scale':
@ -351,6 +351,12 @@ class TabBar(QTabBar):
if option.startswith('colors.tabs.'):
self.update()
# Clear _minimum_tab_size_hint_helper cache when appropriate
if option in ["tabs.indicator_padding",
"tabs.padding",
"tabs.width.indicator"]:
self._minimum_tab_size_hint_helper.cache_clear()
def _on_show_switching_delay_changed(self):
"""Set timer interval when tabs.show_switching_delay got changed."""
self._auto_hide_timer.setInterval(config.val.tabs.show_switching_delay)
@ -459,7 +465,7 @@ class TabBar(QTabBar):
return
super().mousePressEvent(e)
def minimumTabSizeHint(self, index, ellipsis: bool = True):
def minimumTabSizeHint(self, index, ellipsis: bool = True) -> QSize:
"""Set the minimum tab size to indicator/icon/... text.
Args:
@ -469,38 +475,47 @@ class TabBar(QTabBar):
Return:
A QSize of the smallest tab size we can make.
"""
text = '\u2026' if ellipsis else self.tabText(index)
icon = self.tabIcon(index)
extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None, self)
if icon.isNull():
icon_width = 0
else:
icon_width = icon.actualSize(QSize(extent, extent)).width()
return self._minimum_tab_size_hint_helper(self.tabText(index),
icon_width,
ellipsis)
@functools.lru_cache(maxsize=2**9)
def _minimum_tab_size_hint_helper(self, tab_text: str,
icon_width: int,
ellipsis: bool) -> QSize:
"""Helper function to cache tab results.
Config values accessed in here should be added to _on_config_changed to
ensure cache is flushed when needed.
"""
text = '\u2026' if ellipsis else tab_text
# Don't ever shorten if text is shorter than the ellipsis
text_width = min(self.fontMetrics().width(text),
self.fontMetrics().width(self.tabText(index)))
icon = self.tabIcon(index)
self.fontMetrics().width(tab_text))
padding = config.val.tabs.padding
indicator_padding = config.val.tabs.indicator_padding
padding_h = padding.left + padding.right
padding_h += indicator_padding.left + indicator_padding.right
padding_v = padding.top + padding.bottom
if icon.isNull():
icon_size = QSize(0, 0)
else:
extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None,
self)
icon_size = icon.actualSize(QSize(extent, extent))
height = self.fontMetrics().height() + padding_v
width = (text_width + icon_size.width() +
width = (text_width + icon_width +
padding_h + config.val.tabs.width.indicator)
return QSize(width, height)
def _tab_total_width_pinned(self):
"""Get the current total width of pinned tabs.
This width is calculated assuming no shortening due to ellipsis."""
return sum(self.minimumTabSizeHint(idx, ellipsis=False).width()
for idx in range(self.count())
if self._tab_pinned(idx))
def _pinnedCount(self) -> int:
"""Get the number of pinned tabs."""
return sum(self._tab_pinned(idx) for idx in range(self.count()))
def _pinned_statistics(self) -> (int, int):
"""Get the number of pinned tabs and the total width of pinned tabs."""
pinned_list = [idx for idx in range(self.count())
if self._tab_pinned(idx)]
pinned_count = len(pinned_list)
pinned_width = sum(self.minimumTabSizeHint(idx, ellipsis=False).width()
for idx in pinned_list)
return (pinned_count, pinned_width)
def _tab_pinned(self, index: int) -> bool:
"""Return True if tab is pinned."""
@ -539,8 +554,8 @@ class TabBar(QTabBar):
return QSize()
else:
pinned = self._tab_pinned(index)
no_pinned_count = self.count() - self._pinnedCount()
pinned_width = self._tab_total_width_pinned()
pinned_count, pinned_width = self._pinned_statistics()
no_pinned_count = self.count() - pinned_count
no_pinned_width = self.width() - pinned_width
if pinned:

View File

@ -182,9 +182,17 @@ def debug_cache_stats():
except ImportError:
pass
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
# pylint: disable=protected-access
tab_bar = tabbed_browser.tabBar()
tabbed_browser_info = tab_bar._minimum_tab_size_hint_helper.cache_info()
# pylint: enable=protected-access
log.misc.debug('is_valid_prefix: {}'.format(prefix_info))
log.misc.debug('_render_stylesheet: {}'.format(render_stylesheet_info))
log.misc.debug('history: {}'.format(history_info))
log.misc.debug('tab width cache: {}'.format(tabbed_browser_info))
@cmdutils.register(debug=True)

View File

@ -52,3 +52,16 @@ class TestTabWidget:
with qtbot.waitExposed(widget):
widget.show()
def test_update_tab_titles_benchmark(self, benchmark, widget,
qtbot, fake_web_tab):
"""Benchmark for update_tab_titles."""
widget.addTab(fake_web_tab(), 'foobar')
widget.addTab(fake_web_tab(), 'foobar2')
widget.addTab(fake_web_tab(), 'foobar3')
widget.addTab(fake_web_tab(), 'foobar4')
with qtbot.waitExposed(widget):
widget.show()
benchmark(widget._update_tab_titles)