From a76868c0f4a189e2a2b53a9acbaa6ccc272e55a6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 26 Feb 2015 20:41:04 +0100 Subject: [PATCH] Refactor how click/hint open targets are handled. --- qutebrowser/browser/hints.py | 10 ++++++--- qutebrowser/browser/webpage.py | 35 ++++++++++++++++++++++++++----- qutebrowser/browser/webview.py | 38 ++++++++-------------------------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 7f2045ca7..dd6adbfa3 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -110,7 +110,9 @@ class HintManager(QObject): Signals: mouse_event: Mouse event to be posted in the web view. arg: A QMouseEvent - set_open_target: Set a new target to open the links in. + start_hinting: Emitted when hinting starts, before a link is clicked. + arg: The hinting target name. + stop_hinting: Emitted after a link was clicked. """ HINT_TEXTS = { @@ -131,7 +133,8 @@ class HintManager(QObject): } mouse_event = pyqtSignal('QMouseEvent') - set_open_target = pyqtSignal(str) + start_hinting = pyqtSignal(str) + stop_hinting = pyqtSignal() def __init__(self, win_id, tab_id, parent=None): """Constructor.""" @@ -386,6 +389,7 @@ class HintManager(QObject): action = "Hovering" if target == Target.hover else "Clicking" log.hints.debug("{} on '{}' at {}/{}".format( action, elem, pos.x(), pos.y())) + self.start_hinting.emit(target.name) if target in (Target.tab, Target.tab_bg, Target.window): modifiers = Qt.ControlModifier else: @@ -395,7 +399,6 @@ class HintManager(QObject): Qt.NoModifier), ] if target != Target.hover: - self.set_open_target.emit(target.name) events += [ QMouseEvent(QEvent.MouseButtonPress, pos, Qt.LeftButton, Qt.LeftButton, modifiers), @@ -408,6 +411,7 @@ class HintManager(QObject): QTimer.singleShot(0, functools.partial( elem.webFrame().page().triggerAction, QWebPage.MoveToEndOfDocument)) + QTimer.singleShot(0, self.stop_hinting.emit) def _yank(self, url, context): """Yank an element to the clipboard or primary selection. diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index c75b6ad1a..76cbb537d 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -42,6 +42,9 @@ class BrowserPage(QWebPage): Attributes: error_occured: Whether an error occured while loading. + open_target: Where to open the next navigation request. + ("normal", "tab", "tab_bg") + _hint_target: Override for open_target while hinting, or None. _extension_handlers: Mapping of QWebPage extensions to their handlers. _networkmnager: The NetworkManager used. _win_id: The window ID this BrowserPage is associated with. @@ -64,6 +67,8 @@ class BrowserPage(QWebPage): } self._ignore_load_started = False self.error_occured = False + self.open_target = usertypes.ClickTarget.normal + self._hint_target = None self._networkmanager = networkmanager.NetworkManager( win_id, tab_id, self) self.setNetworkAccessManager(self._networkmanager) @@ -405,6 +410,24 @@ class BrowserPage(QWebPage): if 'scroll-pos' in data and frame.scrollPosition() == QPoint(0, 0): frame.setScrollPosition(data['scroll-pos']) + @pyqtSlot(str) + def on_start_hinting(self, hint_target): + """Emitted before a hinting-click takes place. + + Args: + hint_target: A string to set self._hint_target to. + """ + t = getattr(usertypes.ClickTarget, hint_target) + log.webview.debug("Setting force target to {}/{}".format( + hint_target, t)) + self._hint_target = t + + @pyqtSlot() + def on_stop_hinting(self): + """Emitted when hinting is finished.""" + log.webview.debug("Finishing hinting.") + self._hint_target = None + def userAgentForUrl(self, url): """Override QWebPage::userAgentForUrl to customize the user agent.""" ua = config.get('network', 'user-agent') @@ -513,15 +536,17 @@ class BrowserPage(QWebPage): return False tabbed_browser = objreg.get('tabbed-browser', scope='window', window=self._win_id) - open_target = self.view().open_target - self.view().open_target = usertypes.ClickTarget.normal - if open_target == usertypes.ClickTarget.tab: + if self._hint_target is not None: + target = self._hint_target + else: + target = self.open_target + if target == usertypes.ClickTarget.tab: tabbed_browser.tabopen(url, False) return False - elif open_target == usertypes.ClickTarget.tab_bg: + elif target == usertypes.ClickTarget.tab_bg: tabbed_browser.tabopen(url, True) return False - elif open_target == usertypes.ClickTarget.window: + elif target == usertypes.ClickTarget.window: from qutebrowser.mainwindow import mainwindow window = mainwindow.MainWindow() window.show() diff --git a/qutebrowser/browser/webview.py b/qutebrowser/browser/webview.py index 3df8546fe..13b2cbb9b 100644 --- a/qutebrowser/browser/webview.py +++ b/qutebrowser/browser/webview.py @@ -55,7 +55,6 @@ class WebView(QWebView): statusbar_message: The current javscript statusbar message. inspector: The QWebInspector used for this webview. load_status: loading status of this page (index into LoadStatus) - open_target: Where to open the next tab ("normal", "tab", "tab_bg") viewing_source: Whether the webview is currently displaying source code. keep_icon: Whether the (e.g. cloned) icon should not be cleared on page @@ -66,7 +65,6 @@ class WebView(QWebView): _has_ssl_errors: Whether SSL errors occured during loading. _zoom: A NeighborList with the zoom levels. _old_scroll_pos: The old scroll position. - _force_open_target: Override for open_target. _check_insertmode: If True, in mouseReleaseEvent we should check if we need to enter/leave insert mode. _default_zoom_changed: Whether the zoom was changed from the default. @@ -101,8 +99,6 @@ class WebView(QWebView): self.scroll_pos = (-1, -1) self.statusbar_message = '' self._old_scroll_pos = (-1, -1) - self.open_target = usertypes.ClickTarget.normal - self._force_open_target = None self._zoom = None self._has_ssl_errors = False self.keep_icon = False @@ -127,7 +123,8 @@ class WebView(QWebView): self.setPage(page) hintmanager = hints.HintManager(win_id, self.tab_id, self) hintmanager.mouse_event.connect(self.on_mouse_event) - hintmanager.set_open_target.connect(self.set_force_open_target) + hintmanager.start_hinting.connect(page.on_start_hinting) + hintmanager.stop_hinting.connect(page.on_stop_hinting) objreg.register('hintmanager', hintmanager, registry=self.registry) mode_manager = objreg.get('mode-manager', scope='window', window=win_id) @@ -283,24 +280,18 @@ class WebView(QWebView): Args: e: The QMouseEvent. """ - if self._force_open_target is not None: - self.open_target = self._force_open_target - self._force_open_target = None - log.mouse.debug("Setting force target: {}".format( - self.open_target)) - elif (e.button() == Qt.MidButton or - e.modifiers() & Qt.ControlModifier): + if e.button() == Qt.MidButton or e.modifiers() & Qt.ControlModifier: background_tabs = config.get('tabs', 'background-tabs') if e.modifiers() & Qt.ShiftModifier: background_tabs = not background_tabs if background_tabs: - self.open_target = usertypes.ClickTarget.tab_bg + target = usertypes.ClickTarget.tab_bg else: - self.open_target = usertypes.ClickTarget.tab - log.mouse.debug("Middle click, setting target: {}".format( - self.open_target)) + target = usertypes.ClickTarget.tab + self.page().open_target = target + log.mouse.debug("Middle click, setting target: {}".format(target)) else: - self.open_target = usertypes.ClickTarget.normal + self.page().open_target = usertypes.ClickTarget.normal log.mouse.debug("Normal click, setting normal target") def shutdown(self): @@ -438,17 +429,6 @@ class WebView(QWebView): "left.".format(mode)) self.setFocusPolicy(Qt.WheelFocus) - @pyqtSlot(str) - def set_force_open_target(self, target): - """Change the forced link target. Setter for _force_open_target. - - Args: - target: A string to set self._force_open_target to. - """ - t = getattr(usertypes.ClickTarget, target) - log.webview.debug("Setting force target to {}/{}".format(target, t)) - self._force_open_target = t - def createWindow(self, wintype): """Called by Qt when a page wants to create a new window. @@ -507,7 +487,7 @@ class WebView(QWebView): This does the following things: - Check if a link was clicked with the middle button or Ctrl and - set the open_target attribute accordingly. + set the page's open_target attribute accordingly. - Emit the editable_elem_selected signal if an editable element was clicked.