diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx index f2046e43..8805be51 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_) RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask); /* Override TXWindow::init input mask */ XSelectInput(dpy, DefaultRootWindow(dpy), - PropertyChangeMask | StructureNotifyMask | ExposureMask); + PropertyChangeMask | StructureNotifyMask | ExposureMask | EnterWindowMask | LeaveWindowMask); } else { #endif vlog.info("RANDR extension not present"); @@ -217,11 +217,13 @@ void XDesktop::poll() { Window root, child; int x, y, wx, wy; unsigned int mask; - XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child, - &x, &y, &wx, &wy, &mask); - 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) { + x -= geometry->offsetLeft(); + y -= geometry->offsetTop(); + server->setCursorPos(rfb::Point(x, y), false); + } } } @@ -253,7 +255,15 @@ 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) + setCursor(); + #endif server->setLEDState(ledState); @@ -701,6 +711,9 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { if (cev->subtype != XFixesDisplayCursorNotify) return false; + if (!isCursorVisibleOnScreen) + return false; + return setCursor(); #endif #ifdef HAVE_XRANDR @@ -753,6 +766,20 @@ bool XDesktop::handleGlobalEvent(XEvent* ev) { return true; #endif + } else if (ev->type == EnterNotify || ev->type == LeaveNotify) { + XCrossingEvent* cev; + + if (!running) + return true; + + cev = (XCrossingEvent*)ev; + + if (cev->window != cev->root) + return false; + + setCursor(); + + return true; } 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(); };