Skip to content

Commit

Permalink
fix: mouseDrag diagonally
Browse files Browse the repository at this point in the history
move mouse diagonally instead of first going up/down and then
left/right.

Do not use `time.sleep()` with Twisted reactor as it will also pause all
other event processing.

Patch `vncev` to print all mouse events, including those where not button
is pressed / released.

Issue sibson#287
  • Loading branch information
pmhahn committed Jun 17, 2024
1 parent acd35fe commit 051f805
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Python 3.12 is supported (@phahn)
- Improve documentation (@phahn)
- Improve PEP-484 type hinting (@phahn)
- Fix mouse dragging (@phahn)

1.2.0 (2023-06-06)
----------------------
Expand Down
1 change: 1 addition & 0 deletions libvncserver.mk
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ $(BUILD_DIR)/$(LIBVNCSERVER_TGZ):

$(LIBVNCSERVER_DIR): $(BUILD_DIR)/$(LIBVNCSERVER_TGZ)
tar xfzv $< -C $(BUILD_DIR)
sed -e '/^\s*if(buttonMask)\s*{$/s/buttonMask/1/' -i "$(LIBVNCSERVER_DIR)/examples/vncev.c"

$(LIBVNCSERVER_MAKEFILE): $(LIBVNCSERVER_MAKEFILE_SRCS)
cd $(LIBVNCSERVER_DIR) && cmake .
Expand Down
8 changes: 7 additions & 1 deletion tests/functional/test_send_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,17 @@ def test_type(self) -> None:
self.assertDisconnect()

def test_mouse_move(self) -> None:
# vncev only prints click events, but will include the position
self.run_vncdo('move 10 20 click 1')
self.assertMouse(10, 20, 0x1)
self.assertDisconnect()

def test_mouse_drag(self) -> None:
self.run_vncdo('move 10 20 drag 30 30 click 1')
self.assertMouse(10, 20, 0x0)
self.assertMouse(20, 25, 0x0)
self.assertMouse(30, 30, 0x1)
self.assertDisconnect()

def test_mouse_click_button_two(self) -> None:
self.run_vncdo('click 2')
self.assertMouse(0, 0, 0x2)
Expand Down
35 changes: 11 additions & 24 deletions vncdotool/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@
import logging
import math
import socket
import time
from pathlib import Path
from struct import pack
from typing import IO, Any, TypeVar, Union
from typing import IO, Any, Iterator, TypeVar, Union

from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.defer import Deferred, inlineCallbacks, returnValue
from twisted.internet.endpoints import HostnameEndpoint, UNIXClientEndpoint
from twisted.internet.interfaces import IConnector, ITCPTransport
from twisted.python.failure import Failure
Expand Down Expand Up @@ -346,32 +345,20 @@ def mouseMove(self: TClient, x: int, y: int) -> TClient:
self.pointerEvent(x, y, self.buttons)
return self

def mouseDrag(self: TClient, x: int, y: int, step: int = 1) -> TClient:
@inlineCallbacks
def mouseDrag(self: TClient, x: int, y: int, step: int = 1) -> Iterator[Deferred]:
"""Move the mouse point to position (x, y) in increments of step"""
log.debug("mouseDrag %d,%d", x, y)
if x < self.x:
xsteps = range(self.x - step, x, -step)
else:
xsteps = range(self.x + step, x, step)

if y < self.y:
ysteps = range(self.y - step, y, -step)
else:
ysteps = range(self.y + step, y, step)

for ypos in ysteps:
self.mouseMove(self.x, ypos)
reactor.doPoll(timeout=5)
time.sleep(0.2)

for xpos in xsteps:
self.mouseMove(xpos, self.y)
reactor.doPoll(timeout=5)
time.sleep(0.2)
ox, oy = self.x, self.y
dx, dy = x - ox, y - oy
dmax = max(abs(dx), abs(dy))
for s in range(0, dmax, step):
self.mouseMove(ox + dx * s // dmax, oy + dy * s // dmax)
yield self.pause(0.2)

self.mouseMove(x, y)

return self
returnValue(self)

def setImageMode(self) -> None:
"""Check support for PixelFormats announced by server or select client supported alternative."""
Expand Down

0 comments on commit 051f805

Please sign in to comment.