Add a hints -> find-implementation setting
This makes it possible to switch to an alternative implementation if there are weird issues like #1568. Some users might also prefer the slightly better performance over more accurate hints.
This commit is contained in:
parent
2d54c927e3
commit
035526848e
@ -35,6 +35,9 @@ Added
|
||||
- New `hints -> auto-follow-timeout` setting to ignore keypresses after
|
||||
following a hint when filtering in number mode.
|
||||
- New `:history-clear` command to clear the entire history
|
||||
- New `hints -> find-implementation` to select which implementation (JS/Python)
|
||||
should be used to find hints on a page. The `javascript` implementation is
|
||||
better, but slower.
|
||||
|
||||
Changed
|
||||
~~~~~~~
|
||||
|
@ -186,6 +186,7 @@
|
||||
|<<hints-auto-follow-timeout,auto-follow-timeout>>|A timeout to inhibit normal-mode key bindings after a successfulauto-follow.
|
||||
|<<hints-next-regexes,next-regexes>>|A comma-separated list of regexes to use for 'next' links.
|
||||
|<<hints-prev-regexes,prev-regexes>>|A comma-separated list of regexes to use for 'prev' links.
|
||||
|<<hints-find-implementation,find-implementation>>|Which implementation to use to find elements to hint.
|
||||
|==============
|
||||
|
||||
.Quick reference for section ``colors''
|
||||
@ -1637,6 +1638,17 @@ A comma-separated list of regexes to use for 'prev' links.
|
||||
|
||||
Default: +pass:[\bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,\b(<<|«)\b]+
|
||||
|
||||
[[hints-find-implementation]]
|
||||
=== find-implementation
|
||||
Which implementation to use to find elements to hint.
|
||||
|
||||
Valid values:
|
||||
|
||||
* +javascript+: Better but slower
|
||||
* +python+: Slightly worse but faster
|
||||
|
||||
Default: +pass:[javascript]+
|
||||
|
||||
== searchengines
|
||||
Definitions of search engines which can be used via the address bar.
|
||||
The searchengine named `DEFAULT` is used when `general -> auto-search` is true and something else than a URL was entered to be opened. Other search engines can be used by prepending the search engine name to the search term, e.g. `:open google qutebrowser`. The string `{}` will be replaced by the search term, use `{{` and `}}` for literal `{`/`}` signs.
|
||||
|
@ -381,11 +381,12 @@ class HintManager(QObject):
|
||||
elem: The QWebElement to set the style attributes for.
|
||||
label: The label QWebElement.
|
||||
"""
|
||||
rect = elem.rect_on_view(adjust_zoom=False)
|
||||
no_js = config.get('hints', 'find-implementation') != 'javascript'
|
||||
rect = elem.rect_on_view(adjust_zoom=False, no_js=no_js)
|
||||
left = rect.x()
|
||||
top = rect.y()
|
||||
log.hints.vdebug("Drawing label '{!r}' at {}/{} for element '{!r}'"
|
||||
.format(label, left, top, elem))
|
||||
log.hints.vdebug("Drawing label '{!r}' at {}/{} for element '{!r}' "
|
||||
"(no_js: {})".format(label, left, top, elem, no_js))
|
||||
label.setStyleProperty('left', '{}px !important'.format(left))
|
||||
label.setStyleProperty('top', '{}px !important'.format(top))
|
||||
|
||||
|
@ -173,14 +173,9 @@ class WebElementWrapper(collections.abc.MutableMapping):
|
||||
"""
|
||||
return is_visible(self._elem, mainframe)
|
||||
|
||||
def rect_on_view(self, *, adjust_zoom=True):
|
||||
"""Get the geometry of the element relative to the webview.
|
||||
|
||||
Args:
|
||||
adjust_zoom: Whether to adjust the element position based on the
|
||||
current zoom level.
|
||||
"""
|
||||
return rect_on_view(self._elem, adjust_zoom=adjust_zoom)
|
||||
def rect_on_view(self, **kwargs):
|
||||
"""Get the geometry of the element relative to the webview."""
|
||||
return rect_on_view(self._elem, **kwargs)
|
||||
|
||||
def is_writable(self):
|
||||
"""Check whether an element is writable."""
|
||||
@ -368,7 +363,7 @@ def focus_elem(frame):
|
||||
return WebElementWrapper(elem)
|
||||
|
||||
|
||||
def rect_on_view(elem, *, elem_geometry=None, adjust_zoom=True):
|
||||
def rect_on_view(elem, *, elem_geometry=None, adjust_zoom=True, no_js=False):
|
||||
"""Get the geometry of the element relative to the webview.
|
||||
|
||||
We need this as a standalone function (as opposed to a WebElementWrapper
|
||||
@ -391,13 +386,14 @@ def rect_on_view(elem, *, elem_geometry=None, adjust_zoom=True):
|
||||
want to avoid doing it twice.
|
||||
adjust_zoom: Whether to adjust the element position based on the
|
||||
current zoom level.
|
||||
no_js: Fall back to the Python implementation
|
||||
"""
|
||||
if elem.isNull():
|
||||
raise IsNullError("Got called on a null element!")
|
||||
|
||||
# First try getting the element rect via JS, as that's usually more
|
||||
# accurate
|
||||
if elem_geometry is None:
|
||||
if elem_geometry is None and not no_js:
|
||||
rects = elem.evaluateJavaScript("this.getClientRects()")
|
||||
text = utils.compact_text(elem.toOuterXml(), 500)
|
||||
log.hints.vdebug("Client rectangles of element '{}': {}".format(text,
|
||||
|
@ -930,6 +930,14 @@ def data(readonly=False):
|
||||
r'\b(<<|«)\b'),
|
||||
"A comma-separated list of regexes to use for 'prev' links."),
|
||||
|
||||
('find-implementation',
|
||||
SettingValue(typ.String(
|
||||
valid_values=typ.ValidValues(
|
||||
('javascript', "Better but slower"),
|
||||
('python', "Slightly worse but faster"),
|
||||
)), 'javascript'),
|
||||
"Which implementation to use to find elements to hint."),
|
||||
|
||||
readonly=readonly
|
||||
)),
|
||||
|
||||
|
@ -232,4 +232,3 @@ Feature: Using hints
|
||||
And I press the key "2"
|
||||
And I wait for "Leaving mode KeyMode.hint (reason: all filtered)" in the log
|
||||
Then no crash should happen
|
||||
|
||||
|
@ -38,7 +38,9 @@ def collect_tests():
|
||||
@pytest.mark.parametrize('test_name', collect_tests())
|
||||
@pytest.mark.parametrize('zoom_text_only', [True, False])
|
||||
@pytest.mark.parametrize('zoom_level', [100, 66, 33])
|
||||
def test_hints(test_name, zoom_text_only, zoom_level, quteproc):
|
||||
@pytest.mark.parametrize('find_implementation', ['javascript', 'python'])
|
||||
def test_hints(test_name, zoom_text_only, zoom_level, find_implementation,
|
||||
quteproc):
|
||||
file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||
'data', 'hints', 'html', test_name)
|
||||
url_path = 'data/hints/html/{}'.format(test_name)
|
||||
@ -69,6 +71,7 @@ def test_hints(test_name, zoom_text_only, zoom_level, quteproc):
|
||||
|
||||
# setup
|
||||
quteproc.send_cmd(':set ui zoom-text-only {}'.format(zoom_text_only))
|
||||
quteproc.set_setting('hints', 'find-implementation', find_implementation)
|
||||
quteproc.send_cmd(':zoom {}'.format(zoom_level))
|
||||
# follow hint
|
||||
quteproc.send_cmd(':hint links normal')
|
||||
|
14
tests/manual/hints/find_implementation.html
Normal file
14
tests/manual/hints/find_implementation.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Different hint implementations</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>When setting hints -> find-implementation to python, the label for the wrapped hint should be drawn at the wrong position.</p>
|
||||
<div style="width: 20em;">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis <a href="/data/hello.txt">nostrud exercitation</a> ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user