From 8a7df98a6683f3af958df74308090e5734306b75 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Mon, 23 Sep 2024 15:58:56 +0700 Subject: [PATCH] #4318 backport poll-pointer support --- xpra/client/gtk3/client.py | 2 +- xpra/client/mixins/window_manager.py | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/xpra/client/gtk3/client.py b/xpra/client/gtk3/client.py index b6803878aa..2216297cfe 100644 --- a/xpra/client/gtk3/client.py +++ b/xpra/client/gtk3/client.py @@ -91,7 +91,7 @@ def get_mouse_position(self): if not root: return -1, -1 p = root.get_pointer()[-3:-1] - return self.sp(p[0] or 0, p[1] or 0) + return self.cp(p[0] or 0, p[1] or 0) GObject.type_register(XpraClient) diff --git a/xpra/client/mixins/window_manager.py b/xpra/client/mixins/window_manager.py index f06da5830d..bf44ccf7c3 100644 --- a/xpra/client/mixins/window_manager.py +++ b/xpra/client/mixins/window_manager.py @@ -30,7 +30,7 @@ from xpra.make_thread import start_thread from xpra.os_util import ( bytestostr, memoryview_to_bytes, - OSX, POSIX, is_Ubuntu, + OSX, POSIX, is_Ubuntu, is_Wayland, ) from xpra.util import ( envint, envbool, typedict, @@ -79,6 +79,7 @@ ICON_SHRINKAGE : int = envint("XPRA_ICON_SHRINKAGE", 75) SAVE_WINDOW_ICONS : bool = envbool("XPRA_SAVE_WINDOW_ICONS", False) SAVE_CURSORS : bool = envbool("XPRA_SAVE_CURSORS", False) +POLL_POINTER = envint("XPRA_POLL_POINTER", 0) SIGNAL_WATCHER : bool = envbool("XPRA_SIGNAL_WATCHER", POSIX and not OSX) SIGNAL_WATCHER_COMMAND : str = os.environ.get("XPRA_SIGNAL_WATCHER_COMMAND", "xpra_signal_listener") if SIGNAL_WATCHER: @@ -214,6 +215,9 @@ def __init__(self): self._suspended_at : float = 0 self._button_state = {} + self.poll_pointer_timer = 0 + self.poll_pointer_position = -1, -1 + def init(self, opts) -> None: if opts.system_tray: try: @@ -332,6 +336,7 @@ def cleanup(self) -> None: #(cleaner and needed when we run embedded in the client launcher) self.destroy_all_windows() self.cancel_lost_focus_timer() + self.cancel_poll_pointer_timer() if dq: dq.put(None) dt = self._draw_thread @@ -438,6 +443,11 @@ def parse_server_capabilities(self, c : typedict) -> bool: self.server_input_devices = c.strget("input-devices") self.server_precise_wheel = c.boolget("wheel.precise", False) self.server_pointer_relative = c.boolget("pointer.relative", True) + if POLL_POINTER: + if is_Wayland(): + log.warn("Warning: pointer polling is unlikely to work under Wayland") + log.warn(" and may cause problems") + self.poll_pointer_timer = GLib.timeout_add(POLL_POINTER, self.poll_pointer) return True @@ -566,6 +576,22 @@ def send_input_devices(self, fmt, input_devices) -> None: self.send("input-devices", fmt, input_devices) + def poll_pointer(self) -> bool: + pos = self.get_mouse_position() + if pos != self.poll_pointer_position: + self.poll_pointer_position = pos + device_id = -1 + wid = 0 + mouselog(f"poll_pointer() updated position: {pos}") + self.send_mouse_position(device_id, wid, pos) + return True + + def cancel_poll_pointer_timer(self) -> None: + ppt = self.poll_pointer_timer + if ppt: + self.poll_pointer_timer = 0 + GLib.source_remove(ppt) + ###################################################################### # cursor: def _process_cursor(self, packet : PacketType) -> None: