Try to shut down everything cleanly.

This commit is contained in:
Florian Bruhin 2014-02-17 10:20:57 +01:00
parent 63ee3f4efd
commit 0abb5cf738
2 changed files with 60 additions and 2 deletions

View File

@ -94,7 +94,7 @@ class QuteBrowser(QApplication):
self._init_cmds() self._init_cmds()
self.mainwindow = MainWindow() self.mainwindow = MainWindow()
self.aboutToQuit.connect(config.config.save) self.aboutToQuit.connect(self._shutdown)
self.mainwindow.tabs.keypress.connect(self.keyparser.handle) self.mainwindow.tabs.keypress.connect(self.keyparser.handle)
self.keyparser.set_cmd_text.connect(self.mainwindow.status.cmd.set_cmd) self.keyparser.set_cmd_text.connect(self.mainwindow.status.cmd.set_cmd)
self.mainwindow.tabs.set_cmd_text.connect( self.mainwindow.tabs.set_cmd_text.connect(
@ -244,6 +244,11 @@ class QuteBrowser(QApplication):
except KeyError: except KeyError:
pass pass
def _shutdown(self):
"""Try to shutdown everything cleanly."""
config.config.save()
self.mainwindow.tabs.shutdown()
def cmd_handler(self, tpl): def cmd_handler(self, tpl):
"""Handle commands and delegate the specific actions. """Handle commands and delegate the specific actions.

View File

@ -30,7 +30,8 @@ from PyQt5.QtWidgets import QShortcut, QApplication, QSizePolicy
from PyQt5.QtCore import pyqtSignal, Qt, QEvent from PyQt5.QtCore import pyqtSignal, Qt, QEvent
from PyQt5.QtGui import QClipboard from PyQt5.QtGui import QClipboard
from PyQt5.QtPrintSupport import QPrintPreviewDialog from PyQt5.QtPrintSupport import QPrintPreviewDialog
from PyQt5.QtNetwork import QNetworkReply from PyQt5.QtNetwork import QNetworkReply, QNetworkAccessManager
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWebKitWidgets import QWebView, QWebPage from PyQt5.QtWebKitWidgets import QWebView, QWebPage
import qutebrowser.utils.about as about import qutebrowser.utils.about as about
@ -157,6 +158,7 @@ class TabbedBrowser(TabWidget):
self._tabs.remove(tab) self._tabs.remove(tab)
except ValueError: except ValueError:
pass pass
tab.shutdown()
else: else:
# FIXME # FIXME
pass pass
@ -428,6 +430,11 @@ class TabbedBrowser(TabWidget):
if log_signal: if log_signal:
logging.debug(' ignoring') logging.debug(' ignoring')
def shutdown(self):
"""Try to shut down all tabs cleanly."""
self.currentChanged.disconnect()
for tabidx in range(self.count()):
self.widget(tabidx).shutdown()
class BrowserTab(QWebView): class BrowserTab(QWebView):
@ -502,6 +509,21 @@ class BrowserTab(QWebView):
""" """
self.progress = prog self.progress = prog
def shutdown(self):
"""Shut down the tab cleanly and remove it.
Inspired by [1].
[1] https://github.com/integricho/path-of-a-pyqter/tree/master/qttut08
"""
self.stop()
self.close()
self.settings().setAttribute(QWebSettings.JavascriptEnabled, False)
self.page().deleteLater()
self.deleteLater()
self.page().networkAccessManager().abort_requests()
self.page().networkAccessManager().deleteLater()
def eventFilter(self, watched, e): def eventFilter(self, watched, e):
"""Dirty hack to emit a signal if the scroll position changed. """Dirty hack to emit a signal if the scroll position changed.
@ -552,12 +574,15 @@ class BrowserPage(QWebPage):
"""Our own QWebPage with advanced features.""" """Our own QWebPage with advanced features."""
_extension_handlers = None _extension_handlers = None
_network_access_manager = None
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._extension_handlers = { self._extension_handlers = {
QWebPage.ErrorPageExtension: self._handle_errorpage, QWebPage.ErrorPageExtension: self._handle_errorpage,
} }
self._network_access_manager = NetworkManager()
self.setNetworkAccessManager(self._network_access_manager)
def supportsExtension(self, ext): def supportsExtension(self, ext):
"""Override QWebPage::supportsExtension to provide error pages.""" """Override QWebPage::supportsExtension to provide error pages."""
@ -589,3 +614,31 @@ class BrowserPage(QWebPage):
errpage.content = read_file('html/error.html').format( errpage.content = read_file('html/error.html').format(
title=title, url=urlstr, error=info.errorString, icon='') title=title, url=urlstr, error=info.errorString, icon='')
return True return True
class NetworkManager(QNetworkAccessManager):
"""Our own QNetworkAccessManager."""
_requests = None
def __init__(self, parent=None):
self._requests = {}
super().__init__(parent)
def abort_requests(self):
"""Abort all running requests."""
for request in self._requests.values():
request.abort()
def createRequest(self, op, req, outgoing_data):
"""Return a new QNetworkReply object.
Extend QNetworkAccessManager::createRequest to save requests in
self._requests.
"""
reply = super().createRequest(op, req, outgoing_data)
self._requests[id(reply)] = reply
reply.destroyed.connect(lambda obj: self._requests.pop(id(obj)))
return reply