diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 6da68cf54..803418403 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -20,6 +20,7 @@ |<>|Default encoding to use for websites. |<>|How to open links in an existing instance if a new one is launched. |<>|Whether to log javascript console messages. +|<>|Whether to always save the open pages. |============== .Quick reference for section ``ui'' @@ -386,6 +387,17 @@ Valid values: Default: +pass:[false]+ +[[general-save-session]] +=== save-session +Whether to always save the open pages. + +Valid values: + + * +true+ + * +false+ + +Default: +pass:[false]+ + == ui General options related to the user interface. diff --git a/qutebrowser/app.py b/qutebrowser/app.py index a8ec65edf..ae05db5c4 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -430,7 +430,7 @@ class Application(QApplication): def _connect_signals(self): """Connect all signals to their slots.""" config_obj = objreg.get('config') - self.lastWindowClosed.connect(self.shutdown) + self.lastWindowClosed.connect(self.on_last_window_closed) config_obj.style_changed.connect(style.get_stylesheet.cache_clear) self.focusChanged.connect(self.on_focus_changed) @@ -589,7 +589,7 @@ class Application(QApplication): log.destroy.exception("Error while ignoring ipc") try: - self.lastWindowClosed.disconnect(self.shutdown) + self.lastWindowClosed.disconnect(self.on_last_window_closed) except TypeError: log.destroy.exception("Error while preventing shutdown") QApplication.closeAllWindows() @@ -605,11 +605,6 @@ class Application(QApplication): self._destroy_crashlogfile() sys.exit(1) - @cmdutils.register(instance='app', name=['quit', 'q']) - def quit(self): - """Quit qutebrowser.""" - QApplication.closeAllWindows() - def _get_restart_args(self, pages): """Get the current working directory and args to relaunch qutebrowser. @@ -742,20 +737,41 @@ class Application(QApplication): log.destroy.info("WHY ARE YOU DOING THIS TO ME? :(") sys.exit(128 + signum) - @pyqtSlot() - def shutdown(self, status=0): - """Try to shutdown everything cleanly. + @cmdutils.register(instance='app', name='wq', + completion=[usertypes.Completion.sessions]) + def save_and_quit(self, name='default'): + """Save open pages and quit. - For some reason lastWindowClosing sometimes seem to get emitted twice, - so we make sure we only run once here. + Args: + name: The name of the session. + """ + self.shutdown(session=name) + + @pyqtSlot() + def on_last_window_closed(self): + """Slot which gets invoked when the last window was closed.""" + self.shutdown(last_window=True) + + @cmdutils.register(instance='app', name=['quit', 'q'], ignore_args=True) + def shutdown(self, status=0, session=None, last_window=False): + """Quit qutebrowser. Args: status: The status code to exit with. + session: A session name if saving should be forced. + last_window: If the shutdown was triggered due to the last window + closing. """ if self._shutting_down: return self._shutting_down = True - log.destroy.debug("Shutting down with status {}...".format(status)) + log.destroy.debug("Shutting down with status {}, session {}..." + .format(status, session)) + session_manager = objreg.get('session-manager') + if session is not None: + session_manager.save(session, last_window=last_window) + elif config.get('general', 'save-session'): + session_manager.save('default', last_window=last_window) deferrer = False for win_id in objreg.window_registry: prompter = objreg.get('prompter', None, scope='window', diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 4befbc03c..546cb0db9 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -193,6 +193,10 @@ DATA = collections.OrderedDict([ ('log-javascript-console', SettingValue(typ.Bool(), 'false'), "Whether to log javascript console messages."), + + ('save-session', + SettingValue(typ.Bool(), 'false'), + "Whether to always save the open pages."), )), ('ui', sect.KeyValue( diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index d647696af..09ac7ebd7 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -364,6 +364,8 @@ class MainWindow(QWidget): e.ignore() return e.accept() + if len(objreg.window_registry) == 1: + objreg.get('session-manager').save_last_window_session() objreg.get('app').geometry = bytes(self.saveGeometry()) log.destroy.debug("Closing window {}".format(self.win_id)) self._tabbed_browser.shutdown() diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py index 5738cf864..3481a8dc7 100644 --- a/qutebrowser/misc/sessions.py +++ b/qutebrowser/misc/sessions.py @@ -53,6 +53,8 @@ class SessionManager(QObject): Attributes: _base_path: The path to store sessions under. + _last_window_session: The session data of the last window which was + closed. Signals: update_completion: Emitted when the session completion should get @@ -65,6 +67,7 @@ class SessionManager(QObject): super().__init__(parent) self._base_path = os.path.join( standarddir.get(QStandardPaths.DataLocation), 'sessions') + self._last_window_session = None if not os.path.exists(self._base_path): os.mkdir(self._base_path) @@ -153,12 +156,21 @@ class SessionManager(QObject): data['windows'].append(win_data) return data - def save(self, name): - """Save a named session.""" + def save(self, name, last_window=False): + """Save a named session. + + Args: + last_window: If set, saves the saved self._last_window_session + instead of the currently open state. + """ path = self._get_session_path(name) log.misc.debug("Saving session {} to {}...".format(name, path)) - data = self._save_all() + if last_window: + data = self._last_window_session + assert data is not None + else: + data = self._save_all() log.misc.vdebug("Saving data: {}".format(data)) try: with qtutils.savefile_open(path) as f: @@ -169,6 +181,10 @@ class SessionManager(QObject): else: self.update_completion.emit() + def save_last_window_session(self): + """Temporarily save the session for the last closed window.""" + self._last_window_session = self._save_all() + def _load_tab(self, new_tab, data): """Load yaml data into a newly opened tab.""" entries = [] @@ -268,17 +284,6 @@ class SessionManager(QObject): raise cmdexc.CommandError("Error while saving session: {}" .format(e)) - @cmdutils.register(name='wq', completion=[usertypes.Completion.sessions], - instance='session-manager') - def save_and_quit(self, name='default'): - """Save open pages and quit. - - Args: - name: The name of the session. - """ - self.session_save(name) - QApplication.closeAllWindows() - @cmdutils.register(completion=[usertypes.Completion.sessions], instance='session-manager') def session_delete(self, name):