From 801f6b2667ba3dfc1cfd159769939d0fa6cb65c5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 3 Mar 2015 23:21:23 +0100 Subject: [PATCH] Fix handling of signals with deleted tabs. --- qutebrowser/mainwindow/tabbedbrowser.py | 60 +++++++++++++------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 50cf582db..40adb6d7f 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -38,6 +38,11 @@ from qutebrowser.utils import (log, message, usertypes, utils, qtutils, objreg, UndoEntry = collections.namedtuple('UndoEntry', ['url', 'history']) +class TabDeletedError(Exception): + + """Exception raised when _tab_index is called for a deleted tab.""" + + class TabbedBrowser(tabwidget.TabWidget): """A TabWidget with QWebViews inside. @@ -119,6 +124,21 @@ class TabbedBrowser(tabwidget.TabWidget): def __repr__(self): return utils.get_repr(self, count=self.count()) + def _tab_index(self, tab): + """Get the index of a given tab. + + Raises TabDeletedError if the tab doesn't exist anymore. + """ + try: + idx = self.indexOf(tab) + except RuntimeError as e: + log.webview.debug("Got invalid tab {} ({})!".format(tab, e)) + raise TabDeletedError(e) + if idx == -1: + log.webview.debug("Got invalid tab {} (index is -1)!".format(tab)) + raise TabDeletedError("index is -1!") + return idx + def widgets(self): """Get a list of open tab widgets. @@ -428,14 +448,10 @@ class TabbedBrowser(tabwidget.TabWidget): tab: The tab where the signal belongs to. """ try: - idx = self.indexOf(tab) - except RuntimeError: + idx = self._tab_index(tab) + except TabDeletedError: # We can get signals for tabs we already deleted... return - if idx == -1: - # We can get signals for tabs we already deleted... - log.webview.debug("Got invalid tab {}!".format(tab)) - return self.update_tab_title(idx) if tab.keep_icon: tab.keep_icon = False @@ -466,16 +482,12 @@ class TabbedBrowser(tabwidget.TabWidget): log.webview.debug("Ignoring title change to '{}'.".format(text)) return try: - idx = self.indexOf(tab) - except RuntimeError: + idx = self._tab_index(tab) + except TabDeletedError: # We can get signals for tabs we already deleted... return log.webview.debug("Changing title for idx {} to '{}'".format( idx, text)) - if idx == -1: - # We can get signals for tabs we already deleted... - log.webview.debug("Got invalid tab {}!".format(tab)) - return self.set_page_title(idx, text) if idx == self.currentIndex(): self.update_window_title() @@ -489,14 +501,10 @@ class TabbedBrowser(tabwidget.TabWidget): url: The new URL. """ try: - idx = self.indexOf(tab) - except RuntimeError: + idx = self._tab_index(tab) + except TabDeletedError: # We can get signals for tabs we already deleted... return - if idx == -1: - # We can get signals for tabs we already deleted... - log.webview.debug("Got invalid tab {}!".format(tab)) - return if not self.page_title(idx): self.set_page_title(idx, url) @@ -512,14 +520,10 @@ class TabbedBrowser(tabwidget.TabWidget): if not config.get('tabs', 'show-favicons'): return try: - idx = self.indexOf(tab) - except RuntimeError: + idx = self._tab_index(tab) + except TabDeletedError: # We can get signals for tabs we already deleted... return - if idx == -1: - # We can get *_changed signals for tabs we already deleted... - log.webview.debug("Got invalid tab {}!".format(tab)) - return self.setTabIcon(idx, tab.icon()) @pyqtSlot(usertypes.KeyMode) @@ -562,8 +566,8 @@ class TabbedBrowser(tabwidget.TabWidget): def on_load_progress(self, tab, perc): """Adjust tab indicator on load progress.""" try: - idx = self.indexOf(tab) - except RuntimeError: + idx = self._tab_index(tab) + except TabDeletedError: # We can get signals for tabs we already deleted... return start = config.get('colors', 'tabs.indicator.start') @@ -583,8 +587,8 @@ class TabbedBrowser(tabwidget.TabWidget): See https://github.com/The-Compiler/qutebrowser/issues/84 """ try: - idx = self.indexOf(tab) - except RuntimeError: + idx = self._tab_index(tab) + except TabDeletedError: # We can get signals for tabs we already deleted... return if tab.page().error_occured: