From 16c2268d092c4cd2977ded6e9fe8f7dd027557e0 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 9 Aug 2016 20:18:43 +0200 Subject: [PATCH 1/5] Fix last-focused-main-window's behavior Right now, get('last-focused-main-window') essentially returns the same as qApp.activeWindow(), since it's None when no window is focused. This seems somewhat contrary to its original intent, so I've changed it to only ever update the object. This actually fixes another bug as well: on_focus_changed's new is not always a MainWindow - in fact it's a WebView on my end. To fix this, directly use the QApplication.activeWindow() to find the current focus. That second bit in particular actually some related bugs that probably nobody ever noticed or bothered reporting: * _maybe_hide_mouse_cursor currently pretty much never gets called * :adblock-update doesn't actually show any downloads * ... probably more --- qutebrowser/app.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 295fca1fe..cdcbff460 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -342,16 +342,13 @@ def on_focus_changed(_old, new): if not isinstance(new, QWidget) and new is not None: log.misc.debug("on_focus_changed called with non-QWidget {!r}".format( new)) + return - if new is None or not isinstance(new, mainwindow.MainWindow): - try: - objreg.delete('last-focused-main-window') - except KeyError: - pass - qApp.restoreOverrideCursor() - else: - objreg.register('last-focused-main-window', new.window(), update=True) + if new is not None: _maybe_hide_mouse_cursor() + objreg.register('last-focused-main-window', new.window(), update=True) + else: + qApp.restoreOverrideCursor() def open_desktopservices_url(url): From 2223a285ef4a49adabe735d558db9ab7b65ff78a Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 9 Aug 2016 22:40:30 +0200 Subject: [PATCH 2/5] Remove ui -> hide-mouse-cursor setting This was currently almost completely broken, yet nobody complained. The new behavior (in the previous commit) makes this always hide the mouse cursor, even when an input field has focus. Since the only two easy options to implement are "never hide" and "always hide", combined with the fact that both are sort of useless to an end-user, just remove the option until somebody wants it back. --- CHANGELOG.asciidoc | 2 ++ qutebrowser/app.py | 30 +++++++++------------------- qutebrowser/config/config.py | 1 + qutebrowser/config/configdata.py | 4 ---- qutebrowser/mainwindow/mainwindow.py | 3 --- 5 files changed, 12 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 1cdc19113..c8dafa97b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -63,6 +63,8 @@ Removed and thus removed. - The `:completion-item-prev` and `:completion-item-next` commands got merged into a new `:completion-focus {prev,next}` command and thus removed. +- The `ui -> hide-mouse-cursor` setting since it was completely broken and + nobody seemed to care. v0.8.3 (unreleased) ------------------- diff --git a/qutebrowser/app.py b/qutebrowser/app.py index cdcbff460..a25e3a4bb 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -33,9 +33,9 @@ import tokenize from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtWebKit import QWebSettings -from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QCursor, QWindow +from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QWindow from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QTimer, QUrl, - QObject, Qt, QEvent, pyqtSignal) + QObject, QEvent, pyqtSignal) try: import hunter except ImportError: @@ -339,16 +339,17 @@ def _save_version(): def on_focus_changed(_old, new): """Register currently focused main window in the object registry.""" - if not isinstance(new, QWidget) and new is not None: + if new is None: + return + + if not isinstance(new, QWidget): log.misc.debug("on_focus_changed called with non-QWidget {!r}".format( new)) return - if new is not None: - _maybe_hide_mouse_cursor() - objreg.register('last-focused-main-window', new.window(), update=True) - else: - qApp.restoreOverrideCursor() + window = new.window() + if isinstance(window, mainwindow.MainWindow): + objreg.register('last-focused-main-window', window, update=True) def open_desktopservices_url(url): @@ -359,17 +360,6 @@ def open_desktopservices_url(url): tabbed_browser.tabopen(url) -@config.change_filter('ui', 'hide-mouse-cursor', function=True) -def _maybe_hide_mouse_cursor(): - """Hide the mouse cursor if it isn't yet and it's configured.""" - if config.get('ui', 'hide-mouse-cursor'): - if qApp.overrideCursor() is not None: - return - qApp.setOverrideCursor(QCursor(Qt.BlankCursor)) - else: - qApp.restoreOverrideCursor() - - def _init_modules(args, crash_handler): """Initialize all 'modules' which need to be initialized. @@ -431,8 +421,6 @@ def _init_modules(args, crash_handler): os.environ['QT_WAYLAND_DISABLE_WINDOWDECORATION'] = '1' else: os.environ.pop('QT_WAYLAND_DISABLE_WINDOWDECORATION', None) - _maybe_hide_mouse_cursor() - objreg.get('config').changed.connect(_maybe_hide_mouse_cursor) temp_downloads = downloads.TempDownloadManager(qApp) objreg.register('temporary-downloads', temp_downloads) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index a5521e275..412fdc68f 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -350,6 +350,7 @@ class ConfigManager(QObject): ('tabs', 'auto-hide'), ('tabs', 'hide-always'), ('ui', 'display-statusbar-messages'), + ('ui', 'hide-mouse-cursor'), ('general', 'wrap-search'), ] CHANGED_OPTIONS = { diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 6837ed70a..11ebe5415 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -346,10 +346,6 @@ def data(readonly=False): "* `{scroll_pos}`: The page scroll position.\n" "* `{host}`: The host of the current web page."), - ('hide-mouse-cursor', - SettingValue(typ.Bool(), 'false'), - "Whether to hide the mouse cursor."), - ('modal-js-dialog', SettingValue(typ.Bool(), 'false'), "Use standard JavaScript modal dialog for alert() and confirm()"), diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index 8198ba8cd..b44a5b782 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -175,9 +175,6 @@ class MainWindow(QWidget): QTimer.singleShot(0, self._connect_resize_keyhint) objreg.get('config').changed.connect(self.on_config_changed) - if config.get('ui', 'hide-mouse-cursor'): - self.setCursor(Qt.BlankCursor) - objreg.get("app").new_window.emit(self) def _init_downloadmanager(self): From 6d181e5c6f918d6fcb1f1e48ffc8ec3b5def3c2a Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 9 Aug 2016 20:23:56 +0200 Subject: [PATCH 3/5] Add new-instance-open-target.window setting This adds the ability to open new tabs in the last-focused window instead, which fixes #1801. Right now the only other option is probably not that useful for human users but it's required to make tests behave deterministically and consistently. (But with #881 on the roadmap, I would implement this as another choice) To this end, also make the test framework set this option to preserve the invariant against which existing tests are written: that spawning a new window would effectively also focus it. --- qutebrowser/config/configdata.py | 10 ++++++++++ qutebrowser/mainwindow/mainwindow.py | 6 +++++- qutebrowser/utils/objreg.py | 13 +++++++++---- tests/end2end/fixtures/quteprocess.py | 1 + 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 11ebe5415..8d003a182 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -227,6 +227,16 @@ def data(readonly=False): "How to open links in an existing instance if a new one is " "launched."), + ('new-instance-open-target.window', + SettingValue(typ.String( + valid_values=typ.ValidValues( + ('last-opened', "Open new tabs in the last" + "opened window."), + ('last-focused', "Open new tabs in the most" + "recently focused window.") + )), 'last-focused'), + "Which window to choose when opening links as new tabs."), + ('log-javascript-console', SettingValue(typ.String( valid_values=typ.ValidValues( diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index b44a5b782..a53c4f702 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -69,7 +69,11 @@ def get_window(via_ipc, force_window=False, force_tab=False, window_to_raise = window else: try: - window = objreg.last_window() + win_mode = config.get('general', 'new-instance-open-target.window') + if win_mode == 'last-focused': + window = objreg.last_focused_window() + elif win_mode == 'last-opened': + window = objreg.last_window() except objreg.NoWindow: # There is no window left, so we open a new one window = MainWindow() diff --git a/qutebrowser/utils/objreg.py b/qutebrowser/utils/objreg.py index 0dc6ec68c..d347b7756 100644 --- a/qutebrowser/utils/objreg.py +++ b/qutebrowser/utils/objreg.py @@ -178,10 +178,7 @@ def _get_window_registry(window): app = get('app') win = app.activeWindow() elif window == 'last-focused': - try: - win = get('last-focused-main-window') - except KeyError: - win = last_window() + win = last_focused_window() else: win = window_registry[window] except (KeyError, NoWindow): @@ -276,6 +273,14 @@ def dump_objects(): return lines +def last_focused_window(): + """Get the last focused window, or the last window if none.""" + try: + return get('last-focused-main-window') + except KeyError: + return last_window() + + def last_window(): """Get the last opened window object.""" if not window_registry: diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py index 493b3fb6c..b379b42a5 100644 --- a/tests/end2end/fixtures/quteprocess.py +++ b/tests/end2end/fixtures/quteprocess.py @@ -330,6 +330,7 @@ class QuteProc(testprocess.Process): settings = [ ('ui', 'message-timeout', '0'), ('general', 'auto-save-interval', '0'), + ('general', 'new-instance-open-target.window', 'last-opened') ] if not self._webengine: settings.append(('network', 'ssl-strict', 'false')) From 153b9db8c2c22d13726af0df66be125c03a70c7d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 10 Aug 2016 09:11:26 +0200 Subject: [PATCH 4/5] Fix new-instance-open-target.window valid_values --- qutebrowser/config/configdata.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 8d003a182..7ed51142c 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -230,10 +230,10 @@ def data(readonly=False): ('new-instance-open-target.window', SettingValue(typ.String( valid_values=typ.ValidValues( - ('last-opened', "Open new tabs in the last" - "opened window."), - ('last-focused', "Open new tabs in the most" - "recently focused window.") + ('last-opened', "Open new tabs in the last opened " + "window."), + ('last-focused', "Open new tabs in the most recently " + "focused window.") )), 'last-focused'), "Which window to choose when opening links as new tabs."), From 4576fd9840d87b1ddcbb8d24006d9cd03b210267 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 10 Aug 2016 09:13:35 +0200 Subject: [PATCH 5/5] Update docs --- CHANGELOG.asciidoc | 3 +++ README.asciidoc | 2 +- doc/help/settings.asciidoc | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index c8dafa97b..c22ede6eb 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -55,6 +55,9 @@ Changed title is changed via javascript. - `:hint` now has a `--mode ` flag to override the hint mode configured using the `hints -> mode` setting. +- With `new-instance-open-target` set to a tab option, the tab is now opened in + the most recently focused (instead of the last opened) window. This can be + configured with the new `new-instance-open-target.window` setting. Removed ~~~~~~~ diff --git a/README.asciidoc b/README.asciidoc index f8bbc1404..65bd44d6f 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -177,6 +177,7 @@ Contributors, sorted by the number of commits in descending order: * Oliver Caldwell * Jonas Schürmann * error800 +* Niklas Haas * Liam BEGUIN * skinnay * Zach-Button @@ -202,7 +203,6 @@ Contributors, sorted by the number of commits in descending order: * Samuel Loury * Peter Michely * Panashe M. Fundira -* Niklas Haas * Link * Larry Hynes * Johannes Altmanninger diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 7670057fb..2f680d3c8 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -23,6 +23,7 @@ |<>|Enable workarounds for broken sites. |<>|Default encoding to use for websites. |<>|How to open links in an existing instance if a new one is launched. +|<>|Which window to choose when opening links as new tabs. |<>|How to log javascript console messages. |<>|Whether to always save the open pages. |<>|The name of the session to save by default, or empty for the last loaded session. @@ -49,7 +50,6 @@ |<>|Whether to hide the statusbar unless a message is shown. |<>|Padding for statusbar (top, bottom, left, right). |<>|The format to use for the window title. The following placeholders are defined: -|<>|Whether to hide the mouse cursor. |<>|Use standard JavaScript modal dialog for alert() and confirm() |<>|Hide the window decoration when using wayland (requires restart) |<>|Keychains that shouldn't be shown in the keyhint dialog @@ -448,6 +448,17 @@ Valid values: Default: +pass:[tab]+ +[[general-new-instance-open-target.window]] +=== new-instance-open-target.window +Which window to choose when opening links as new tabs. + +Valid values: + + * +last-opened+: Open new tabs in the last opened window. + * +last-focused+: Open new tabs in the most recently focused window. + +Default: +pass:[last-focused]+ + [[general-log-javascript-console]] === log-javascript-console How to log javascript console messages. @@ -651,17 +662,6 @@ The format to use for the window title. The following placeholders are defined: Default: +pass:[{perc}{title}{title_sep}qutebrowser]+ -[[ui-hide-mouse-cursor]] -=== hide-mouse-cursor -Whether to hide the mouse cursor. - -Valid values: - - * +true+ - * +false+ - -Default: +pass:[false]+ - [[ui-modal-js-dialog]] === modal-js-dialog Use standard JavaScript modal dialog for alert() and confirm()