Repository: qutebrowser/qutebrowser

Issue:
Pinned tab titles stretch tabs bar beyond the `tabs.width` value
<!-- If this is a bug report, please remember to mention your version info from
`:open qute:version` or `qutebrowser --version` -->

**Step to reproduce**:
- Set `tabs.title.alignment` to `left`;
- Set `tabs.width` to `2%` _(or any other very small value)_;
- Set `tabs.title.format_pinned` to a very long string;

**Expected result**:
The tab title should be cropped respecting the defined `tabs.width`.

**Actual result**:
The tab bar expands to display the longest pinned tab title.

**Version**:
http://paste.the-compiler.org/view/f002785d



Discussion:

Resolving patch:
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -494,8 +494,8 @@ def minimumTabSizeHint(self, index, ellipsis: bool = True) -> QSize:
                              self.iconSize().width()) + icon_padding
 
         pinned = self._tab_pinned(index)
-        if pinned:
-            # Never consider ellipsis an option for pinned tabs
+        if not self.vertical and pinned and config.val.tabs.pinned.shrink:
+            # Never consider ellipsis an option for horizontal pinned tabs
             ellipsis = False
         return self._minimum_tab_size_hint_helper(self.tabText(index),
                                                   icon_width, ellipsis,


Test patch:
diff --git a/tests/unit/mainwindow/test_tabwidget.py b/tests/unit/mainwindow/test_tabwidget.py
--- a/tests/unit/mainwindow/test_tabwidget.py
+++ b/tests/unit/mainwindow/test_tabwidget.py
@@ -61,6 +61,60 @@ def test_small_icon_doesnt_crash(self, widget, qtbot, fake_web_tab):
         with qtbot.waitExposed(widget):
             widget.show()
 
+    # Sizing tests
+
+    def test_tab_size_same(self, widget, fake_web_tab):
+        """Ensure by default, all tab sizes are the same."""
+        num_tabs = 10
+        for i in range(num_tabs):
+            widget.addTab(fake_web_tab(), 'foobar' + str(i))
+
+        first_size = widget.tabBar().tabSizeHint(0)
+        first_size_min = widget.tabBar().minimumTabSizeHint(0)
+
+        for i in range(num_tabs):
+            assert first_size == widget.tabBar().tabSizeHint(i)
+            assert first_size_min == widget.tabBar().minimumTabSizeHint(i)
+
+    @pytest.mark.parametrize("shrink_pinned", [True, False])
+    @pytest.mark.parametrize("vertical", [True, False])
+    def test_pinned_size(self, widget, fake_web_tab, config_stub,
+                         shrink_pinned, vertical):
+        """Ensure by default, pinned min sizes are forced to title.
+
+        If pinned.shrink is not true, then all tabs should be the same
+
+        If tabs are vertical, all tabs should be the same"""
+        num_tabs = 10
+        for i in range(num_tabs):
+            widget.addTab(fake_web_tab(), 'foobar' + str(i))
+
+        # Set pinned title format longer than unpinned
+        config_stub.val.tabs.title.format_pinned = "_" * 20
+        config_stub.val.tabs.title.format = "_" * 2
+        config_stub.val.tabs.pinned.shrink = shrink_pinned
+        if vertical:
+            # Use pixel width so we don't need to mock main-window
+            config_stub.val.tabs.width = 50
+            config_stub.val.tabs.position = "left"
+
+        pinned_num = [1, num_tabs - 1]
+        for tab in pinned_num:
+            widget.set_tab_pinned(widget.widget(tab), True)
+
+        first_size = widget.tabBar().tabSizeHint(0)
+        first_size_min = widget.tabBar().minimumTabSizeHint(0)
+
+        for i in range(num_tabs):
+            if i in pinned_num and shrink_pinned and not vertical:
+                assert (first_size.width() <
+                        widget.tabBar().tabSizeHint(i).width())
+                assert (first_size_min.width() <
+                        widget.tabBar().minimumTabSizeHint(i).width())
+            else:
+                assert first_size == widget.tabBar().tabSizeHint(i)
+                assert first_size_min == widget.tabBar().minimumTabSizeHint(i)
+
     @pytest.mark.parametrize("num_tabs", [4, 10])
     def test_update_tab_titles_benchmark(self, benchmark, widget,
                                          qtbot, fake_web_tab, num_tabs):