#include "cocoa.h"
#endif
+#define EDGE_SCROLL_SIZE 32
+#define EDGE_SCROLL_SPEED 20
+
using namespace rfb;
static rfb::LogWriter vlog("DesktopWindow");
: 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
Fl::remove_timeout(handleGrab, this);
Fl::remove_timeout(handleResizeTimeout, this);
Fl::remove_timeout(handleFullscreenTimeout, this);
+ Fl::remove_timeout(handleEdgeScroll, this);
OptionsDialog::removeCallback(handleOptions);
case FL_FULLSCREEN:
fullScreen.setParam(fullscreen_active());
+ if (fullscreen_active())
+ scroll->type(0);
+ else
+ scroll->type(Fl_Scroll::BOTH);
+
if (!fullscreenSystemKeys)
break;
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...
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
+}