|
|
e70a52 |
From f783d5c8b567199178b6690f347e060a69d2aa36 Mon Sep 17 00:00:00 2001
|
|
|
e70a52 |
From: Jan Grulich <jgrulich@redhat.com>
|
|
|
e70a52 |
Date: Thu, 11 Aug 2022 13:15:29 +0200
|
|
|
e70a52 |
Subject: [PATCH] x0vncserver: update/display cursor only on correct screen in
|
|
|
e70a52 |
zaphod mode
|
|
|
e70a52 |
|
|
|
e70a52 |
We have to check whether we update cursor position/shape only in case
|
|
|
e70a52 |
the cursor is on our display, otherwise in zaphod mode, ie. when having
|
|
|
e70a52 |
two instances of x0vncserver on screens :0.0 and :0.1 we would be having
|
|
|
e70a52 |
the cursor duplicated and actually not funcional (aka ghost cursor) as
|
|
|
e70a52 |
it would be actually not present. We also additionally watch EnterNotify
|
|
|
e70a52 |
and LeaveNotify events in order to show/hide cursor accordingly.
|
|
|
e70a52 |
|
|
|
e70a52 |
Change made with help from Olivier Fourdan <ofourdan@redhat.com>
|
|
|
e70a52 |
---
|
|
|
e70a52 |
unix/x0vncserver/XDesktop.cxx | 60 +++++++++++++++++++++++++++++++----
|
|
|
e70a52 |
1 file changed, 53 insertions(+), 7 deletions(-)
|
|
|
e70a52 |
|
|
|
e70a52 |
diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx
|
|
|
e70a52 |
index f2046e43e..f07fd78bf 100644
|
|
|
e70a52 |
--- a/unix/x0vncserver/XDesktop.cxx
|
|
|
e70a52 |
+++ b/unix/x0vncserver/XDesktop.cxx
|
|
|
e70a52 |
@@ -192,7 +192,8 @@ XDesktop::XDesktop(Display* dpy_, Geometry *geometry_)
|
|
|
e70a52 |
RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask);
|
|
|
e70a52 |
/* Override TXWindow::init input mask */
|
|
|
e70a52 |
XSelectInput(dpy, DefaultRootWindow(dpy),
|
|
|
e70a52 |
- PropertyChangeMask | StructureNotifyMask | ExposureMask);
|
|
|
e70a52 |
+ PropertyChangeMask | StructureNotifyMask |
|
|
|
e70a52 |
+ ExposureMask | EnterWindowMask | LeaveWindowMask);
|
|
|
e70a52 |
} else {
|
|
|
e70a52 |
#endif
|
|
|
e70a52 |
vlog.info("RANDR extension not present");
|
|
|
e70a52 |
@@ -217,11 +218,13 @@ void XDesktop::poll() {
|
|
|
e70a52 |
Window root, child;
|
|
|
e70a52 |
int x, y, wx, wy;
|
|
|
e70a52 |
unsigned int mask;
|
|
|
e70a52 |
- XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child,
|
|
|
e70a52 |
- &x, &y, &wx, &wy, &mask);
|
|
|
e70a52 |
- x -= geometry->offsetLeft();
|
|
|
e70a52 |
- y -= geometry->offsetTop();
|
|
|
e70a52 |
- server->setCursorPos(rfb::Point(x, y), false);
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child,
|
|
|
e70a52 |
+ &x, &y, &wx, &wy, &mask)) {
|
|
|
e70a52 |
+ x -= geometry->offsetLeft();
|
|
|
e70a52 |
+ y -= geometry->offsetTop();
|
|
|
e70a52 |
+ server->setCursorPos(rfb::Point(x, y), false);
|
|
|
e70a52 |
+ }
|
|
|
e70a52 |
}
|
|
|
e70a52 |
}
|
|
|
e70a52 |
|
|
|
e70a52 |
@@ -253,7 +256,14 @@ void XDesktop::start(VNCServer* vs) {
|
|
|
e70a52 |
#endif
|
|
|
e70a52 |
|
|
|
e70a52 |
#ifdef HAVE_XFIXES
|
|
|
e70a52 |
- setCursor();
|
|
|
e70a52 |
+ Window root, child;
|
|
|
e70a52 |
+ int x, y, wx, wy;
|
|
|
e70a52 |
+ unsigned int mask;
|
|
|
e70a52 |
+ // Check whether the cursor is initially on our screen
|
|
|
e70a52 |
+ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child,
|
|
|
e70a52 |
+ &x, &y, &wx, &wy, &mask))
|
|
|
e70a52 |
+ setCursor();
|
|
|
e70a52 |
+
|
|
|
e70a52 |
#endif
|
|
|
e70a52 |
|
|
|
e70a52 |
server->setLEDState(ledState);
|
|
|
e70a52 |
@@ -701,6 +711,15 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) {
|
|
|
e70a52 |
if (cev->subtype != XFixesDisplayCursorNotify)
|
|
|
e70a52 |
return false;
|
|
|
e70a52 |
|
|
|
e70a52 |
+ Window root, child;
|
|
|
e70a52 |
+ int x, y, wx, wy;
|
|
|
e70a52 |
+ unsigned int mask;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ // Check whether the cursor is initially on our screen
|
|
|
e70a52 |
+ if (!XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child,
|
|
|
e70a52 |
+ &x, &y, &wx, &wy, &mask))
|
|
|
e70a52 |
+ return false;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
return setCursor();
|
|
|
e70a52 |
#endif
|
|
|
e70a52 |
#ifdef HAVE_XRANDR
|
|
|
e70a52 |
@@ -753,6 +772,33 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) {
|
|
|
e70a52 |
|
|
|
e70a52 |
return true;
|
|
|
e70a52 |
#endif
|
|
|
e70a52 |
+#ifdef HAVE_XFIXES
|
|
|
e70a52 |
+ } else if (ev->type == EnterNotify) {
|
|
|
e70a52 |
+ XCrossingEvent* cev;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ if (!running)
|
|
|
e70a52 |
+ return true;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ cev = (XCrossingEvent*)ev;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ if (cev->window != cev->root)
|
|
|
e70a52 |
+ return false;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ return setCursor();
|
|
|
e70a52 |
+ } else if (ev->type == LeaveNotify) {
|
|
|
e70a52 |
+ XCrossingEvent* cev;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ if (!running)
|
|
|
e70a52 |
+ return true;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ cev = (XCrossingEvent*)ev;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ if (cev->window == cev->root)
|
|
|
e70a52 |
+ return false;
|
|
|
e70a52 |
+
|
|
|
e70a52 |
+ server->setCursor(0, 0, Point(), NULL);
|
|
|
e70a52 |
+ return true;
|
|
|
e70a52 |
+#endif
|
|
|
e70a52 |
}
|
|
|
e70a52 |
|
|
|
e70a52 |
return false;
|