When using rapid hints in number mode e.g. on https://github.com/The-Compiler/qutebrowser/issues and filtering by text until only one hint matches (e.g. by typing pull so pulse doesn't match anymore), we get this on both master and v0.8.x:
06:47:05 DEBUG commands command:run:523 command called: hint ['--rapid', 'links', 'tab-bg']
06:47:05 DEBUG commands command:run:538 Calling qutebrowser.browser.hints.HintManager.start(<qutebrowser.browser.hints.HintManager object at 0x7f619c055438>, True, <Group.links: 2>, <Target.tab_bg: 5>, win_id=0, mode=None)
06:47:05 DEBUG hints hints:_start_cb:575 hints: 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
06:47:05 DEBUG message message:set_text:221 Follow hint in background tab (rapid mode)...
06:47:05 DEBUG statusbar text:set_text:55 Setting normal text to 'Follow hint in background tab (rapid mode)...'.
06:47:05 DEBUG modes modeman:enter:237 Entering mode KeyMode.hint (reason: HintManager.start)
06:47:05 DEBUG modes modeman:_eventFilter_keypress:191 handled: True, forward-unbound-keys: auto, passthrough: False, is_non_alnum: False --> filter: True (focused: <qutebrowser.browser.webkit.webview.WebView tab_id=0 url='https://github.com/The-Compiler/qutebrowser/issues'>)
06:47:05 DEBUG modes modeman:_eventFilter_keyrelease:211 filter: True
06:47:06 DEBUG modes modeman:_eventFilter_keypress:166 got keypress in mode KeyMode.hint - delegating to <qutebrowser.keyinput.modeparsers.HintKeyParser supports_chains=True supports_count=False>
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Got key: 0x50 / text: 'p'
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Giving up with 'p', no matches
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 discarding keystring 'p'.
06:47:06 DEBUG hints hints:handle_partial_key:745 Handling new keystring: ''
06:47:06 DEBUG keyboard modeparsers:_handle_special_key:168 Got special key 0x50 text p
06:47:06 DEBUG modes modeman:_eventFilter_keypress:191 handled: True, forward-unbound-keys: auto, passthrough: False, is_non_alnum: False --> filter: True (focused: <qutebrowser.browser.webkit.webview.WebView tab_id=0 url='https://github.com/The-Compiler/qutebrowser/issues'>)
06:47:06 DEBUG modes modeman:_eventFilter_keyrelease:211 filter: True
06:47:06 DEBUG modes modeman:_eventFilter_keypress:166 got keypress in mode KeyMode.hint - delegating to <qutebrowser.keyinput.modeparsers.HintKeyParser supports_chains=True supports_count=False>
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Got key: 0x55 / text: 'u'
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Giving up with 'u', no matches
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 discarding keystring 'u'.
06:47:06 DEBUG hints hints:handle_partial_key:745 Handling new keystring: ''
06:47:06 DEBUG keyboard modeparsers:_handle_special_key:168 Got special key 0x55 text u
06:47:06 DEBUG modes modeman:_eventFilter_keypress:191 handled: True, forward-unbound-keys: auto, passthrough: False, is_non_alnum: False --> filter: True (focused: <qutebrowser.browser.webkit.webview.WebView tab_id=0 url='https://github.com/The-Compiler/qutebrowser/issues'>)
06:47:06 DEBUG modes modeman:_eventFilter_keyrelease:211 filter: True
06:47:06 DEBUG modes modeman:_eventFilter_keypress:166 got keypress in mode KeyMode.hint - delegating to <qutebrowser.keyinput.modeparsers.HintKeyParser supports_chains=True supports_count=False>
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Got key: 0x4c / text: 'l'
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Giving up with 'l', no matches
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 discarding keystring 'l'.
06:47:06 DEBUG hints hints:handle_partial_key:745 Handling new keystring: ''
06:47:06 DEBUG keyboard modeparsers:_handle_special_key:168 Got special key 0x4c text l
06:47:06 DEBUG modes modeman:_eventFilter_keypress:191 handled: True, forward-unbound-keys: auto, passthrough: False, is_non_alnum: False --> filter: True (focused: <qutebrowser.browser.webkit.webview.WebView tab_id=0 url='https://github.com/The-Compiler/qutebrowser/issues'>)
06:47:06 DEBUG modes modeman:_eventFilter_keyrelease:211 filter: True
06:47:06 DEBUG modes modeman:_eventFilter_keypress:166 got keypress in mode KeyMode.hint - delegating to <qutebrowser.keyinput.modeparsers.HintKeyParser supports_chains=True supports_count=False>
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Got key: 0x4c / text: 'l'
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 Giving up with 'l', no matches
06:47:06 DEBUG keyboard basekeyparser:_debug_log:112 discarding keystring 'l'.
06:47:06 DEBUG hints hints:handle_partial_key:745 Handling new keystring: ''
06:47:06 DEBUG keyboard modeparsers:_handle_special_key:168 Got special key 0x4c text l
06:47:07 ERROR misc crashsignal:exception_hook:211 Uncaught exception
Traceback (most recent call last):
File "/home/florian/proj/qutebrowser/git/qutebrowser/app.py", line 864, in eventFilter
return handler(event)
File "/home/florian/proj/qutebrowser/git/qutebrowser/app.py", line 824, in _handle_key_event
return man.eventFilter(event)
File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeman.py", line 326, in eventFilter
return self._eventFilter_keypress(event)
File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeman.py", line 167, in _eventFilter_keypress
handled = parser.handle(event)
File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeparsers.py", line 222, in handle
return self._handle_special_key(e)
File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeparsers.py", line 197, in _handle_special_key
hintmanager.filter_hints(self._filtertext)
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/hints.py", line 814, in filter_hints
visible=self._context.labels)
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/hints.py", line 741, in _handle_auto_follow
self._fire(*visible)
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/hints.py", line 867, in _fire
self.filter_hints(None)
# [...]
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/hints.py", line 867, in _fire
self.filter_hints(None)
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/hints.py", line 781, in filter_hints
if self._filter_matches(filterstr, str(label.elem)):
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/webelem.py", line 90, in __str__
return self.text()
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/webkit/webkitelem.py", line 121, in text
if self.is_content_editable() or not use_js:
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/webelem.py", line 200, in is_content_editable
return self['contenteditable'].lower() not in ['false', 'inherit']
File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/webkit/webkitelem.py", line 56, in __getitem__
if key not in self:
RecursionError: maximum recursion depth exceeded
Reports:
Are you currently working on that? I've looked into this and basically when HintManager wants to clear hints after rapid number-mode fires, it calls filter_hints(None). Unfortunately filter_hints on None uses arg from previous call which is obviously a match. So _fire calls filter_hints, which calls _fire... until the RecursionError pops out. So you can do something like:
self._context.filterstr = "" # or None, not sure which looks better
self.filter_hints(None)
But then there's another issue - HintKeyParser keeps its own filtertext variable, which holds user hint keystrokes and it doesn't reset after firing with rapid number-mode. So if you want to follow projects it follows on proj and reset labels but not the filtertext, so if you now press e it fires projects again, if you press anything else, it exits rapid (since there's no projx on page, for example).
So with this dirty solution it does work, but I'm not sure how to make it less hackish:
# HintManager._fire, something around line 876
self._context.filterstr = ""
self.filter_hints(None)
keyparsers = objreg.get('keyparsers', scope='window',
window=self._win_id)
keyparsers[usertypes.KeyMode.hint]._filtertext = ''
I hope it helps somehow!
Thanks for the investigation, that definitely helps! I haven't had time to take a closer look at this yet, and I'll probably only do after v0.9.0 is released.
Most helpful comment
Are you currently working on that? I've looked into this and basically when
HintManagerwants to clear hints after rapid number-mode fires, it callsfilter_hints(None). Unfortunatelyfilter_hintsonNoneuses arg from previous call which is obviously a match. So_firecallsfilter_hints, which calls_fire... until theRecursionErrorpops out. So you can do something like:But then there's another issue -
HintKeyParserkeeps its ownfiltertextvariable, which holds user hint keystrokes and it doesn't reset after firing with rapid number-mode. So if you want to followprojectsit follows on proj and reset labels but not thefiltertext, so if you now presseit fires projects again, if you press anything else, it exits rapid (since there's noprojxon page, for example).So with this dirty solution it does work, but I'm not sure how to make it less hackish:
I hope it helps somehow!