From 695712e50c3871f00959b838909545ff12ae3d6b Mon Sep 17 00:00:00 2001 From: Artur Shaik Date: Thu, 9 Apr 2015 22:55:42 +0600 Subject: [PATCH 1/4] Basic caret and visual modes implementation Allow user switch in caret mode for browsing with caret, and visual mode for select and yank text with keyboard. Default keybindings is c or v for caret mode, and again v for visual mode. All basic movements provided by WebAction enum implemened with vim-like bindings. Yanking with y and Y for selection and clipboard respectively. There is bug/feature in WebKit that after caret enabled, caret doesn't show until mouse click (or sometimes Tab helps). So I add some workaround for that with mouse event. I think should be better aproach. Signed-off-by: Artur Shaik --- qutebrowser/browser/commands.py | 191 ++++++++++++++++++++++++ qutebrowser/browser/webview.py | 38 ++++- qutebrowser/config/configdata.py | 33 ++++ qutebrowser/keyinput/modeman.py | 5 + qutebrowser/keyinput/modeparsers.py | 24 +++ qutebrowser/mainwindow/tabbedbrowser.py | 3 +- qutebrowser/utils/usertypes.py | 2 +- 7 files changed, 293 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 7dc0a35fd..93488bd04 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -40,6 +40,7 @@ from qutebrowser.browser import webelem from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils, objreg, utils) from qutebrowser.misc import editor +from qutebrowser.keyinput import modeman class CommandDispatcher: @@ -1071,3 +1072,193 @@ class CommandDispatcher: elem.evaluateJavaScript("this.value='{}'".format(text)) except webelem.IsNullError: raise cmdexc.CommandError("Element vanished while editing!") + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_next_line(self): + """Move the cursor or select to the next line.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToNextLine + else: + act = QWebPage.SelectNextLine + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_prev_line(self): + """Move the cursor or select to the prev line.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToPreviousLine + else: + act = QWebPage.SelectPreviousLine + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_next_char(self): + """Move the cursor or select to the next char.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToNextChar + else: + act = QWebPage.SelectNextChar + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_prev_char(self): + """Move the cursor or select to the prev char.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToPreviousChar + else: + act = QWebPage.SelectPreviousChar + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_end_of_word(self): + """Move the cursor or select to the next word.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToNextWord + else: + act = QWebPage.SelectNextWord + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_next_word(self): + """Move the cursor or select to the next word.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = [QWebPage.MoveToNextWord, QWebPage.MoveToNextChar] + else: + act = [QWebPage.SelectNextWord, QWebPage.SelectNextChar] + for a in act: + self._current_widget().triggerPageAction(a) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_prev_word(self): + """Move the cursor or select to the prev word.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToPreviousWord + else: + act = QWebPage.SelectPreviousWord + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_start_of_line(self): + """Move the cursor or select to the start of line.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToStartOfLine + else: + act = QWebPage.SelectStartOfLine + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_end_of_line(self): + """Move the cursor or select to the end of line.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToEndOfLine + else: + act = QWebPage.SelectEndOfLine + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_start_of_block(self): + """Move the cursor or select to the start of block.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToStartOfBlock + else: + act = QWebPage.SelectStartOfBlock + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_end_of_block(self): + """Move the cursor or select to the end of block.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToEndOfBlock + else: + act = QWebPage.SelectEndOfBlock + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_start_of_document(self): + """Move the cursor or select to the start of document.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToStartOfDocument + else: + act = QWebPage.SelectStartOfDocument + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.caret, usertypes.KeyMode.visual], + hide=True, scope='window') + def move_to_end_of_document(self): + """Move the cursor or select to the end of document.""" + modemanager = modeman._get_modeman(self._win_id) + if modemanager.mode == usertypes.KeyMode.caret: + act = QWebPage.MoveToEndOfDocument + else: + act = QWebPage.SelectEndOfDocument + self._current_widget().triggerPageAction(act) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.visual], + hide=True, scope='window') + def yank_selected(self, sel=False): + """Yank selected text to the clipboard or primary selection. + + Args: + sel: Use the primary selection instead of the clipboard. + """ + s = self._current_widget().selectedText() + if not self._current_widget().hasSelection() or len(s) == 0: + message.info(self._win_id, "Nothing to yank") + return + + clipboard = QApplication.clipboard() + if sel and clipboard.supportsSelection(): + mode = QClipboard.Selection + target = "primary selection" + else: + mode = QClipboard.Clipboard + target = "clipboard" + log.misc.debug("Yanking to {}: '{}'".format(target, s)) + clipboard.setText(s, mode) + message.info(self._win_id, "{} {} yanked to {}" + .format(len(s), "char" if len(s) == 1 else "chars", target)) + + @cmdutils.register(instance='command-dispatcher', + modes=[usertypes.KeyMode.visual], + hide=True, scope='window') + def drop_selection(self): + """Drop selection and stay in visual mode.""" + self._current_widget().triggerPageAction(QWebPage.MoveToNextChar) diff --git a/qutebrowser/browser/webview.py b/qutebrowser/browser/webview.py index ee88e4089..19c34f9c3 100644 --- a/qutebrowser/browser/webview.py +++ b/qutebrowser/browser/webview.py @@ -23,10 +23,11 @@ import sys import itertools import functools -from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QTimer, QUrl +from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QTimer, QUrl, QPoint from PyQt5.QtWidgets import QApplication, QStyleFactory from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKitWidgets import QWebView, QWebPage +from PyQt5.QtGui import QMouseEvent from qutebrowser.config import config from qutebrowser.keyinput import modeman @@ -69,6 +70,7 @@ class WebView(QWebView): _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. + _caret_exist: Whether caret already has focus element Signals: scroll_pos_changed: Scroll percentage of current tab changed. @@ -142,6 +144,7 @@ class WebView(QWebView): self.viewing_source = False self.setZoomFactor(float(config.get('ui', 'default-zoom')) / 100) self._default_zoom_changed = False + self._caret_exist = False objreg.get('config').changed.connect(self.on_config_changed) if config.get('input', 'rocker-gestures'): self.setContextMenuPolicy(Qt.PreventContextMenu) @@ -427,6 +430,31 @@ class WebView(QWebView): "entered.".format(mode)) self.setFocusPolicy(Qt.NoFocus) + self._caret_exist = False + elif mode in (usertypes.KeyMode.caret, usertypes.KeyMode.visual): + self.settings().setAttribute(QWebSettings.CaretBrowsingEnabled, True) + + tabbed_browser = objreg.get('tabbed-browser', scope='window', + window=self.win_id) + if self.tab_id == tabbed_browser._now_focused.tab_id and not self._caret_exist: + """ + Here is a workaround for auto position enabled caret. + Unfortunatly, caret doesn't appear until you click + mouse button on element. I have such behavior in dwb, + so I decided to implement this workaround. + May be should be reworked. + """ + frame = self.page().currentFrame() + halfWidth = frame.scrollBarGeometry(Qt.Horizontal).width() / 2 + point = QPoint(halfWidth,1) + event = QMouseEvent(QMouseEvent.MouseButtonPress, point, point, + point, Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) + QApplication.sendEvent(self, event) + + self._caret_exist = True + else: + self._caret_exist = False + @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Restore focus policy if status-input modes were left.""" @@ -434,8 +462,16 @@ class WebView(QWebView): usertypes.KeyMode.yesno): log.webview.debug("Restoring focus policy because mode {} was " "left.".format(mode)) + elif mode in (usertypes.KeyMode.caret, usertypes.KeyMode.visual): + if self.settings().testAttribute(QWebSettings.CaretBrowsingEnabled): + if mode == usertypes.KeyMode.visual and self.hasSelection(): + # Remove selection if exist + self.triggerPageAction(QWebPage.MoveToNextChar) + self.settings().setAttribute(QWebSettings.CaretBrowsingEnabled, False) + self.setFocusPolicy(Qt.WheelFocus) + def createWindow(self, wintype): """Called by Qt when a page wants to create a new window. diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index fea34ab91..079b0da87 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1019,6 +1019,8 @@ KEY_SECTION_DESC = { " * `prompt-accept`: Confirm the entered value.\n" " * `prompt-yes`: Answer yes to a yes/no question.\n" " * `prompt-no`: Answer no to a yes/no question."), + 'caret': ( + ""), } @@ -1083,6 +1085,7 @@ KEY_DATA = collections.OrderedDict([ ('search-next', ['n']), ('search-prev', ['N']), ('enter-mode insert', ['i']), + ('enter-mode caret', ['c', 'v']), ('yank', ['yy']), ('yank -s', ['yY']), ('yank -t', ['yt']), @@ -1178,6 +1181,36 @@ KEY_DATA = collections.OrderedDict([ ('rl-delete-char', ['']), ('rl-backward-delete-char', ['']), ])), + + ('visual', collections.OrderedDict([ + ('yank-selected', ['y']), + ('yank-selected -s', ['Y']), + ('drop-selection', ['v']), + ('enter-mode caret', ['c']), + ])), + + ('caret', collections.OrderedDict([ + ('enter-mode visual', ['v']), + ('enter-mode normal', ['c']), + ])), + + ('caret,visual', collections.OrderedDict([ + ('move-to-next-line', ['j']), + ('move-to-prev-line', ['k']), + ('move-to-next-char', ['l']), + ('move-to-prev-char', ['h']), + ('move-to-end-of-word', ['e']), + ('move-to-next-word', ['w']), + ('move-to-prev-word', ['b']), + ('move-to-start-of-line', ['0']), + ('move-to-end-of-line', ['$']), + ('move-to-start-of-document', ['gg']), + ('move-to-end-of-document', ['G']), + ('scroll -50 0', ['H']), + ('scroll 0 50', ['J']), + ('scroll 0 -50', ['K']), + ('scroll 50 0', ['L']), + ])), ]) diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index 4699de8e9..d956cfc08 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -25,6 +25,7 @@ from PyQt5.QtGui import QWindow from PyQt5.QtCore import pyqtSignal, Qt, QObject, QEvent from PyQt5.QtWidgets import QApplication from PyQt5.QtWebKitWidgets import QWebView +from PyQt5.QtWebKit import QWebSettings from qutebrowser.keyinput import modeparsers, keyparser from qutebrowser.config import config @@ -79,6 +80,8 @@ def init(win_id, parent): KM.prompt: keyparser.PassthroughKeyParser(win_id, 'prompt', modeman, warn=False), KM.yesno: modeparsers.PromptKeyParser(win_id, modeman), + KM.caret: modeparsers.CaretKeyParser(win_id, modeman), + KM.visual: modeparsers.VisualKeyParser(win_id, modeman), } objreg.register('keyparsers', keyparsers, scope='window', window=win_id) modeman.destroyed.connect( @@ -93,6 +96,8 @@ def init(win_id, parent): passthrough=True) modeman.register(KM.prompt, keyparsers[KM.prompt].handle, passthrough=True) modeman.register(KM.yesno, keyparsers[KM.yesno].handle) + modeman.register(KM.caret, keyparsers[KM.caret].handle, passthrough=True) + modeman.register(KM.visual, keyparsers[KM.visual].handle, passthrough=True) return modeman diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py index 7ca4eabc7..4a545f53e 100644 --- a/qutebrowser/keyinput/modeparsers.py +++ b/qutebrowser/keyinput/modeparsers.py @@ -218,3 +218,27 @@ class HintKeyParser(keyparser.CommandKeyParser): hintmanager = objreg.get('hintmanager', scope='tab', window=self._win_id, tab='current') hintmanager.handle_partial_key(keystr) + +class CaretKeyParser(keyparser.CommandKeyParser): + + """KeyParser for Caret mode.""" + + def __init__(self, win_id, parent=None): + super().__init__(win_id, parent, supports_count=True, + supports_chains=True) + self.read_config('caret') + + def __repr__(self): + return utils.get_repr(self) + +class VisualKeyParser(keyparser.CommandKeyParser): + + """KeyParser for Visual mode.""" + + def __init__(self, win_id, parent=None): + super().__init__(win_id, parent, supports_count=True, + supports_chains=True) + self.read_config('visual') + + def __repr__(self): + return utils.get_repr(self) diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 30cdf1245..5e2d40cf0 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -546,7 +546,8 @@ class TabbedBrowser(tabwidget.TabWidget): tab = self.widget(idx) log.modes.debug("Current tab changed, focusing {!r}".format(tab)) tab.setFocus() - for mode in (usertypes.KeyMode.hint, usertypes.KeyMode.insert): + for mode in (usertypes.KeyMode.hint, usertypes.KeyMode.insert, + usertypes.KeyMode.caret, usertypes.KeyMode.visual): modeman.maybe_leave(self._win_id, mode, 'tab changed') if self._now_focused is not None: objreg.register('last-focused-tab', self._now_focused, update=True, diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 7371f3114..ba5957155 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -231,7 +231,7 @@ ClickTarget = enum('ClickTarget', ['normal', 'tab', 'tab_bg', 'window']) # Key input modes KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt', - 'insert', 'passthrough']) + 'insert', 'passthrough', 'caret', 'visual']) # Available command completions From 941eac848efca4298e64c4522e0b2c201f805f44 Mon Sep 17 00:00:00 2001 From: Artur Shaik Date: Mon, 13 Apr 2015 18:37:33 +0600 Subject: [PATCH 2/4] Remove "c" key from normal -> caret mode key bindings --- qutebrowser/config/configdata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 079b0da87..0765727b5 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1085,7 +1085,7 @@ KEY_DATA = collections.OrderedDict([ ('search-next', ['n']), ('search-prev', ['N']), ('enter-mode insert', ['i']), - ('enter-mode caret', ['c', 'v']), + ('enter-mode caret', ['v']), ('yank', ['yy']), ('yank -s', ['yY']), ('yank -t', ['yt']), From a6443231e5644d204088c56b7bfdad436b2311d1 Mon Sep 17 00:00:00 2001 From: Artur Shaik Date: Mon, 13 Apr 2015 19:50:27 +0600 Subject: [PATCH 3/4] Add statusbar coloring for caret and visual modes --- qutebrowser/config/configdata.py | 8 +++++ qutebrowser/mainwindow/statusbar/bar.py | 45 ++++++++++++++++++++----- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 0765727b5..d4b68cb34 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -758,6 +758,14 @@ DATA = collections.OrderedDict([ SettingValue(typ.QssColor(), 'darkgreen'), "Background color of the statusbar in insert mode."), + ('statusbar.bg.caret', + SettingValue(typ.QssColor(), 'purple'), + "Background color of the statusbar in caret mode."), + + ('statusbar.bg.visual', + SettingValue(typ.QssColor(), '#a12dff'), + "Background color of the statusbar in visual mode."), + ('statusbar.progress.bg', SettingValue(typ.QssColor(), 'white'), "Background color of the progress bar."), diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index a1c8aabd0..af33d3fe6 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -91,6 +91,8 @@ class StatusBar(QWidget): _severity = None _prompt_active = False _insert_active = False + _caret_active = False + _visual_active = False STYLESHEET = """ QWidget#StatusBar { @@ -101,6 +103,14 @@ class StatusBar(QWidget): {{ color['statusbar.bg.insert'] }} } + QWidget#StatusBar[caret_active="true"] { + {{ color['statusbar.bg.caret'] }} + } + + QWidget#StatusBar[visual_active="true"] { + {{ color['statusbar.bg.visual'] }} + } + QWidget#StatusBar[prompt_active="true"] { {{ color['statusbar.bg.prompt'] }} } @@ -253,14 +263,31 @@ class StatusBar(QWidget): """Getter for self.insert_active, so it can be used as Qt property.""" return self._insert_active - def _set_insert_active(self, val): - """Setter for self.insert_active. + @pyqtProperty(bool) + def caret_active(self): + """Getter for self.caret_active, so it can be used as Qt property.""" + return self._caret_active + + @pyqtProperty(bool) + def visual_active(self): + """Getter for self.visual_active, so it can be used as Qt property.""" + return self._visual_active + + def _set_mode_active(self, mode, val): + """Setter for self.insert_active, self.caret_active or self.visual_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ - log.statusbar.debug("Setting insert_active to {}".format(val)) - self._insert_active = val + if mode == usertypes.KeyMode.insert: + log.statusbar.debug("Setting insert_active to {}".format(val)) + self._insert_active = val + elif mode == usertypes.KeyMode.caret: + log.statusbar.debug("Setting caret_active to {}".format(val)) + self._caret_active = val + elif mode == usertypes.KeyMode.visual: + log.statusbar.debug("Setting visual_active to {}".format(val)) + self._visual_active = val self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) def _set_mode_text(self, mode): @@ -438,8 +465,9 @@ class StatusBar(QWidget): window=self._win_id) if mode in mode_manager.passthrough: self._set_mode_text(mode.name) - if mode == usertypes.KeyMode.insert: - self._set_insert_active(True) + if mode in (usertypes.KeyMode.insert, usertypes.KeyMode.caret, + usertypes.KeyMode.visual): + self._set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): @@ -451,8 +479,9 @@ class StatusBar(QWidget): self._set_mode_text(new_mode.name) else: self.txt.set_text(self.txt.Text.normal, '') - if old_mode == usertypes.KeyMode.insert: - self._set_insert_active(False) + if old_mode in (usertypes.KeyMode.insert, usertypes.KeyMode.caret, + usertypes.KeyMode.visual): + self._set_mode_active(old_mode, False) @config.change_filter('ui', 'message-timeout') def set_pop_timer_interval(self): From e603d9a2d07b879ec221f515b14fbe84d1e1faab Mon Sep 17 00:00:00 2001 From: Artur Shaik Date: Mon, 13 Apr 2015 19:55:45 +0600 Subject: [PATCH 4/4] Slight modify of autofocus caret Make mouseclick event point slightly down. Add commented tries of more reliable methods of caret focusing. --- qutebrowser/browser/webview.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/webview.py b/qutebrowser/browser/webview.py index 19c34f9c3..22dca3878 100644 --- a/qutebrowser/browser/webview.py +++ b/qutebrowser/browser/webview.py @@ -446,10 +446,16 @@ class WebView(QWebView): """ frame = self.page().currentFrame() halfWidth = frame.scrollBarGeometry(Qt.Horizontal).width() / 2 - point = QPoint(halfWidth,1) + point = QPoint(halfWidth,10) event = QMouseEvent(QMouseEvent.MouseButtonPress, point, point, point, Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) QApplication.sendEvent(self, event) + #frame.setFocus() + #frame.documentElement().setFocus() + #frame.documentElement().firstChild().setFocus() + #self.page().focusNextPrevChild(True) + #self.page().setContentEditable(True) + #self.triggerPageAction(QWebPage.MoveToNextChar) self._caret_exist = True else: