From: Selene ToyKeeper Date: Fri, 30 Apr 2021 14:34:17 +0000 (-0600) Subject: made full-screen edge scrolling smoother and faster X-Git-Tag: v1.11.90~30^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F1242%2Fhead;p=tigervnc.git made full-screen edge scrolling smoother and faster The old method used a very slow frame rate with small steps, which made it obnoxious during use. The new method has a few improvements: - Calculates "edge" region width automatically, as a ratio of the viewport size. Default is 1/16th. - Uses a different edge width for x and y, which works better on very wide or very tall screens. - Increased default frame rate from 10 fps to 60 fps. - Replaced hardcoded frame rate with a #define. - Reduced maximum movement per frame slightly, because the frame rate is so much faster. The overall result is still much faster, but also easier to do small adjustments with. - Fixed off-by-one error in scroll rate calculation formula. Left/up scrolls were faster than down/right, but this is fixed. This makes it more comfortable to use TigerVNC on a small screen to work on a larger screen for hours at a time. --- diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx index 5401b191..dddd74d7 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -54,8 +54,18 @@ #include #endif -#define EDGE_SCROLL_SIZE 32 -#define EDGE_SCROLL_SPEED 20 +// width of each "edge" region where scrolling happens, +// as a ratio compared to the viewport size +// default: 1/16th of the viewport size +#define EDGE_SCROLL_SIZE 16 +// edge width is calculated at runtime; these values are just examples +static int edge_scroll_size_x = 128; +static int edge_scroll_size_y = 96; +// maximum pixels to scroll per frame +#define EDGE_SCROLL_SPEED 16 +// how long to wait between viewport scroll position changes +// default: roughly 60 fps for smooth motion +#define EDGE_SCROLL_SECONDS_PER_FRAME 0.016666 using namespace rfb; @@ -768,12 +778,16 @@ int DesktopWindow::handle(int event) } } 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))) { + // calculate width of "edge" regions + edge_scroll_size_x = viewport->w() / EDGE_SCROLL_SIZE; + edge_scroll_size_y = viewport->h() / EDGE_SCROLL_SIZE; + // if cursor is near the edge of the viewport, scroll + if (((viewport->x() < 0) && (Fl::event_x() < edge_scroll_size_x)) || + ((viewport->x() + viewport->w() >= w()) && (Fl::event_x() >= w() - edge_scroll_size_x)) || + ((viewport->y() < 0) && (Fl::event_y() < edge_scroll_size_y)) || + ((viewport->y() + viewport->h() >= h()) && (Fl::event_y() >= h() - edge_scroll_size_y))) { if (!Fl::has_timeout(handleEdgeScroll, this)) - Fl::add_timeout(0.1, handleEdgeScroll, this); + Fl::add_timeout(EDGE_SCROLL_SECONDS_PER_FRAME, handleEdgeScroll, this); } } // Continue processing so that the viewport also gets mouse events @@ -1408,27 +1422,27 @@ void DesktopWindow::handleEdgeScroll(void *data) if (my > self->h()) my = self->h(); - if ((self->viewport->x() < 0) && (mx < EDGE_SCROLL_SIZE)) + if ((self->viewport->x() < 0) && (mx < edge_scroll_size_x)) 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)) + EDGE_SCROLL_SPEED * mx / edge_scroll_size_x; + if ((self->viewport->x() + self->viewport->w() >= self->w()) && + (mx >= self->w() - edge_scroll_size_x)) + dx = EDGE_SCROLL_SPEED * (self->w() - mx) / edge_scroll_size_x - + EDGE_SCROLL_SPEED - 1; + if ((self->viewport->y() < 0) && (my < edge_scroll_size_y)) 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; + EDGE_SCROLL_SPEED * my / edge_scroll_size_y; + if ((self->viewport->y() + self->viewport->h() >= self->h()) && + (my >= self->h() - edge_scroll_size_y)) + dy = EDGE_SCROLL_SPEED * (self->h() - my) / edge_scroll_size_y - + EDGE_SCROLL_SPEED - 1; if ((dx == 0) && (dy == 0)) return; self->scrollTo(self->hscroll->value() - dx, self->vscroll->value() - dy); - Fl::repeat_timeout(0.1, handleEdgeScroll, data); + Fl::repeat_timeout(EDGE_SCROLL_SECONDS_PER_FRAME, handleEdgeScroll, data); } void DesktopWindow::handleStatsTimeout(void *data)