summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoofar <toofar@spalge.com>2024-01-03 18:48:48 +1300
committertoofar <toofar@spalge.com>2024-01-06 20:54:43 +1300
commit3ec2000b2f1cc4ea95d25ef4804871e82fcc8d69 (patch)
tree50861659005053418cfc7003916868cfd6323a6f
parent8aa88b83e8b63a81958882d9d6a2abff63a5cc76 (diff)
downloadqutebrowser-3ec2000b2f1cc4ea95d25ef4804871e82fcc8d69.tar.gz
qutebrowser-3ec2000b2f1cc4ea95d25ef4804871e82fcc8d69.zip
Handle tab title updates while loading hidden tabs from a session
This is the third case where errors have been raised from update_tab_titles() due to a mismatch between the tab widget and node tree: 1. on startup when the tabs are being added to the widget but the tree hasn't grown yet - identified with heuristic 2. when hiding and showing tabs - changed logic to not fire updates mid-operation 3. when shutting down tabs get removed from the widget before they are removed from the tree - changed logic to not fire updates mid-operation Now there is a fourth issue: loading a session with hidden tabs. In this case tabs will be in the widget but not in the rendered tree, because that doesn't include hidden nodes. I'm using "all the URLs are empty" as a proxy for "a session is loading into this window". That combined with there being a hidden tab in the tree should hopefully be a good enough heuristic for this case. Although it would be good to check with 100% certainty that a session was being loaded. Or just having something to see if the current window was still being initialized would do it, as sessions are always loaded into new windows. I've refactored the logic in this method so that we are matching on exact tab value, instead of having two lists and assuming the indexes are going to line up. This way seems a bit more deliberate.
-rw-r--r--qutebrowser/mainwindow/treetabwidget.py74
1 files changed, 59 insertions, 15 deletions
diff --git a/qutebrowser/mainwindow/treetabwidget.py b/qutebrowser/mainwindow/treetabwidget.py
index 8534a6283..082b7a079 100644
--- a/qutebrowser/mainwindow/treetabwidget.py
+++ b/qutebrowser/mainwindow/treetabwidget.py
@@ -38,27 +38,71 @@ class TreeTabWidget(TabWidget):
return fields
rendered_tree = self.tree_root.render()
+ tab = self.widget(idx)
+ found = [
+ prefix
+ for prefix, node in rendered_tree
+ if node.value == tab
+ ]
+
+ if len(found) == 1:
+ # we remove the first two chars because every tab is child of tree
+ # root and that gets rendered as well
+ fields['tree'] = found[0][2:]
+ fields['collapsed'] = '[...] ' if tab.node.collapsed else ''
+ return fields
- # We are getting called with an index into the tab bar. If we have a
- # different amount of nodes in the tree than the tab bar that
- # indicates a logic error.
- difference = len(rendered_tree) - 1 - self.count()
- if difference != 0:
- tabs = [str(self.widget(idx)) for idx in range(self.count())]
+ # Beyond here we have a mismatch between the tab widget and the tree.
+ # Try to identify known situations where this happens precisely and
+ # handle them gracefully. Blow up on unknown situations so we don't
+ # miss them.
+
+ # Just sanity checking, we haven't seen this yet.
+ assert len(found) == 0, (
+ "Found multiple tree nodes with the same tab as value: tab={tab}"
+ )
+
+ # Having more tabs in the widget when loading a session with a
+ # collapsed group in is a known case. Check for it with a heuristic
+ # (for now) and assert if that doesn't look like that's how we got
+ # here.
+ all_nodes = self.tree_root.traverse()
+ node = [n for n in all_nodes if n.value == tab][0]
+ is_hidden = any(n.collapsed for n in node.path)
+
+ tabs = [str(self.widget(idx)) for idx in range(self.count())]
+ difference = len(rendered_tree) - 1 - len(tabs)
+ # empty_urls here is a proxy for "there is a session being loaded into
+ # this window"
+ empty_urls = all(
+ [self.widget(idx).url().toString() == "" for idx in range(self.count())]
+ )
+ if empty_urls and is_hidden:
+ # All tabs will be added to the tab widget during session load
+ # and they will only be removed later when the widget is
+ # updated from the tree. Meanwhile, if we get here we'll have
+ # hidden tabs present in the widget but absent from the node.
+ # To detect this situation more clearly we could do something like
+ # have a is_starting_up or is_loading_session attribute on the
+ # tabwidget/tabbbedbrowser. Or have the session manager add all
+ # nodes to the tree uncollapsed initially and then go through and
+ # collapse them.
+ log.misc.vdebug(
+ "get_tab_fields() called with different amount of tabs in "
+ f"widget vs in the tree: difference={difference} "
+ f"tree={rendered_tree[1:]} tabs={tabs}"
+ )
+ else:
+ # If we get here then we have another case to investigate.
assert difference == 0, (
"Different amount of nodes in tree than widget. "
f"difference={difference} tree={rendered_tree[1:]} tabs={tabs}"
)
- # we remove the first two chars because every tab is child of tree
- # root and that gets rendered as well
- pre, _ = rendered_tree[idx+1]
- tree_prefix = pre[2:]
- fields['tree'] = tree_prefix
-
- tab = self.widget(idx)
- fields['collapsed'] = '[...] ' if tab.node.collapsed else ''
-
+ # Return dummy entries for now. Once we finish whatever operation is
+ # causing the current irregularity we should get proper values.
+ fields["tree"] = ""
+ fields["collapsed"] = ""
return fields
def update_tree_tab_positions(self):