Revision: 4924 http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4924&view=rev Author: ossman_ Date: 2012-07-04 11:27:47 +0000 (Wed, 04 Jul 2012) Log Message: ----------- Make it possible to dynamically resize the size of the session, when resizing the viewer window, or when entering or leaving fullscreen mode. Initial work done by Arthur Huillet and clohr.
Modified Paths: -------------- trunk/vncviewer/CConn.cxx trunk/vncviewer/DesktopWindow.cxx trunk/vncviewer/DesktopWindow.h trunk/vncviewer/parameters.cxx trunk/vncviewer/parameters.h Modified: trunk/vncviewer/CConn.cxx =================================================================== --- trunk/vncviewer/CConn.cxx 2012-07-04 11:10:46 UTC (rev 4923) +++ trunk/vncviewer/CConn.cxx 2012-07-04 11:27:47 UTC (rev 4924) @@ -304,43 +304,11 @@ desktop->updateWindow(); if (firstUpdate) { - int width, height; - // We need fences to make extra update requests and continuous // updates "safe". See fence() for the next step. if (cp.supportsFence) writer()->writeFence(fenceFlagRequest | fenceFlagSyncNext, 0, NULL); - if (cp.supportsSetDesktopSize && - sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) == 2) { - ScreenSet layout; - - layout = cp.screenLayout; - - if (layout.num_screens() == 0) - layout.add_screen(rfb::Screen()); - else if (layout.num_screens() != 1) { - ScreenSet::iterator iter; - - while (true) { - iter = layout.begin(); - ++iter; - - if (iter == layout.end()) - break; - - layout.remove_screen(iter->id); - } - } - - layout.begin()->dimensions.tl.x = 0; - layout.begin()->dimensions.tl.y = 0; - layout.begin()->dimensions.br.x = width; - layout.begin()->dimensions.br.y = height; - - writer()->writeSetDesktopSize(width, height, layout); - } - firstUpdate = false; } Modified: trunk/vncviewer/DesktopWindow.cxx =================================================================== --- trunk/vncviewer/DesktopWindow.cxx 2012-07-04 11:10:46 UTC (rev 4923) +++ trunk/vncviewer/DesktopWindow.cxx 2012-07-04 11:27:47 UTC (rev 4924) @@ -26,12 +26,14 @@ #include <string.h> #include <rfb/LogWriter.h> +#include <rfb/CMsgWriter.h> #include "DesktopWindow.h" #include "OptionsDialog.h" #include "i18n.h" #include "parameters.h" #include "vncviewer.h" +#include "CConn.h" #include <FL/Fl_Scroll.H> #include <FL/x.H> @@ -51,18 +53,15 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name, const rfb::PixelFormat& serverPF, CConn* cc_) - : Fl_Window(w, h) + : Fl_Window(w, h), cc(cc_), firstUpdate(true) { - // Allow resize - size_range(100, 100, w, h); - Fl_Scroll *scroll = new Fl_Scroll(0, 0, w, h); scroll->color(FL_BLACK); // Automatically adjust the scroll box to the window resizable(scroll); - viewport = new Viewport(w, h, serverPF, cc_); + viewport = new Viewport(w, h, serverPF, cc); scroll->end(); @@ -76,11 +75,9 @@ Fl::event_dispatch(&fltkHandle); #ifdef HAVE_FLTK_FULLSCREEN - if (fullScreen) { - // See comment in DesktopWindow::handleOptions - size_range(100, 100, 0, 0); + if (fullScreen) fullscreen(); - } else + else #endif { // If we are creating a window which is equal to the size on the @@ -106,6 +103,7 @@ // Unregister all timeouts in case they get a change tro trigger // again later when this object is already gone. Fl::remove_timeout(handleGrab, this); + Fl::remove_timeout(handleResizeTimeout, this); OptionsDialog::removeCallback(handleOptions); @@ -149,6 +147,12 @@ void DesktopWindow::updateWindow() { + if (firstUpdate) { + if (cc->cp.supportsSetDesktopSize) + remoteResize(); + firstUpdate = false; + } + viewport->updateWindow(); } @@ -158,9 +162,6 @@ if ((new_w == viewport->w()) && (new_h == viewport->h())) return; - // Turn off size limitations for a bit while we juggle things around - size_range(100, 100, 0, 0); - // If we're letting the viewport match the window perfectly, then // keep things that way for the new size, otherwise just keep things // like they are. @@ -186,12 +187,6 @@ // to make sure the viewport is centered. repositionViewport(); - // Update allowed resize range -#ifdef HAVE_FLTK_FULLSCREEN - if (!fullscreen_active()) -#endif - size_range(100, 100, new_w, new_h); - // repositionViewport() makes sure the scroll widget notices any changes // in position, but it might be just the size that changes so we also // need a poke here as well. @@ -210,6 +205,20 @@ { Fl_Window::resize(x, y, w, h); + // 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 + // + if (not firstUpdate 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); + Fl::add_timeout(0.5, handleResizeTimeout, this); + } + // Deal with some scrolling corner cases repositionViewport(); } @@ -222,18 +231,6 @@ case FL_FULLSCREEN: fullScreen.setParam(fullscreen_active()); - if (!fullscreen_active()) { - size_range(100, 100, viewport->w(), viewport->h()); - size(viewport->w(), viewport->h()); - } else { - // We need to turn off the size limitations for proper - // fullscreen support, but in case fullscreen is activated via - // the WM, this is a bit of a problem. In practice, it seems to - // work to change the size limits after we have recieved the - // FL_FULLSCREEN event, at least with my Metacity. - size_range(100, 100, 0, 0); - } - if (!fullscreenSystemKeys) break; @@ -383,6 +380,65 @@ } +void DesktopWindow::handleResizeTimeout(void *data) +{ + DesktopWindow *self = (DesktopWindow *)data; + + assert(self); + + self->remoteResize(); +} + + +void DesktopWindow::remoteResize() +{ + int width, height; + ScreenSet layout; + + if (firstUpdate) { + if (sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) != 2) + return; + } else { + width = w(); + height = h(); + } + + layout = cc->cp.screenLayout; + + if (layout.num_screens() == 0) + layout.add_screen(rfb::Screen()); + else if (layout.num_screens() != 1) { + ScreenSet::iterator iter; + + while (true) { + iter = layout.begin(); + ++iter; + + if (iter == layout.end()) + break; + + layout.remove_screen(iter->id); + } + } + + layout.begin()->dimensions.tl.x = 0; + layout.begin()->dimensions.tl.y = 0; + layout.begin()->dimensions.br.x = width; + layout.begin()->dimensions.br.y = height; + + // Do we actually change anything? + if ((width == cc->cp.width) && + (height == cc->cp.height) && + (layout == cc->cp.screenLayout)) + return; + + vlog.debug("Requesting framebuffer resize from %dx%d to %dx%d", + cc->cp.width, cc->cp.height, width, height); + + cc->writer()->writeSetDesktopSize(width, height, layout); +} + + void DesktopWindow::repositionViewport() { int new_x, new_y; @@ -442,12 +498,9 @@ else self->ungrabKeyboard(); - if (fullScreen && !self->fullscreen_active()) { - // Some WMs (Metacity) apparently requires that the size limits - // are removed before fullscreen - self->size_range(100, 100, 0, 0); + if (fullScreen && !self->fullscreen_active()) self->fullscreen(); - } else if (!fullScreen && self->fullscreen_active()) + else if (!fullScreen && self->fullscreen_active()) self->fullscreen_off(); #endif } Modified: trunk/vncviewer/DesktopWindow.h =================================================================== --- trunk/vncviewer/DesktopWindow.h 2012-07-04 11:10:46 UTC (rev 4923) +++ trunk/vncviewer/DesktopWindow.h 2012-07-04 11:27:47 UTC (rev 4924) @@ -86,6 +86,9 @@ static void handleGrab(void *data); + static void handleResizeTimeout(void *data); + void remoteResize(); + void repositionViewport(); static void handleClose(Fl_Widget *wnd, void *data); @@ -93,7 +96,10 @@ static void handleOptions(void *data); private: + CConn* cc; Viewport *viewport; + + bool firstUpdate; }; #endif Modified: trunk/vncviewer/parameters.cxx =================================================================== --- trunk/vncviewer/parameters.cxx 2012-07-04 11:10:46 UTC (rev 4923) +++ trunk/vncviewer/parameters.cxx 2012-07-04 11:27:47 UTC (rev 4924) @@ -68,6 +68,10 @@ StringParameter desktopSize("DesktopSize", "Reconfigure desktop size on the server on " "connect (if possible)", ""); +BoolParameter remoteResize("RemoteResize", + "Dynamically resize the remote desktop size as " + "the size of the local client window changes. " + "(Does not work with all servers)", true); BoolParameter viewOnly("ViewOnly", "Don't send any mouse or keyboard events to the server", Modified: trunk/vncviewer/parameters.h =================================================================== --- trunk/vncviewer/parameters.h 2012-07-04 11:10:46 UTC (rev 4923) +++ trunk/vncviewer/parameters.h 2012-07-04 11:27:47 UTC (rev 4924) @@ -39,6 +39,7 @@ extern rfb::BoolParameter fullScreen; extern rfb::StringParameter desktopSize; +extern rfb::BoolParameter remoteResize; extern rfb::BoolParameter viewOnly; extern rfb::BoolParameter shared; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Tigervnc-commits mailing list Tigervnc-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-commits