From: Pierre Ossman Date: Thu, 23 Aug 2012 14:53:36 +0000 (+0000) Subject: X11 window managers are very buggy when it comes to having a window start X-Git-Tag: v1.2.90~127 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4c4b66f1a0de2d56506050829645f973902b573f;p=tigervnc.git X11 window managers are very buggy when it comes to having a window start in full screen mode. So we'll resort to creating a normal window, and then switching to full screen once it is mapped. Unfortunately it means we need to handle delaying some resize handling. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4958 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index 0894275a..463adf36 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -53,7 +53,8 @@ static rfb::LogWriter vlog("DesktopWindow"); DesktopWindow::DesktopWindow(int w, int h, const char *name, const rfb::PixelFormat& serverPF, CConn* cc_) - : Fl_Window(w, h), cc(cc_), firstUpdate(true) + : Fl_Window(w, h), cc(cc_), firstUpdate(true), + delayedFullscreen(false), delayedDesktopSize(false) { Fl_Scroll *scroll = new Fl_Scroll(0, 0, w, h); scroll->color(FL_BLACK); @@ -75,9 +76,16 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name, Fl::event_dispatch(&fltkHandle); #ifdef HAVE_FLTK_FULLSCREEN - if (fullScreen) + if (fullScreen) { + // Hack: Window managers seem to be rather crappy at respecting + // fullscreen hints on initial windows. So on X11 we'll have to + // wait until after we've been mapped. +#if defined(WIN32) || defined(__APPLE__) fullscreen_on(); - else +#else + delayedFullscreen = true; +#endif + } else #endif { // If we are creating a window which is equal to the size on the @@ -102,6 +110,16 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name, // the scroll widget for things to behave sanely. if ((w != this->w()) || (h != this->h())) scroll->size(this->w(), this->h()); + +#ifdef HAVE_FLTK_FULLSCREEN + if (delayedFullscreen) { + // Hack: Fullscreen requests may be ignored, so we need a timeout for + // when we should stop waiting. We also really need to wait for the + // resize, which can come after the fullscreen event. + Fl::add_timeout(0.5, handleFullscreenTimeout, this); + fullscreen_on(); + } +#endif } @@ -111,6 +129,7 @@ DesktopWindow::~DesktopWindow() // again later when this object is already gone. Fl::remove_timeout(handleGrab, this); Fl::remove_timeout(handleResizeTimeout, this); + Fl::remove_timeout(handleFullscreenTimeout, this); OptionsDialog::removeCallback(handleOptions); @@ -155,8 +174,14 @@ void DesktopWindow::setColourMapEntries(int firstColour, int nColours, void DesktopWindow::updateWindow() { if (firstUpdate) { - if (cc->cp.supportsSetDesktopSize) - remoteResize(); + if (cc->cp.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; } @@ -226,8 +251,10 @@ void DesktopWindow::resize(int x, int y, int w, int h) // 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 ::remoteResize and cc->cp.supportsSetDesktopSize) { + if (not firstUpdate and not delayedFullscreen and + ::remoteResize and cc->cp.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); @@ -481,30 +508,32 @@ void DesktopWindow::maximizeWindow() } +void DesktopWindow::handleDesktopSize() +{ + int width, height; + + if (sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) != 2) + return; + + remoteResize(width, height); +} + + void DesktopWindow::handleResizeTimeout(void *data) { DesktopWindow *self = (DesktopWindow *)data; assert(self); - self->remoteResize(); + self->remoteResize(self->w(), self->h()); } -void DesktopWindow::remoteResize() +void DesktopWindow::remoteResize(int width, int height) { - int width, height; ScreenSet layout; ScreenSet::iterator iter; - if (firstUpdate) { - if (sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) != 2) - return; - } else { - width = w(); - height = h(); - } - #ifdef HAVE_FLTK_FULLSCREEN if (!fullscreen_active() || (width > w()) || (height > h())) { #endif @@ -690,3 +719,17 @@ void DesktopWindow::handleOptions(void *data) self->fullscreen_off(); #endif } + +void DesktopWindow::handleFullscreenTimeout(void *data) +{ + DesktopWindow *self = (DesktopWindow *)data; + + assert(self); + + self->delayedFullscreen = false; + + if (self->delayedDesktopSize) { + self->handleDesktopSize(); + self->delayedDesktopSize = false; + } +} diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h index 6008d067..81d29300 100644 --- a/vncviewer/DesktopWindow.h +++ b/vncviewer/DesktopWindow.h @@ -90,8 +90,9 @@ private: void maximizeWindow(); + void handleDesktopSize(); static void handleResizeTimeout(void *data); - void remoteResize(); + void remoteResize(int width, int height); void repositionViewport(); @@ -99,11 +100,15 @@ private: static void handleOptions(void *data); + static void handleFullscreenTimeout(void *data); + private: CConn* cc; Viewport *viewport; bool firstUpdate; + bool delayedFullscreen; + bool delayedDesktopSize; }; #endif