diff options
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 83 | ||||
-rw-r--r-- | vncviewer/DesktopWindow.h | 4 |
2 files changed, 86 insertions, 1 deletions
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index d6c31e1b..ef5ec005 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -46,6 +46,9 @@ #include "cocoa.h" #endif +#define EDGE_SCROLL_SIZE 32 +#define EDGE_SCROLL_SPEED 20 + using namespace rfb; static rfb::LogWriter vlog("DesktopWindow"); @@ -56,7 +59,7 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name, : Fl_Window(w, h), cc(cc_), firstUpdate(true), delayedFullscreen(false), delayedDesktopSize(false) { - Fl_Scroll *scroll = new Fl_Scroll(0, 0, w, h); + scroll = new Fl_Scroll(0, 0, w, h); scroll->color(FL_BLACK); // Automatically adjust the scroll box to the window @@ -164,6 +167,7 @@ DesktopWindow::~DesktopWindow() Fl::remove_timeout(handleGrab, this); Fl::remove_timeout(handleResizeTimeout, this); Fl::remove_timeout(handleFullscreenTimeout, this); + Fl::remove_timeout(handleEdgeScroll, this); OptionsDialog::removeCallback(handleOptions); @@ -308,6 +312,11 @@ int DesktopWindow::handle(int event) case FL_FULLSCREEN: fullScreen.setParam(fullscreen_active()); + if (fullscreen_active()) + scroll->type(0); + else + scroll->type(Fl_Scroll::BOTH); + if (!fullscreenSystemKeys) break; @@ -317,7 +326,23 @@ int DesktopWindow::handle(int event) ungrabKeyboard(); break; + + case FL_ENTER: + case FL_LEAVE: + case FL_DRAG: + case FL_MOVE: + if (fullscreen_active()) { + if (((viewport->x() < 0) && (Fl::event_x() < EDGE_SCROLL_SIZE)) || + ((viewport->x() + viewport->w() > w()) && (Fl::event_x() > w() - EDGE_SCROLL_SIZE)) || + ((viewport->y() < 0) && (Fl::event_y() < EDGE_SCROLL_SIZE)) || + ((viewport->y() + viewport->h() > h()) && (Fl::event_y() > h() - EDGE_SCROLL_SIZE))) { + if (!Fl::has_timeout(handleEdgeScroll, this)) + Fl::add_timeout(0.1, handleEdgeScroll, this); + } + } + return 1; #endif + case FL_SHORTCUT: // Sometimes the focus gets out of whack and we fall through to the // shortcut dispatching. Try to make things sane again... @@ -773,3 +798,59 @@ void DesktopWindow::handleFullscreenTimeout(void *data) self->delayedDesktopSize = false; } } + +void DesktopWindow::handleEdgeScroll(void *data) +{ +#ifdef HAVE_FLTK_FULLSCREEN + DesktopWindow *self = (DesktopWindow *)data; + + int mx, my; + int dx, dy; + + assert(self); + + if (!self->fullscreen_active()) + return; + + mx = Fl::event_x(); + my = Fl::event_y(); + + dx = dy = 0; + + // Clamp mouse position in case it is outside the window + if (mx < 0) + mx = 0; + if (mx > self->w()) + mx = self->w(); + if (my < 0) + my = 0; + if (my > self->h()) + my = self->h(); + + if ((self->viewport->x() < 0) && (mx < EDGE_SCROLL_SIZE)) + dx = EDGE_SCROLL_SPEED - EDGE_SCROLL_SPEED * mx / EDGE_SCROLL_SIZE; + if ((self->viewport->x() + self->viewport->w() > self->w()) && (mx > self->w() - EDGE_SCROLL_SIZE)) + dx = EDGE_SCROLL_SPEED * (self->w() - mx) / EDGE_SCROLL_SIZE - EDGE_SCROLL_SPEED; + if ((self->viewport->y() < 0) && (my < EDGE_SCROLL_SIZE)) + dy = EDGE_SCROLL_SPEED - EDGE_SCROLL_SPEED * my / EDGE_SCROLL_SIZE; + if ((self->viewport->y() + self->viewport->h() > self->h()) && (my > self->h() - EDGE_SCROLL_SIZE)) + dy = EDGE_SCROLL_SPEED * (self->h() - my) / EDGE_SCROLL_SIZE - EDGE_SCROLL_SPEED; + + if ((dx == 0) && (dy == 0)) + return; + + // Make sure we don't move the viewport too much + if (self->viewport->x() + dx > 0) + dx = -self->viewport->x(); + if (self->viewport->x() + dx + self->viewport->w() < self->w()) + dx = self->w() - (self->viewport->x() + self->viewport->w()); + if (self->viewport->y() + dy > 0) + dy = -self->viewport->y(); + if (self->viewport->y() + dy + self->viewport->h() < self->h()) + dy = self->h() - (self->viewport->y() + self->viewport->h()); + + self->scroll->scroll_to(self->scroll->xposition() - dx, self->scroll->yposition() - dy); + + Fl::repeat_timeout(0.1, handleEdgeScroll, data); +#endif +} diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h index 81d29300..78d9bf79 100644 --- a/vncviewer/DesktopWindow.h +++ b/vncviewer/DesktopWindow.h @@ -30,6 +30,7 @@ #include <FL/Fl_Window.H> class CConn; +class Fl_Scroll; class DesktopWindow : public Fl_Window { public: @@ -102,8 +103,11 @@ private: static void handleFullscreenTimeout(void *data); + static void handleEdgeScroll(void *data); + private: CConn* cc; + Fl_Scroll *scroll; Viewport *viewport; bool firstUpdate; |