diff --git a/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch b/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch index 5527076..8e45eb6 100644 --- a/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch +++ b/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch @@ -1,26 +1,36 @@ +From f783d5c8b567199178b6690f347e060a69d2aa36 Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Thu, 11 Aug 2022 13:15:29 +0200 +Subject: [PATCH] x0vncserver: update/display cursor only on correct screen in + zaphod mode + +We have to check whether we update cursor position/shape only in case +the cursor is on our display, otherwise in zaphod mode, ie. when having +two instances of x0vncserver on screens :0.0 and :0.1 we would be having +the cursor duplicated and actually not funcional (aka ghost cursor) as +it would be actually not present. We also additionally watch EnterNotify +and LeaveNotify events in order to show/hide cursor accordingly. + +Change made with help from Olivier Fourdan +--- + unix/x0vncserver/XDesktop.cxx | 60 +++++++++++++++++++++++++++++++---- + 1 file changed, 53 insertions(+), 7 deletions(-) + diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx -index f2046e43..8805be51 100644 +index f2046e43e..f07fd78bf 100644 --- a/unix/x0vncserver/XDesktop.cxx +++ b/unix/x0vncserver/XDesktop.cxx -@@ -80,7 +80,7 @@ XDesktop::XDesktop(Display* dpy_, Geometry *geometry_) - queryConnectDialog(0), queryConnectSock(0), - oldButtonMask(0), haveXtest(false), haveDamage(false), - maxButtons(0), running(false), ledMasks(), ledState(0), -- codeMap(0), codeMapLen(0) -+ codeMap(0), codeMapLen(0), isCursorVisibleOnScreen(false) - { - int major, minor; - -@@ -192,7 +192,7 @@ XDesktop::XDesktop(Display* dpy_, Geometry *geometry_) +@@ -192,7 +192,8 @@ XDesktop::XDesktop(Display* dpy_, Geometry *geometry_) RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask); /* Override TXWindow::init input mask */ XSelectInput(dpy, DefaultRootWindow(dpy), - PropertyChangeMask | StructureNotifyMask | ExposureMask); -+ PropertyChangeMask | StructureNotifyMask | ExposureMask | EnterWindowMask | LeaveWindowMask); ++ PropertyChangeMask | StructureNotifyMask | ++ ExposureMask | EnterWindowMask | LeaveWindowMask); } else { #endif vlog.info("RANDR extension not present"); -@@ -217,11 +217,13 @@ void XDesktop::poll() { +@@ -217,11 +218,13 @@ void XDesktop::poll() { Window root, child; int x, y, wx, wy; unsigned int mask; @@ -29,48 +39,54 @@ index f2046e43..8805be51 100644 - x -= geometry->offsetLeft(); - y -= geometry->offsetTop(); - server->setCursorPos(rfb::Point(x, y), false); -+ isCursorVisibleOnScreen = XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, -+ &x, &y, &wx, &wy, &mask); -+ if (isCursorVisibleOnScreen) { ++ ++ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, ++ &x, &y, &wx, &wy, &mask)) { + x -= geometry->offsetLeft(); + y -= geometry->offsetTop(); + server->setCursorPos(rfb::Point(x, y), false); + } } } - -@@ -253,7 +255,15 @@ void XDesktop::start(VNCServer* vs) { + +@@ -253,7 +256,14 @@ void XDesktop::start(VNCServer* vs) { #endif - + #ifdef HAVE_XFIXES - setCursor(); + Window root, child; + int x, y, wx, wy; + unsigned int mask; + // Check whether the cursor is initially on our screen -+ isCursorVisibleOnScreen = XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, -+ &x, &y, &wx, &wy, &mask); -+ if (isCursorVisibleOnScreen) ++ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, ++ &x, &y, &wx, &wy, &mask)) + setCursor(); + #endif - + server->setLEDState(ledState); -@@ -701,6 +711,9 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { +@@ -701,6 +711,15 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { if (cev->subtype != XFixesDisplayCursorNotify) return false; - -+ if (!isCursorVisibleOnScreen) + ++ Window root, child; ++ int x, y, wx, wy; ++ unsigned int mask; ++ ++ // Check whether the cursor is initially on our screen ++ if (!XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, ++ &x, &y, &wx, &wy, &mask)) + return false; + return setCursor(); #endif #ifdef HAVE_XRANDR -@@ -753,6 +766,20 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { - +@@ -753,6 +772,33 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { + return true; #endif -+ } else if (ev->type == EnterNotify || ev->type == LeaveNotify) { ++#ifdef HAVE_XFIXES ++ } else if (ev->type == EnterNotify) { + XCrossingEvent* cev; + + if (!running) @@ -81,21 +97,21 @@ index f2046e43..8805be51 100644 + if (cev->window != cev->root) + return false; + -+ setCursor(); ++ return setCursor(); ++ } else if (ev->type == LeaveNotify) { ++ XCrossingEvent* cev; + ++ if (!running) ++ return true; ++ ++ cev = (XCrossingEvent*)ev; ++ ++ if (cev->window == cev->root) ++ return false; ++ ++ server->setCursor(0, 0, Point(), NULL); + return true; ++#endif } - + return false; -diff --git a/unix/x0vncserver/XDesktop.h b/unix/x0vncserver/XDesktop.h -index 840d4331..f01c63f7 100644 ---- a/unix/x0vncserver/XDesktop.h -+++ b/unix/x0vncserver/XDesktop.h -@@ -97,6 +97,7 @@ protected: - unsigned ledState; - const unsigned short *codeMap; - unsigned codeMapLen; -+ bool isCursorVisibleOnScreen; - bool setCursor(); - rfb::ScreenSet computeScreenLayout(); - }; diff --git a/tigervnc.spec b/tigervnc.spec index 8c9a978..813e0f5 100644 --- a/tigervnc.spec +++ b/tigervnc.spec @@ -5,7 +5,7 @@ Name: tigervnc Version: 1.12.0 -Release: 6%{?dist} +Release: 7%{?dist} Summary: A TigerVNC remote display system %global _hardened_build 1 @@ -28,6 +28,7 @@ Patch50: tigervnc-selinux-restore-context-in-case-of-different-policies.p Patch51: tigervnc-fix-typo-in-mirror-monitor-detection.patch Patch52: tigervnc-root-user-selinux-context.patch Patch53: tigervnc-vncsession-restore-script-systemd-service.patch +Patch54: tigervnc-fix-ghost-cursor-in-zaphod-mode.patch # This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg Patch100: tigervnc-xserver120.patch @@ -35,7 +36,7 @@ Patch100: tigervnc-xserver120.patch Patch101: 0001-rpath-hack.patch # Upstreamable patches -Patch200: tigervnc-fix-ghost-cursor-in-zaphod-mode.patch +# https://github.com/TigerVNC/tigervnc/pull/1513 BuildRequires: gcc-c++ BuildRequires: libX11-devel, automake, autoconf, libtool, gettext, gettext-autopoint @@ -167,8 +168,7 @@ popd %patch51 -p1 -b .fix-typo-in-mirror-monitor-detection %patch52 -p1 -b .root-user-selinux-context %patch53 -p1 -b .vncsession-restore-script-systemd-service - -%patch200 -p1 -b .fix-ghost-cursor-in-zaphod-mode +%patch54 -p1 -b .fix-ghost-cursor-in-zaphod-mode %build %ifarch sparcv9 sparc64 s390 s390x @@ -323,6 +323,10 @@ fi %ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename} %changelog +* Wed Aug 24 2022 Jan Grulich - 1.12.0-7 +- x0vncserver: fix ghost cursor in zaphod mode (better version) + Resolves: bz#2109679 + * Wed Aug 17 2022 Jan Grulich - 1.12.0-6 - x0vncserver: fix ghost cursor in zaphod mode Resolves: bz#2109679