From a54693351666528c2f279be1c1a5e6ab9afd3b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Mon, 15 Feb 2016 15:48:56 +0100 Subject: [PATCH] hints: use getClientRects() JS method to get the correct click position --- qutebrowser/browser/hints.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index c9a722dc6..b38fc5c0c 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -26,7 +26,7 @@ import re import string from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl, - QTimer) + QTimer, QPoint) from PyQt5.QtGui import QMouseEvent from PyQt5.QtWebKit import QWebElement from PyQt5.QtWebKitWidgets import QWebPage @@ -438,14 +438,31 @@ class HintManager(QObject): target_mapping[Target.tab] = usertypes.ClickTarget.tab_bg else: target_mapping[Target.tab] = usertypes.ClickTarget.tab + + action = "Hovering" if context.target == Target.hover else "Clicking" + log.hints.debug("{} on element '{}'".format(action, elem.debug_text())) + # FIXME Instead of clicking the center, we could have nicer heuristics. # e.g. parse (-webkit-)border-radius correctly and click text fields at # the bottom right, and everything else on the top left or so. # https://github.com/The-Compiler/qutebrowser/issues/70 pos = elem.rect_on_view().center() - action = "Hovering" if context.target == Target.hover else "Clicking" - log.hints.debug("{} on '{}' at {}/{}".format( - action, elem, pos.x(), pos.y())) + log.hints.debug("Center position: {}".format(pos)) + boxes = elem.evaluateJavaScript("this.getClientRects()") + log.hints.debug("Bounding boxes: {}".format(boxes)) + for key in sorted(boxes): + box = boxes[key] + width = box.get("width", 0) + height = box.get("height", 0) + # skip boxes with zero dimensions (happens to if they contain + # other elements with display:block style) + # https://github.com/The-Compiler/qutebrowser/issues/1298 + if width > 0 and height > 0: + pos = QPoint(box["left"] + width / 2, box["top"] + height / 2) + log.hints.debug("Updated position: {}".format(pos)) + break + log.hints.debug("Final position is {}".format(pos)) + self.start_hinting.emit(target_mapping[context.target]) if context.target in [Target.tab, Target.tab_fg, Target.tab_bg, Target.window]: