Explicitly check screen layout after change
There are some cases where the server state will not automatically
be updated on a change. A prominent one is when only RFB attributes
were changes (e.g. the screen ID) but nothing else. In that case
there is no actual change in the X server, so it never sends any
notification about change back to us.
diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx
index d8360ab..c7961f2 100644
--- a/unix/x0vncserver/XDesktop.cxx
+++ b/unix/x0vncserver/XDesktop.cxx
@@ -567,11 +567,14 @@
VNCSConnectionST::setDesktopSize. Another ExtendedDesktopSize
with reason=0 will be sent in response to the changes seen by the
event handler. */
- if (adjustedLayout != layout) {
+ if (adjustedLayout != layout)
return rfb::resultInvalid;
- } else {
- return ret;
- }
+
+ // Explicitly update the server state with the result as there
+ // can be corner cases where we don't get feedback from the X server
+ server->setScreenLayout(computeScreenLayout());
+
+ return ret;
#else
return rfb::resultProhibited;
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index 4aac765..7eaf3f9 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -557,6 +557,8 @@
unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height,
const rfb::ScreenSet& layout)
{
+ unsigned int result;
+
char buffer[2048];
vlog.debug("Got request for framebuffer resize to %dx%d",
fb_width, fb_height);
@@ -564,7 +566,13 @@
vlog.debug("%s", buffer);
vncSetGlueContext(screenIndex);
- return ::setScreenLayout(fb_width, fb_height, layout, &outputIdMap);
+ result = ::setScreenLayout(fb_width, fb_height, layout, &outputIdMap);
+
+ // Explicitly update the server state with the result as there
+ // can be corner cases where we don't get feedback from the X core
+ refreshScreenLayout();
+
+ return result;
}
void XserverDesktop::grabRegion(const rfb::Region& region)