1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/renderer/webscrollbarbehavior_impl_gtkoraura.h"
6
7#include "third_party/WebKit/public/platform/WebPoint.h"
8#include "third_party/WebKit/public/platform/WebRect.h"
9
10namespace content {
11
12bool WebScrollbarBehaviorImpl::shouldCenterOnThumb(
13      blink::WebScrollbarBehavior::Button mouseButton,
14      bool shiftKeyPressed,
15      bool altKeyPressed) {
16#if (defined(OS_LINUX) && !defined(OS_CHROMEOS))
17  if (mouseButton == blink::WebScrollbarBehavior::ButtonMiddle)
18    return true;
19#endif
20  return (mouseButton == blink::WebScrollbarBehavior::ButtonLeft) &&
21      shiftKeyPressed;
22}
23
24bool WebScrollbarBehaviorImpl::shouldSnapBackToDragOrigin(
25    const blink::WebPoint& eventPoint,
26    const blink::WebRect& scrollbarRect,
27    bool isHorizontal) {
28  // Constants used to figure the drag rect outside which we should snap the
29  // scrollbar thumb back to its origin. These calculations are based on
30  // observing the behavior of the MSVC8 main window scrollbar + some
31  // guessing/extrapolation.
32  static const int kOffEndMultiplier = 3;
33  static const int kOffSideMultiplier = 8;
34  static const int kDefaultWinScrollbarThickness = 17;
35
36  // Find the rect within which we shouldn't snap, by expanding the track rect
37  // in both dimensions.
38  gfx::Rect noSnapRect(scrollbarRect);
39  int thickness = isHorizontal ? noSnapRect.height() : noSnapRect.width();
40  // Even if the platform's scrollbar is narrower than the default Windows one,
41  // we still want to provide at least as much slop area, since a slightly
42  // narrower scrollbar doesn't necessarily imply that users will drag
43  // straighter.
44  thickness = std::max(thickness, kDefaultWinScrollbarThickness);
45  noSnapRect.Inset(
46      (isHorizontal ? kOffEndMultiplier : kOffSideMultiplier) * -thickness,
47      (isHorizontal ? kOffSideMultiplier : kOffEndMultiplier) * -thickness);
48
49  // On most platforms, we should snap iff the event is outside our calculated
50  // rect.  On Linux, however, we should not snap for events off the ends, but
51  // not the sides, of the rect.
52#if (defined(OS_LINUX) && !defined(OS_CHROMEOS))
53  return isHorizontal ?
54      (eventPoint.y < noSnapRect.y() || eventPoint.y >= noSnapRect.bottom()) :
55      (eventPoint.x < noSnapRect.x() || eventPoint.x >= noSnapRect.right());
56#else
57  return !noSnapRect.Contains(eventPoint);
58#endif
59}
60
61}  // namespace content
62