aboutsummaryrefslogtreecommitdiffstats
path: root/vncviewer
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2025-02-06 13:42:44 +0100
committerPierre Ossman <ossman@cendio.se>2025-02-06 13:42:44 +0100
commit03ebc9b180429b219b73acdf33fd8dc6f9258851 (patch)
tree6e970a7c54a0b74f54c72b60e726c84970eb2933 /vncviewer
parent299e6177f4ba770433db04f5fe3a308cecca637c (diff)
parenta1fad72e9ea49c3666cfc81698967100c9f66a05 (diff)
downloadtigervnc-03ebc9b180429b219b73acdf33fd8dc6f9258851.tar.gz
tigervnc-03ebc9b180429b219b73acdf33fd8dc6f9258851.zip
Merge branch 'resize' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'vncviewer')
-rw-r--r--vncviewer/CConn.cxx22
-rw-r--r--vncviewer/CConn.h1
-rw-r--r--vncviewer/DesktopWindow.cxx106
-rw-r--r--vncviewer/DesktopWindow.h11
4 files changed, 69 insertions, 71 deletions
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index f8e80429..5f943640 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -35,9 +35,9 @@
#include <rfb/Hostname.h>
#include <rfb/LogWriter.h>
#include <rfb/Security.h>
-#include <rfb/screenTypes.h>
#include <rfb/fenceTypes.h>
#include <rfb/Timer.h>
+#include <rfb/screenTypes.h>
#include <network/TcpSocket.h>
#ifndef WIN32
#include <network/UnixSocket.h>
@@ -317,26 +317,14 @@ void CConn::initDone()
setPreferredEncoding(encNum);
}
-// setDesktopSize() is called when the desktop size changes (including when
-// it is set initially).
-void CConn::setDesktopSize(int w, int h)
-{
- CConnection::setDesktopSize(w,h);
- resizeFramebuffer();
-}
-
-// setExtendedDesktopSize() is a more advanced version of setDesktopSize()
void CConn::setExtendedDesktopSize(unsigned reason, unsigned result,
- int w, int h, const rfb::ScreenSet& layout)
+ int w, int h,
+ const rfb::ScreenSet& layout)
{
CConnection::setExtendedDesktopSize(reason, result, w, h, layout);
- if ((reason == reasonClient) && (result != resultSuccess)) {
- vlog.error(_("SetDesktopSize failed: %d"), result);
- return;
- }
-
- resizeFramebuffer();
+ if (reason == reasonClient)
+ desktop->setDesktopSizeDone(result);
}
// setName() is called when the desktop name changes
diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h
index a7b9afda..e830ecaa 100644
--- a/vncviewer/CConn.h
+++ b/vncviewer/CConn.h
@@ -57,7 +57,6 @@ public:
void initDone() override;
- void setDesktopSize(int w, int h) override;
void setExtendedDesktopSize(unsigned reason, unsigned result,
int w, int h,
const rfb::ScreenSet& layout) override;
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 33ff890c..1ca67ba1 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -83,7 +83,8 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name,
CConn* cc_)
: Fl_Window(w, h), cc(cc_), offscreen(nullptr), overlay(nullptr),
firstUpdate(true),
- delayedFullscreen(false), delayedDesktopSize(false),
+ delayedFullscreen(false), sentDesktopSize(false),
+ pendingRemoteResize(false), lastResize({0, 0}),
keyboardGrabbed(false), mouseGrabbed(false),
statsLastUpdates(0), statsLastPixels(0), statsLastPosition(0),
statsGraph(nullptr)
@@ -339,15 +340,8 @@ void DesktopWindow::setName(const char *name)
void DesktopWindow::updateWindow()
{
if (firstUpdate) {
- if (cc->server.supportsSetDesktopSize) {
- // Hack: Wait until we're in the proper mode and position until
- // resizing things, otherwise we might send the wrong thing.
- if (delayedFullscreen)
- delayedDesktopSize = true;
- else
- handleDesktopSize();
- }
firstUpdate = false;
+ remoteResize();
}
viewport->updateWindow();
@@ -410,6 +404,19 @@ void DesktopWindow::resizeFramebuffer(int new_w, int new_h)
}
+void DesktopWindow::setDesktopSizeDone(unsigned result)
+{
+ pendingRemoteResize = false;
+
+ if (result != 0)
+ return;
+
+ // We might have resized again whilst waiting for the previous
+ // request, so check if we are in sync
+ remoteResize();
+}
+
+
void DesktopWindow::setCursor(int width, int height,
const rfb::Point& hotspot,
const uint8_t* data)
@@ -697,21 +704,7 @@ void DesktopWindow::resize(int x, int y, int w, int h)
Fl_Window::resize(x, y, w, h);
if (resizing) {
- // Try to get the remote size to match our window size, provided
- // the following conditions are true:
- //
- // a) The user has this feature turned on
- // b) The server supports it
- // c) We're not still waiting for a chance to handle DesktopSize
- // d) We're not still waiting for startup fullscreen to kick in
- //
- if (not firstUpdate and not delayedFullscreen and
- ::remoteResize and cc->server.supportsSetDesktopSize) {
- // We delay updating the remote desktop as we tend to get a flood
- // of resize events as the user is dragging the window.
- Fl::remove_timeout(handleResizeTimeout, this);
- Fl::add_timeout(0.5, handleResizeTimeout, this);
- }
+ remoteResize();
repositionWidgets();
}
@@ -1290,32 +1283,13 @@ void DesktopWindow::maximizeWindow()
}
-void DesktopWindow::handleDesktopSize()
-{
- if (strcmp(desktopSize, "") != 0) {
- int width, height;
-
- // An explicit size has been requested
-
- if (sscanf(desktopSize, "%dx%d", &width, &height) != 2)
- return;
-
- remoteResize(width, height);
- } else if (::remoteResize) {
- // No explicit size, but remote resizing is on so make sure it
- // matches whatever size the window ended up being
- remoteResize(w(), h());
- }
-}
-
-
void DesktopWindow::handleResizeTimeout(void *data)
{
DesktopWindow *self = (DesktopWindow *)data;
assert(self);
- self->remoteResize(self->w(), self->h());
+ self->remoteResize();
}
@@ -1330,14 +1304,48 @@ void DesktopWindow::reconfigureFullscreen(void* /*data*/)
}
-void DesktopWindow::remoteResize(int width, int height)
+void DesktopWindow::remoteResize()
{
+ int width, height;
ScreenSet layout;
ScreenSet::const_iterator iter;
if (viewOnly)
return;
+ if (!::remoteResize)
+ return;
+ if (!cc->server.supportsSetDesktopSize)
+ return;
+
+ // Don't pester the server with a resize until we have our final size
+ if (delayedFullscreen)
+ return;
+
+ // Rate limit to one pending resize at a time
+ if (pendingRemoteResize)
+ return;
+
+ // And no more than once every 100ms
+ if (msSince(&lastResize) < 100) {
+ Fl::remove_timeout(handleResizeTimeout, this);
+ Fl::add_timeout((100.0 - msSince(&lastResize)) / 1000.0,
+ handleResizeTimeout, this);
+ return;
+ }
+
+ width = w();
+ height = h();
+
+ if (!sentDesktopSize && (strcmp(desktopSize, "") != 0)) {
+ // An explicit size has been requested
+
+ if (sscanf(desktopSize, "%dx%d", &width, &height) != 2)
+ return;
+
+ sentDesktopSize = true;
+ }
+
if (!fullscreen_active() || (width > w()) || (height > h())) {
// In windowed mode (or the framebuffer is so large that we need
// to scroll) we just report a single virtual screen that covers
@@ -1456,6 +1464,8 @@ void DesktopWindow::remoteResize(int width, int height)
vlog.debug("%s", buffer);
}
+ pendingRemoteResize = true;
+ gettimeofday(&lastResize, nullptr);
cc->writer()->writeSetDesktopSize(width, height, layout);
}
@@ -1576,11 +1586,7 @@ void DesktopWindow::handleFullscreenTimeout(void *data)
assert(self);
self->delayedFullscreen = false;
-
- if (self->delayedDesktopSize) {
- self->handleDesktopSize();
- self->delayedDesktopSize = false;
- }
+ self->remoteResize();
}
void DesktopWindow::scrollTo(int x, int y)
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index ce7960ce..97c3c00d 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -55,6 +55,9 @@ public:
// Resize the current framebuffer, but retain the contents
void resizeFramebuffer(int new_w, int new_h);
+ // A previous call to writeSetDesktopSize() has completed
+ void setDesktopSizeDone(unsigned result);
+
// New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,
const uint8_t* data);
@@ -101,10 +104,9 @@ private:
void maximizeWindow();
- void handleDesktopSize();
static void handleResizeTimeout(void *data);
static void reconfigureFullscreen(void *data);
- void remoteResize(int width, int height);
+ void remoteResize();
void repositionWidgets();
@@ -131,7 +133,10 @@ private:
bool firstUpdate;
bool delayedFullscreen;
- bool delayedDesktopSize;
+ bool sentDesktopSize;
+
+ bool pendingRemoteResize;
+ struct timeval lastResize;
bool keyboardGrabbed;
bool mouseGrabbed;