Use fake key events for scrolling.

Closes #669.
Fixes #218.

See #246, #534.
This commit is contained in:
Florian Bruhin 2015-05-15 18:59:46 +02:00
parent c236046a73
commit f49dba6e38
3 changed files with 96 additions and 10 deletions

View File

@ -27,8 +27,8 @@ import posixpath
import functools
from PyQt5.QtWidgets import QApplication, QTabBar
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QClipboard
from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtGui import QClipboard, QKeyEvent
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
from PyQt5.QtWebKitWidgets import QWebPage
import pygments
@ -555,8 +555,8 @@ class CommandDispatcher:
@cmdutils.register(instance='command-dispatcher', hide=True,
scope='window', count='count')
def scroll(self, dx: {'type': float}, dy: {'type': float}, count=1):
"""Scroll the current tab by 'count * dx/dy'.
def scroll_px(self, dx: {'type': float}, dy: {'type': float}, count=1):
"""Scroll the current tab by 'count * dx/dy' pixels.
Args:
dx: How much to scroll in x-direction.
@ -569,6 +569,57 @@ class CommandDispatcher:
cmdutils.check_overflow(dy, 'int')
self._current_widget().page().currentFrame().scroll(dx, dy)
@cmdutils.register(instance='command-dispatcher', hide=True,
scope='window', count='count')
def scroll(self,
direction: {'type': (str, float)},
dy: {'type': float, 'hide': True}=None,
count=1):
"""Scroll the current tab in the given direction.
Args:
direction: In which direction to scroll
(up/down/left/right/top/bottom).
dy: Deprecated argument to support the old dx/dy form.
count: multiplier
"""
try:
# Check for deprecated dx/dy form (like with scroll-px).
dx = float(direction)
dy = float(dy)
except (ValueError, TypeError):
# Invalid values will get handled later.
pass
else:
message.warning(self._win_id, ":scroll with dx/dy arguments is "
"deprecated - use :scroll-px instead!")
self.scroll_px(dx, dy, count=count)
return
fake_keys = {
'up': Qt.Key_Up,
'down': Qt.Key_Down,
'left': Qt.Key_Left,
'right': Qt.Key_Right,
'top': Qt.Key_Home,
'bottom': Qt.Key_End,
'page-up': Qt.Key_PageUp,
'page-down': Qt.Key_PageDown,
}
try:
key = fake_keys[direction]
except KeyError:
raise cmdexc.CommandError("Invalid value {!r} for direction - "
"expected one of: {}".format(
direction, ', '.join(fake_keys)))
widget = self._current_widget()
press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0)
release_evt = QKeyEvent(QEvent.KeyRelease, key, Qt.NoModifier, 0, 0, 0)
for _ in range(count):
widget.keyPressEvent(press_evt)
widget.keyReleaseEvent(release_evt)
@cmdutils.register(instance='command-dispatcher', hide=True,
scope='window', count='count')
def scroll_perc(self, perc: {'type': float}=None,
@ -596,10 +647,22 @@ class CommandDispatcher:
y: How many pages to scroll down.
count: multiplier
"""
mult_x = count * x
mult_y = count * y
if mult_y.is_integer():
if mult_y == 0:
pass
elif mult_y < 0:
self.scroll('page-up', count=-mult_y)
elif mult_y > 0:
self.scroll('page-down', count=mult_y)
mult_y = 0
if mult_x == 0 and mult_y == 0:
return
frame = self._current_widget().page().currentFrame()
size = frame.geometry()
dx = count * x * size.width()
dy = count * y * size.height()
dx = mult_x * size.width()
dy = mult_y * size.height()
cmdutils.check_overflow(dx, 'int')
cmdutils.check_overflow(dy, 'int')
frame.scroll(dx, dy)

View File

@ -1143,10 +1143,10 @@ KEY_DATA = collections.OrderedDict([
('hint --rapid links tab-bg', [';r']),
('hint --rapid links window', [';R']),
('hint links download', [';d']),
('scroll -50 0', ['h']),
('scroll 0 50', ['j']),
('scroll 0 -50', ['k']),
('scroll 50 0', ['l']),
('scroll left', ['h']),
('scroll down', ['j']),
('scroll up', ['k']),
('scroll right', ['l']),
('undo', ['u', '<Ctrl-Shift-T>']),
('scroll-perc 0', ['gg']),
('scroll-perc', ['G']),
@ -1260,12 +1260,22 @@ KEY_DATA = collections.OrderedDict([
CHANGED_KEY_COMMANDS = [
(re.compile(r'^open -([twb]) about:blank$'), r'open -\1'),
(re.compile(r'^download-page$'), r'download'),
(re.compile(r'^cancel-download$'), r'download-cancel'),
(re.compile(r'^search ""$'), r'search'),
(re.compile(r"^search ''$"), r'search'),
(re.compile(r"""^set-cmd-text ['"](.*) ['"]$"""), r'set-cmd-text -s \1'),
(re.compile(r"""^set-cmd-text ['"](.*)['"]$"""), r'set-cmd-text \1'),
(re.compile(r"^hint links rapid$"), r'hint --rapid links tab-bg'),
(re.compile(r"^hint links rapid-win$"), r'hint --rapid links window'),
(re.compile(r'^scroll -50 0$'), r'scroll left'),
(re.compile(r'^scroll 0 50$'), r'scroll down'),
(re.compile(r'^scroll 0 -50$'), r'scroll up'),
(re.compile(r'^scroll 50 0$'), r'scroll right'),
(re.compile(r'^scroll ([-\d]+ [-\d]+)$'), r'scroll-px \1'),
]

View File

@ -198,18 +198,31 @@ class TestKeyConfigParser:
('open -b about:blank', 'open -b'),
('open about:blank', None),
('open -t example.com', None),
('download-page', 'download'),
('cancel-download', 'download-cancel'),
('search ""', 'search'),
("search ''", 'search'),
('search "foo"', None),
('set-cmd-text "foo bar"', 'set-cmd-text foo bar'),
("set-cmd-text 'foo bar'", 'set-cmd-text foo bar'),
('set-cmd-text foo bar', None),
('set-cmd-text "foo bar "', 'set-cmd-text -s foo bar'),
("set-cmd-text 'foo bar '", 'set-cmd-text -s foo bar'),
('hint links rapid', 'hint --rapid links tab-bg'),
('hint links rapid-win', 'hint --rapid links window'),
('scroll -50 0', 'scroll left'),
('scroll 0 50', 'scroll down'),
('scroll 0 -50', 'scroll up'),
('scroll 50 0', 'scroll right'),
('scroll -50 10', 'scroll-px -50 10'),
('scroll 50 50', 'scroll-px 50 50'),
('scroll 0 0', 'scroll-px 0 0'),
('scroll 23 42', 'scroll-px 23 42'),
]
)
def test_migrations(self, old, new_expected):