diff options
author | Maxim Devaev <[email protected]> | 2024-11-20 17:50:27 +0200 |
---|---|---|
committer | Maxim Devaev <[email protected]> | 2024-11-20 17:50:27 +0200 |
commit | 3cbeabe2e86ba988f58c3a269889f1cc241b3ca8 (patch) | |
tree | 3dc7505c8018313a549eb1859e6a1926d2973740 /kvmd | |
parent | e9e7f9bd0553b77a993f560d64ec814f520852fb (diff) |
VNC: Supported ExtendedMouseButtons
Diffstat (limited to 'kvmd')
-rw-r--r-- | kvmd/apps/vnc/rfb/__init__.py | 9 | ||||
-rw-r--r-- | kvmd/apps/vnc/rfb/encodings.py | 18 | ||||
-rw-r--r-- | kvmd/apps/vnc/server.py | 2 |
3 files changed, 20 insertions, 9 deletions
diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py index d2c6b50b..fc6e435c 100644 --- a/kvmd/apps/vnc/rfb/__init__.py +++ b/kvmd/apps/vnc/rfb/__init__.py @@ -464,6 +464,10 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute if self._encodings.has_ext_keys: # Preferred method await self._write_fb_update("ExtKeys FBUR", 0, 0, RfbEncodings.EXT_KEYS, drain=True) + + if self._encodings.has_ext_mouse: # Preferred too + await self._write_fb_update("ExtMouse FBUR", 0, 0, RfbEncodings.EXT_MOUSE, drain=True) + await self._on_set_encodings() async def __handle_fb_update_request(self) -> None: @@ -486,11 +490,16 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute async def __handle_pointer_event(self) -> None: (buttons, to_x, to_y) = await self._read_struct("pointer event", "B HH") + ext_buttons = 0 + if self._encodings.has_ext_mouse and (buttons & 0x80): # Marker bit 7 for ext event + ext_buttons = await self._read_number("ext pointer event buttons", "B") await self._on_pointer_event( buttons={ "left": bool(buttons & 0x1), "right": bool(buttons & 0x4), "middle": bool(buttons & 0x2), + "up": bool(ext_buttons & 0x2), + "down": bool(ext_buttons & 0x1), }, wheel={ "x": (-4 if buttons & 0x40 else (4 if buttons & 0x20 else 0)), diff --git a/kvmd/apps/vnc/rfb/encodings.py b/kvmd/apps/vnc/rfb/encodings.py index 597e3a92..940a383f 100644 --- a/kvmd/apps/vnc/rfb/encodings.py +++ b/kvmd/apps/vnc/rfb/encodings.py @@ -31,6 +31,7 @@ class RfbEncodings: RENAME = -307 # DesktopName Pseudo-encoding LEDS_STATE = -261 # QEMU LED State Pseudo-encoding EXT_KEYS = -258 # QEMU Extended Key Events Pseudo-encoding + EXT_MOUSE = -316 # ExtendedMouseButtons Pseudo-encoding CONT_UPDATES = -313 # ContinuousUpdates Pseudo-encoding TIGHT = 7 @@ -50,16 +51,17 @@ def _make_meta(variants: (int | frozenset[int])) -> dict: class RfbClientEncodings: # pylint: disable=too-many-instance-attributes encodings: frozenset[int] - has_resize: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RESIZE)) # noqa: E224 - has_rename: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RENAME)) # noqa: E224 - has_leds_state: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.LEDS_STATE)) # noqa: E224 - has_ext_keys: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.EXT_KEYS)) # noqa: E224 - has_cont_updates: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.CONT_UPDATES)) # noqa: E224 + has_resize: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RESIZE)) # noqa: E224 + has_rename: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.RENAME)) # noqa: E224 + has_leds_state: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.LEDS_STATE)) # noqa: E224 + has_ext_keys: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.EXT_KEYS)) # noqa: E224 + has_ext_mouse: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.EXT_MOUSE)) # noqa: E224 + has_cont_updates: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.CONT_UPDATES)) # noqa: E224 - has_tight: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.TIGHT)) # noqa: E224 - tight_jpeg_quality: int = dataclasses.field(default=0, metadata=_make_meta(frozenset(RfbEncodings.TIGHT_JPEG_QUALITIES))) # noqa: E224 + has_tight: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.TIGHT)) # noqa: E224 + tight_jpeg_quality: int = dataclasses.field(default=0, metadata=_make_meta(frozenset(RfbEncodings.TIGHT_JPEG_QUALITIES))) # noqa: E224 - has_h264: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.H264)) # noqa: E224 + has_h264: bool = dataclasses.field(default=False, metadata=_make_meta(RfbEncodings.H264)) # noqa: E224 def get_summary(self) -> list[str]: summary: list[str] = [f"encodings -- {sorted(self.encodings)}"] diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py index 5abca7b0..6bb7caed 100644 --- a/kvmd/apps/vnc/server.py +++ b/kvmd/apps/vnc/server.py @@ -130,7 +130,7 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes # Эти состояния шарить не обязательно - бекенд исключает дублирующиеся события. # Все это нужно только чтобы не посылать лишние жсоны в сокет KVMD - self.__mouse_buttons: dict[str, (bool | None)] = dict.fromkeys(["left", "right", "middle"], None) + self.__mouse_buttons: dict[str, (bool | None)] = dict.fromkeys(["left", "right", "middle", "up", "down"], None) self.__mouse_move = {"x": -1, "y": -1} self.__modifiers = 0 |