diff --git a/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch b/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch
index 5527076..8e45eb6 100644
--- a/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch
+++ b/SOURCES/tigervnc-fix-ghost-cursor-in-zaphod-mode.patch
@@ -1,26 +1,36 @@
+From f783d5c8b567199178b6690f347e060a69d2aa36 Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jgrulich@redhat.com>
+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 <ofourdan@redhat.com>
+---
+ 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/SPECS/tigervnc.spec b/SPECS/tigervnc.spec
index 8c9a978..813e0f5 100644
--- a/SPECS/tigervnc.spec
+++ b/SPECS/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 <jgrulich@redhat.com> - 1.12.0-7
+- x0vncserver: fix ghost cursor in zaphod mode (better version)
+  Resolves: bz#2109679
+
 * Wed Aug 17 2022 Jan Grulich <jgrulich@redhat.com> - 1.12.0-6
 - x0vncserver: fix ghost cursor in zaphod mode
   Resolves: bz#2109679