]> source.dussan.org Git - tigervnc.git/commitdiff
vncviewer: Fix scrollbar visibility 466/head
authorLuke Shumaker <lukeshu@lukeshu.com>
Tue, 23 May 2017 18:03:15 +0000 (14:03 -0400)
committerLuke Shumaker <lukeshu@lukeshu.com>
Wed, 24 May 2017 22:35:37 +0000 (18:35 -0400)
Have a window that is sized to the remote screen.  Now shrink the window
vertically, making it shorter than the remote screen in one axis. The
vertical scrollbar appears. However, the horizontal scrollbar does not
appear, despite the rightmost ~24 pixels (Fl::scrollbar_size()) being
hidden by the vertical scroll bar.

Fix that.

For clarity, move the fullscreen checks into a separate `if` statement,
rather than keeping the size and fullscreen checks together.

I think the comment does a decent job of explaining and justifying the
check's logic, but if you require further convincing, perhaps this
alternate explanation will help:

  The check for the X-axis is

      if ((w() - (h() < viewport->h() ? Fl::scrollbar_size() : 0) < viewport->w())

  To be a bit more verbose and repetitive, we can split that ternary in to
  two separate checks, and add some comments:

      if (
             (w() -  < viewport->w()) // X needs a scrollbar
          ||
             ( (w() - Fl::scrollbar_size() < viewport->w()) && (h() < viewport->h()) )
             //( X doesn't need a scrollbar unless Y does ) && (  Y does need one  ) )
         )

  Within the "Y does need one" check, we don't need to worry about the
  case where `h() - Fl::scrollbar_size() < viewport-h()` is true,
  because if both axes are saying "I don't need a scrollbar unless
  you do", then neither needs one.

vncviewer/DesktopWindow.cxx

index 47fe8f8935adaf2ede09734765a5031e54db709b..e2ed08879958ede1864a64a75694002839777c75 100644 (file)
@@ -1046,15 +1046,35 @@ void DesktopWindow::repositionWidgets()
 
   // Scrollbars visbility
 
-  if (!fullscreen_active() && (w() < viewport->w()))
-    hscroll->show();
-  else
+  if (fullscreen_active()) {
     hscroll->hide();
-
-  if (!fullscreen_active() && (h() < viewport->h()))
-    vscroll->show();
-  else
     vscroll->hide();
+  } else {
+    // Decide whether to show a scrollbar by checking if the window
+    // size (possibly minus scrollbar_size) is less than the viewport
+    // (remote framebuffer) size.
+    //
+    // We decide whether to subtract scrollbar_size on an axis by
+    // checking if the other axis *definitely* needs a scrollbar.  You
+    // might be tempted to think that this becomes a weird recursive
+    // problem, but it isn't: If the window size is less than the
+    // viewport size (without subtracting the scrollbar_size), then
+    // that axis *definitely* needs a scrollbar; if the check changes
+    // when we subtract scrollbar_size, then that axis only *maybe*
+    // needs a scrollbar.  If both axes only "maybe" need a scrollbar,
+    // then neither does; so we don't need to recurse on the "maybe"
+    // cases.
+
+    if (w() - (h() < viewport->h() ? Fl::scrollbar_size() : 0) < viewport->w())
+      hscroll->show();
+    else
+      hscroll->hide();
+
+    if (h() - (w() < viewport->w() ? Fl::scrollbar_size() : 0) < viewport->h())
+      vscroll->show();
+    else
+      vscroll->hide();
+  }
 
   // Scrollbars positions