Repository: qutebrowser/qutebrowser

Issue:
Crash when window size is very, very small and lots of pinned tabs are present on a session restore

If you have a lot of pinned tabs and shrink qb, then close (with session auto restore on), and the new window restores as small as it was (tiny) this happens.

```
Traceback (most recent call last):
  File "qutebrowser\mainwindow\tabwidget.py", line 545, in tabSizeHint
  File "qutebrowser\utils\qtutils.py", line 175, in ensure_valid
qutebrowser.utils.qtutils.QtValueError: PyQt5.QtCore.QSize(-3, 20) is not valid
```

```
==== Version info ====
qutebrowser v0.11.0
Git commit: v0.11.0-9-geaecfe588 (2017-07-04 22:27:17 +0200)
Backend: QtWebEngine (Chromium 56.0.2924.122)
```

I think that the cause of this is pretty clear, I'll try and work on this tonight. I probably should have tested this on a non-tiling WM 😄 


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
@@ -503,10 +503,6 @@ def tabSizeHint(self, index):
             # We return it directly rather than setting `size' because we don't
             # want to ensure it's valid in this special case.
             return QSize()
-        elif self.count() * minimum_size.width() > self.width():
-            # If we don't have enough space, we return the minimum size so we
-            # get scroll buttons as soon as needed.
-            size = minimum_size
         else:
             tab_width_pinned_conf = config.get('tabs', 'pinned-width')
 
@@ -523,13 +519,13 @@ def tabSizeHint(self, index):
                 width = tab_width_pinned_conf
             else:
 
-                # If we *do* have enough space, tabs should occupy the whole
-                # window width. If there are pinned tabs their size will be
-                # subtracted from the total window width.
-                # During shutdown the self.count goes down,
-                # but the self.pinned_count not - this generates some odd
+                # Tabs should attempt to occupy the whole window width. If
+                # there are pinned tabs their size will be subtracted from the
+                # total window width.  During shutdown the self.count goes
+                # down, but the self.pinned_count not - this generates some odd
                 # behavior. To avoid this we compare self.count against
-                # self.pinned_count.
+                # self.pinned_count. If we end up having too little space, we
+                # set the minimum size below.
                 if self.pinned_count > 0 and no_pinned_count > 0:
                     width = no_pinned_width / no_pinned_count
                 else:
@@ -541,6 +537,10 @@ def tabSizeHint(self, index):
                     index < no_pinned_width % no_pinned_count):
                 width += 1
 
+            # If we don't have enough space, we return the minimum size so we
+            # get scroll buttons as soon as needed.
+            width = max(width, minimum_size.width())
+
             size = QSize(width, height)
         qtutils.ensure_valid(size)
         return size


Test patch: