]> source.dussan.org Git - tigervnc.git/commitdiff
VNCServerST: Add a timeout to pointer button ownership 1718/head
authorMike Looijmans <mike.looijmans@topic.nl>
Tue, 16 Jan 2024 15:27:43 +0000 (16:27 +0100)
committerMike Looijmans <mike.looijmans@topic.nl>
Mon, 22 Jan 2024 13:55:03 +0000 (14:55 +0100)
When one clients holds down a button on the pointer device (probably
dragging something), other clients' attempts at pointer operations
are denied. This yields a sane user experience, but with limits.

When one clients starts dragging, and then his network connection fails,
other clients are denied access to the pointer until the VNC server
finally discovers that the connection is dead and closes it. This can
take about 15 minutes.

Add a timeout to this policy: If we don't hear from the client for 3
seconds, other clients are allowed to control the pointer once more.

This solves the problem that one failing network could make the server
completely deaf to other clients for a long time.

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
common/rfb/VNCServerST.cxx
common/rfb/VNCServerST.h

index f0cfc31a2615c83922920836ba54789cfff78f05..bd29f243616d1cd1dd385f37c17d9a8d2fd80242 100644 (file)
@@ -83,6 +83,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
   : blHosts(&blacklist), desktop(desktop_), desktopStarted(false),
     blockCounter(0), pb(0), ledState(ledUnknown),
     name(name_), pointerClient(0), clipboardClient(0),
+    pointerClientTime(0),
     comparer(0), cursor(new Cursor(0, 0, Point(), NULL)),
     renderedCursorInvalid(false),
     keyRemapper(&KeyRemapper::defInstance),
@@ -484,14 +485,17 @@ void VNCServerST::keyEvent(uint32_t keysym, uint32_t keycode, bool down)
 void VNCServerST::pointerEvent(VNCSConnectionST* client,
                                const Point& pos, int buttonMask)
 {
+  time_t now = time(0);
   if (rfb::Server::maxIdleTime)
     idleTimer.start(secsToMillis(rfb::Server::maxIdleTime));
 
   // Let one client own the cursor whilst buttons are pressed in order
-  // to provide a bit more sane user experience
-  if ((pointerClient != NULL) && (pointerClient != client))
+  // to provide a bit more sane user experience. But limit the time to prevent
+  // locking out all others when e.g. the network is down.
+  if ((pointerClient != NULL) && (pointerClient != client) && ((now - pointerClientTime) < 3))
     return;
 
+  pointerClientTime = now;
   if (buttonMask)
     pointerClient = client;
   else
index 028903c9829be9df23a0ee7b195f6457c5ecac8d..f688b317ad39165bbf542a24d186e1975d8aa68a 100644 (file)
@@ -191,6 +191,8 @@ namespace rfb {
     std::list<VNCSConnectionST*> clipboardRequestors;
     std::list<network::Socket*> closingSockets;
 
+    time_t pointerClientTime;
+
     ComparingUpdateTracker* comparer;
 
     Point cursorPos;