Skip to content

Commit

Permalink
VNCServerST: Add a timeout to pointer button ownership
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
MikeLooijmans committed Jan 16, 2024
1 parent 986280b commit ad1d39c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
20 changes: 14 additions & 6 deletions common/rfb/VNCServerST.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -488,14 +489,21 @@ void VNCServerST::pointerEvent(VNCSConnectionST* client,
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))
return;
// 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) {
time_t now = time(0);

if (buttonMask)
pointerClient = client;
else
if ((pointerClient != client) && (now - pointerClientTime) < 3)
return;

if (buttonMask) {
pointerClient = client;
pointerClientTime = now;
}
} else {
pointerClient = NULL;
}

desktop->pointerEvent(pos, buttonMask);
}
Expand Down
2 changes: 2 additions & 0 deletions common/rfb/VNCServerST.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ namespace rfb {
std::list<VNCSConnectionST*> clipboardRequestors;
std::list<network::Socket*> closingSockets;

time_t pointerClientTime;

ComparingUpdateTracker* comparer;

Point cursorPos;
Expand Down

0 comments on commit ad1d39c

Please sign in to comment.