diff options
author | Pierre Ossman <ossman@cendio.se> | 2025-02-06 13:42:44 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2025-02-06 13:42:44 +0100 |
commit | 03ebc9b180429b219b73acdf33fd8dc6f9258851 (patch) | |
tree | 6e970a7c54a0b74f54c72b60e726c84970eb2933 /vncviewer | |
parent | 299e6177f4ba770433db04f5fe3a308cecca637c (diff) | |
parent | a1fad72e9ea49c3666cfc81698967100c9f66a05 (diff) | |
download | tigervnc-03ebc9b180429b219b73acdf33fd8dc6f9258851.tar.gz tigervnc-03ebc9b180429b219b73acdf33fd8dc6f9258851.zip |
Merge branch 'resize' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'vncviewer')
-rw-r--r-- | vncviewer/CConn.cxx | 22 | ||||
-rw-r--r-- | vncviewer/CConn.h | 1 | ||||
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 106 | ||||
-rw-r--r-- | vncviewer/DesktopWindow.h | 11 |
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; |