Merge branch 'shutdown'
Conflicts: qutebrowser/widgets/webview.py
This commit is contained in:
commit
cb8af1de31
@ -578,22 +578,6 @@ class Application(QApplication):
|
|||||||
self._destroy_crashlogfile()
|
self._destroy_crashlogfile()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def _maybe_quit(self, sender):
|
|
||||||
"""Maybe quit qutebrowser.
|
|
||||||
|
|
||||||
This only quits if both the ExceptionCrashDialog was ready to quit AND
|
|
||||||
the shutdown is complete.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
The sender of the quit signal (string)
|
|
||||||
"""
|
|
||||||
self._quit_status[sender] = True
|
|
||||||
log.destroy.debug("maybe_quit called from {}, quit status {}".format(
|
|
||||||
sender, self._quit_status))
|
|
||||||
if all(self._quit_status.values()):
|
|
||||||
log.destroy.debug("maybe_quit quitting.")
|
|
||||||
self.quit()
|
|
||||||
|
|
||||||
@cmdutils.register(instance='', nargs=0)
|
@cmdutils.register(instance='', nargs=0)
|
||||||
def restart(self, shutdown=True, pages=None):
|
def restart(self, shutdown=True, pages=None):
|
||||||
"""Restart qutebrowser while keeping existing tabs open."""
|
"""Restart qutebrowser while keeping existing tabs open."""
|
||||||
@ -687,26 +671,8 @@ class Application(QApplication):
|
|||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
log.destroy.warning("Could not save {}.".format(what))
|
log.destroy.warning("Could not save {}.".format(what))
|
||||||
log.destroy.debug(e)
|
log.destroy.debug(e)
|
||||||
# Shut down tabs
|
|
||||||
try:
|
|
||||||
self.mainwindow.tabs.shutdown_complete.connect(partial(
|
|
||||||
self._maybe_quit, 'tabs'))
|
|
||||||
self.mainwindow.tabs.shutdown()
|
|
||||||
except AttributeError as e: # mainwindow or tabs could still be None
|
|
||||||
log.destroy.warning("No mainwindow/tabs to shut down ({}).".format(
|
|
||||||
e))
|
|
||||||
self._maybe_quit('tabs')
|
|
||||||
# Re-enable faulthandler to stdout, then remove crash log
|
# Re-enable faulthandler to stdout, then remove crash log
|
||||||
self._destroy_crashlogfile()
|
self._destroy_crashlogfile()
|
||||||
# If we don't kill our custom handler here we might get segfaults
|
# If we don't kill our custom handler here we might get segfaults
|
||||||
qInstallMessageHandler(None)
|
qInstallMessageHandler(None)
|
||||||
self._maybe_quit('main')
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_tab_shutdown_complete(self):
|
|
||||||
"""Quit application after a shutdown.
|
|
||||||
|
|
||||||
Gets called when all tabs finished shutting down after shutdown().
|
|
||||||
"""
|
|
||||||
log.destroy.debug("Shutdown complete, quitting.")
|
|
||||||
self.quit()
|
self.quit()
|
||||||
|
@ -73,7 +73,6 @@ class TabbedBrowser(TabWidget):
|
|||||||
cur_load_status_changed: Loading status of current tab changed.
|
cur_load_status_changed: Loading status of current tab changed.
|
||||||
hint_strings_updated: Hint strings were updated.
|
hint_strings_updated: Hint strings were updated.
|
||||||
arg: A list of hint strings.
|
arg: A list of hint strings.
|
||||||
shutdown_complete: The shuttdown is completed.
|
|
||||||
quit: The last tab was closed, quit application.
|
quit: The last tab was closed, quit application.
|
||||||
resized: Emitted when the browser window has resized, so the completion
|
resized: Emitted when the browser window has resized, so the completion
|
||||||
widget can adjust its size to it.
|
widget can adjust its size to it.
|
||||||
@ -97,7 +96,6 @@ class TabbedBrowser(TabWidget):
|
|||||||
start_download = pyqtSignal('QNetworkReply*')
|
start_download = pyqtSignal('QNetworkReply*')
|
||||||
download_get = pyqtSignal('QUrl', 'QWebPage')
|
download_get = pyqtSignal('QUrl', 'QWebPage')
|
||||||
hint_strings_updated = pyqtSignal(list)
|
hint_strings_updated = pyqtSignal(list)
|
||||||
shutdown_complete = pyqtSignal()
|
|
||||||
quit = pyqtSignal()
|
quit = pyqtSignal()
|
||||||
resized = pyqtSignal('QRect')
|
resized = pyqtSignal('QRect')
|
||||||
got_cmd = pyqtSignal(str)
|
got_cmd = pyqtSignal(str)
|
||||||
@ -133,24 +131,6 @@ class TabbedBrowser(TabWidget):
|
|||||||
w.append(self.widget(i))
|
w.append(self.widget(i))
|
||||||
return w
|
return w
|
||||||
|
|
||||||
def _cb_tab_shutdown(self, tab):
|
|
||||||
"""Called after a tab has been shut down completely.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tab: The tab object which has been shut down.
|
|
||||||
|
|
||||||
Emit:
|
|
||||||
shutdown_complete: When the tab shutdown is done completely.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self._tabs.remove(tab)
|
|
||||||
except ValueError:
|
|
||||||
log.destroy.exception("tab {} could not be removed")
|
|
||||||
log.destroy.debug("Tabs after removing: {}".format(self._tabs))
|
|
||||||
if not self._tabs: # all tabs shut down
|
|
||||||
log.destroy.debug("Tab shutdown complete.")
|
|
||||||
self.shutdown_complete.emit()
|
|
||||||
|
|
||||||
def _connect_tab_signals(self, tab):
|
def _connect_tab_signals(self, tab):
|
||||||
"""Set up the needed signals for tab."""
|
"""Set up the needed signals for tab."""
|
||||||
page = tab.page()
|
page = tab.page()
|
||||||
@ -243,12 +223,8 @@ class TabbedBrowser(TabWidget):
|
|||||||
log.destroy.debug("Error while shutting down tabs: {}: {}".format(
|
log.destroy.debug("Error while shutting down tabs: {}: {}".format(
|
||||||
e.__class__.__name__, e))
|
e.__class__.__name__, e))
|
||||||
tabcount = self.count()
|
tabcount = self.count()
|
||||||
if tabcount == 0:
|
|
||||||
log.destroy.debug("No tabs -> shutdown complete")
|
|
||||||
self.shutdown_complete.emit()
|
|
||||||
return
|
|
||||||
for tab in self.widgets:
|
for tab in self.widgets:
|
||||||
tab.shutdown(callback=partial(self._cb_tab_shutdown, tab))
|
self._tabs.remove(tab)
|
||||||
|
|
||||||
def close_tab(self, tab_or_idx):
|
def close_tab(self, tab_or_idx):
|
||||||
"""Close a tab with either index or tab given.
|
"""Close a tab with either index or tab given.
|
||||||
@ -278,8 +254,7 @@ class TabbedBrowser(TabWidget):
|
|||||||
if not url.isEmpty():
|
if not url.isEmpty():
|
||||||
qt_ensure_valid(url)
|
qt_ensure_valid(url)
|
||||||
self.url_stack.append(url)
|
self.url_stack.append(url)
|
||||||
tab.shutdown(callback=partial(self._cb_tab_shutdown, tab))
|
self._tabs.remove(tab)
|
||||||
log.destroy.debug("Removing tab {}/{}".format(idx, tab))
|
|
||||||
self.removeTab(idx)
|
self.removeTab(idx)
|
||||||
elif last_close == 'quit':
|
elif last_close == 'quit':
|
||||||
self.quit.emit()
|
self.quit.emit()
|
||||||
|
@ -67,10 +67,7 @@ class WebView(QWebView):
|
|||||||
_has_ssl_errors: Whether SSL errors occured during loading.
|
_has_ssl_errors: Whether SSL errors occured during loading.
|
||||||
_zoom: A NeighborList with the zoom levels.
|
_zoom: A NeighborList with the zoom levels.
|
||||||
_old_scroll_pos: The old scroll position.
|
_old_scroll_pos: The old scroll position.
|
||||||
_shutdown_callback: Callback to be called after shutdown.
|
|
||||||
_force_open_target: Override for _open_target.
|
_force_open_target: Override for _open_target.
|
||||||
_shutdown_callback: The callback to call after shutting down.
|
|
||||||
_destroyed: Dict of all items to be destroyed on shtudown.
|
|
||||||
_check_insertmode: If True, in mouseReleaseEvent we should check if we
|
_check_insertmode: If True, in mouseReleaseEvent we should check if we
|
||||||
need to enter/leave insert mode.
|
need to enter/leave insert mode.
|
||||||
|
|
||||||
@ -98,11 +95,9 @@ class WebView(QWebView):
|
|||||||
self.scroll_pos = (-1, -1)
|
self.scroll_pos = (-1, -1)
|
||||||
self.statusbar_message = ''
|
self.statusbar_message = ''
|
||||||
self._old_scroll_pos = (-1, -1)
|
self._old_scroll_pos = (-1, -1)
|
||||||
self._shutdown_callback = None
|
|
||||||
self._open_target = None
|
self._open_target = None
|
||||||
self.open_target = ClickTarget.normal
|
self.open_target = ClickTarget.normal
|
||||||
self._force_open_target = None
|
self._force_open_target = None
|
||||||
self._destroyed = {}
|
|
||||||
self._zoom = None
|
self._zoom = None
|
||||||
self._has_ssl_errors = False
|
self._has_ssl_errors = False
|
||||||
self._init_neighborlist()
|
self._init_neighborlist()
|
||||||
@ -180,22 +175,6 @@ class WebView(QWebView):
|
|||||||
default=config.get('ui', 'default-zoom'),
|
default=config.get('ui', 'default-zoom'),
|
||||||
mode=NeighborList.Modes.block)
|
mode=NeighborList.Modes.block)
|
||||||
|
|
||||||
def _on_destroyed(self, sender):
|
|
||||||
"""Called when a subsystem has been destroyed during shutdown.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
sender: The object which called the callback.
|
|
||||||
"""
|
|
||||||
self._destroyed[sender] = True
|
|
||||||
dbgout = ' / '.join(['{}: {}'.format(k.__class__.__name__, v)
|
|
||||||
for (k, v) in self._destroyed.items()])
|
|
||||||
log.destroy.debug("{} has been destroyed, new status: {}".format(
|
|
||||||
sender.__class__.__name__, dbgout))
|
|
||||||
if all(self._destroyed.values()):
|
|
||||||
if self._shutdown_callback is not None:
|
|
||||||
log.destroy.debug("Everything destroyed, calling callback")
|
|
||||||
self._shutdown_callback()
|
|
||||||
|
|
||||||
def _mousepress_backforward(self, e):
|
def _mousepress_backforward(self, e):
|
||||||
"""Handle back/forward mouse button presses.
|
"""Handle back/forward mouse button presses.
|
||||||
|
|
||||||
@ -357,40 +336,6 @@ class WebView(QWebView):
|
|||||||
else:
|
else:
|
||||||
raise CommandError("At end of history.")
|
raise CommandError("At end of history.")
|
||||||
|
|
||||||
def shutdown(self, callback=None):
|
|
||||||
"""Shut down the tab cleanly and remove it.
|
|
||||||
|
|
||||||
Inspired by [1].
|
|
||||||
|
|
||||||
[1] https://github.com/integricho/path-of-a-pyqter/tree/master/qttut08
|
|
||||||
|
|
||||||
Args:
|
|
||||||
callback: Function to call after shutting down.
|
|
||||||
"""
|
|
||||||
self._shutdown_callback = callback
|
|
||||||
# Avoid loading finished signal when stopping
|
|
||||||
try:
|
|
||||||
self.loadFinished.disconnect()
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
self.page().mainFrame().loadFinished.disconnect()
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
self.stop()
|
|
||||||
self.close()
|
|
||||||
self.settings().setAttribute(QWebSettings.JavascriptEnabled, False)
|
|
||||||
|
|
||||||
self._destroyed[self.page()] = False
|
|
||||||
self.page().destroyed.connect(functools.partial(self._on_destroyed,
|
|
||||||
self.page()))
|
|
||||||
self.page().shutdown()
|
|
||||||
|
|
||||||
self._destroyed[self] = False
|
|
||||||
self.destroyed.connect(functools.partial(self._on_destroyed, self))
|
|
||||||
self.deleteLater()
|
|
||||||
log.destroy.debug("Tab shutdown scheduled")
|
|
||||||
|
|
||||||
@pyqtSlot('QUrl')
|
@pyqtSlot('QUrl')
|
||||||
def on_url_changed(self, url):
|
def on_url_changed(self, url):
|
||||||
"""Update url_text when URL has changed."""
|
"""Update url_text when URL has changed."""
|
||||||
|
Loading…
Reference in New Issue
Block a user