[GTK] clicking on the scrollbar trough steps rather than jumps to the clicked position
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Feb 2016 09:50:26 +0000 (09:50 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Feb 2016 09:50:26 +0000 (09:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=115363

Reviewed by Michael Catanzaro.

Allow ScrollbarTheme to decide the behavior of a button press event,
instead of only deciding whether to center on thumb or not. This
way we can match the current GTK+ behavior in WebKit, without
affecting other ports.

* platform/ScrollTypes.h: Add ScrollbarButtonPressAction enum.
* platform/Scrollbar.cpp:
(WebCore::Scrollbar::mouseDown): Ask ScrollbarTheme to handle the
event for the pressed part and do the requested action.
* platform/ScrollbarTheme.cpp:
(WebCore::ScrollbarTheme::handleMousePressEvent): Add default
implementation. It's equivalent to the previous default implementation.
* platform/ScrollbarTheme.h:
* platform/gtk/ScrollbarThemeGtk.cpp:
(WebCore::ScrollbarThemeGtk::handleMousePressEvent): Match current
GTK+ behavior: left click centers on thumb and right click
scrolls. Dragging the thumb works for left and middle buttons.
* platform/gtk/ScrollbarThemeGtk.h:
* platform/ios/ScrollbarThemeIOS.h: Remove shouldCenterOnThumb,
and don't override handleMousePressEvent since iOS wants the
default behavior.
* platform/ios/ScrollbarThemeIOS.mm:
* platform/mac/ScrollbarThemeMac.h: Override handleMousePressEvent
and remove shouldCenterOnThumb.
* platform/mac/ScrollbarThemeMac.mm:
(WebCore::shouldCenterOnThumb): Same implementation just made it
static to be used as helper.
(WebCore::ScrollbarThemeMac::handleMousePressEvent): Return the
desired action keeping the same behavior.
* platform/win/ScrollbarThemeWin.cpp:
(WebCore::ScrollbarThemeWin::handleMousePressEvent): Ditto.
* platform/win/ScrollbarThemeWin.h:
* rendering/RenderScrollbarTheme.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196632 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/ScrollTypes.h
Source/WebCore/platform/Scrollbar.cpp
Source/WebCore/platform/ScrollbarTheme.cpp
Source/WebCore/platform/ScrollbarTheme.h
Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
Source/WebCore/platform/gtk/ScrollbarThemeGtk.h
Source/WebCore/platform/ios/ScrollbarThemeIOS.h
Source/WebCore/platform/ios/ScrollbarThemeIOS.mm
Source/WebCore/platform/mac/ScrollbarThemeMac.h
Source/WebCore/platform/mac/ScrollbarThemeMac.mm
Source/WebCore/platform/win/ScrollbarThemeWin.cpp
Source/WebCore/platform/win/ScrollbarThemeWin.h
Source/WebCore/rendering/RenderScrollbarTheme.h

index 6484fed..6584ca5 100644 (file)
@@ -1,5 +1,46 @@
 2016-02-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [GTK] clicking on the scrollbar trough steps rather than jumps to the clicked position
+        https://bugs.webkit.org/show_bug.cgi?id=115363
+
+        Reviewed by Michael Catanzaro.
+
+        Allow ScrollbarTheme to decide the behavior of a button press event,
+        instead of only deciding whether to center on thumb or not. This
+        way we can match the current GTK+ behavior in WebKit, without
+        affecting other ports.
+
+        * platform/ScrollTypes.h: Add ScrollbarButtonPressAction enum.
+        * platform/Scrollbar.cpp:
+        (WebCore::Scrollbar::mouseDown): Ask ScrollbarTheme to handle the
+        event for the pressed part and do the requested action.
+        * platform/ScrollbarTheme.cpp:
+        (WebCore::ScrollbarTheme::handleMousePressEvent): Add default
+        implementation. It's equivalent to the previous default implementation.
+        * platform/ScrollbarTheme.h:
+        * platform/gtk/ScrollbarThemeGtk.cpp:
+        (WebCore::ScrollbarThemeGtk::handleMousePressEvent): Match current
+        GTK+ behavior: left click centers on thumb and right click
+        scrolls. Dragging the thumb works for left and middle buttons.
+        * platform/gtk/ScrollbarThemeGtk.h:
+        * platform/ios/ScrollbarThemeIOS.h: Remove shouldCenterOnThumb,
+        and don't override handleMousePressEvent since iOS wants the
+        default behavior.
+        * platform/ios/ScrollbarThemeIOS.mm:
+        * platform/mac/ScrollbarThemeMac.h: Override handleMousePressEvent
+        and remove shouldCenterOnThumb.
+        * platform/mac/ScrollbarThemeMac.mm:
+        (WebCore::shouldCenterOnThumb): Same implementation just made it
+        static to be used as helper.
+        (WebCore::ScrollbarThemeMac::handleMousePressEvent): Return the
+        desired action keeping the same behavior.
+        * platform/win/ScrollbarThemeWin.cpp:
+        (WebCore::ScrollbarThemeWin::handleMousePressEvent): Ditto.
+        * platform/win/ScrollbarThemeWin.h:
+        * rendering/RenderScrollbarTheme.h:
+
+2016-02-16  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         Mouse cursor doesn't change when entering scrollbars
         https://bugs.webkit.org/show_bug.cgi?id=154243
 
index 49865de..df79001 100644 (file)
@@ -180,6 +180,13 @@ enum ScrollBehaviorForFixedElements {
     StickToViewportBounds
 };
 
+enum class ScrollbarButtonPressAction {
+    None,
+    CenterOnThumb,
+    StartDrag,
+    Scroll
+};
+
 }
 
 #endif
index 4b701c7..05bf16a 100644 (file)
@@ -391,31 +391,34 @@ bool Scrollbar::mouseUp(const PlatformMouseEvent& mouseEvent)
 
 bool Scrollbar::mouseDown(const PlatformMouseEvent& evt)
 {
-    // Early exit for right click
-    if (evt.button() == RightButton)
-        return true; // FIXME: Handled as context menu by Qt right now.  Should just avoid even calling this method on a right click though.
+    ScrollbarPart pressedPart = theme().hitTest(*this, evt.position());
+    auto action = theme().handleMousePressEvent(*this, evt, pressedPart);
+    if (action == ScrollbarButtonPressAction::None)
+        return true;
 
     m_scrollableArea.mouseIsDownInScrollbar(this, true);
-    setPressedPart(theme().hitTest(*this, evt.position()));
-    int pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y());
-    
-    if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && theme().shouldCenterOnThumb(*this, evt)) {
+    setPressedPart(pressedPart);
+
+    int pressedPosition = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y());
+    if (action == ScrollbarButtonPressAction::CenterOnThumb) {
         setHoveredPart(ThumbPart);
         setPressedPart(ThumbPart);
         m_dragOrigin = m_currentPos;
-        int thumbLen = theme().thumbLength(*this);
-        int desiredPos = pressedPos;
         // Set the pressed position to the middle of the thumb so that when we do the move, the delta
         // will be from the current pixel position of the thumb to the new desired position for the thumb.
-        m_pressedPos = theme().trackPosition(*this) + theme().thumbPosition(*this) + thumbLen / 2;
-        moveThumb(desiredPos);
+        m_pressedPos = theme().trackPosition(*this) + theme().thumbPosition(*this) + theme().thumbLength(*this) / 2;
+        moveThumb(pressedPosition);
         return true;
-    } else if (m_pressedPart == ThumbPart)
+    }
+
+    m_pressedPos = pressedPosition;
+
+    if (action == ScrollbarButtonPressAction::StartDrag)
         m_dragOrigin = m_currentPos;
-    
-    m_pressedPos = pressedPos;
 
-    autoscrollPressedPart(theme().initialAutoscrollTimerDelay());
+    if (action == ScrollbarButtonPressAction::Scroll)
+        autoscrollPressedPart(theme().initialAutoscrollTimerDelay());
+
     return true;
 }
 
index 438f368..b5e93c7 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "ScrollbarTheme.h"
 
+#include "PlatformMouseEvent.h"
 #include "ScrollbarThemeMock.h"
 #include "Settings.h"
 #include <wtf/NeverDestroyed.h>
@@ -41,4 +42,13 @@ ScrollbarTheme& ScrollbarTheme::theme()
     return nativeTheme();
 }
 
+ScrollbarButtonPressAction ScrollbarTheme::handleMousePressEvent(Scrollbar&, const PlatformMouseEvent& event, ScrollbarPart pressedPart)
+{
+    if (event.button() == RightButton)
+        return ScrollbarButtonPressAction::None;
+    if (pressedPart == ThumbPart)
+        return ScrollbarButtonPressAction::StartDrag;
+    return ScrollbarButtonPressAction::Scroll;
+}
+
 }
index cae5299..7252942 100644 (file)
@@ -95,7 +95,7 @@ public:
     virtual void setUpContentShadowLayer(GraphicsLayer*) { }
 #endif
 
-    virtual bool shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent&) { return false; }
+    virtual ScrollbarButtonPressAction handleMousePressEvent(Scrollbar&, const PlatformMouseEvent&, ScrollbarPart);
     virtual bool shouldSnapBackToDragOrigin(Scrollbar&, const PlatformMouseEvent&) { return false; }
     virtual bool shouldDragDocumentInsteadOfThumb(Scrollbar&, const PlatformMouseEvent&) { return false; }
     virtual int thumbPosition(Scrollbar&) { return 0; } // The position of the thumb relative to the track.
index fc6e903..2f456a1 100644 (file)
@@ -493,9 +493,25 @@ bool ScrollbarThemeGtk::paint(Scrollbar& scrollbar, GraphicsContext& graphicsCon
     return true;
 }
 
-bool ScrollbarThemeGtk::shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent& event)
+ScrollbarButtonPressAction ScrollbarThemeGtk::handleMousePressEvent(Scrollbar&, const PlatformMouseEvent& event, ScrollbarPart pressedPart)
 {
-    return (event.shiftKey() && event.button() == LeftButton) || (event.button() == MiddleButton);
+    switch (pressedPart) {
+    case BackTrackPart:
+    case ForwardTrackPart:
+        if (event.button() == LeftButton)
+            return ScrollbarButtonPressAction::CenterOnThumb;
+        if (event.button() == RightButton)
+            return ScrollbarButtonPressAction::Scroll;
+        break;
+    case ThumbPart:
+        if (event.button() != RightButton)
+            return ScrollbarButtonPressAction::StartDrag;
+        break;
+    default:
+        break;
+    }
+
+    return ScrollbarButtonPressAction::None;
 }
 
 int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize)
index 8b7b64c..e474015 100644 (file)
@@ -53,7 +53,7 @@ public:
     virtual void paintTrackBackground(GraphicsContext&, Scrollbar&, const IntRect&) override;
     virtual void paintThumb(GraphicsContext&, Scrollbar&, const IntRect&) override;
     virtual void paintButton(GraphicsContext&, Scrollbar&, const IntRect&, ScrollbarPart) override;
-    virtual bool shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent&) override;
+    virtual ScrollbarButtonPressAction handleMousePressEvent(Scrollbar&, const PlatformMouseEvent&, ScrollbarPart) override;
     virtual int scrollbarThickness(ScrollbarControlSize) override;
     virtual int minimumThumbLength(Scrollbar&) override;
 
index 12d345f..0597f83 100644 (file)
@@ -58,9 +58,7 @@ protected:
     virtual IntRect trackRect(Scrollbar&, bool painting = false) override;
 
     virtual int minimumThumbLength(Scrollbar&) override;
-    
-    virtual bool shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent&) override;
-    
+
 public:
     void preferencesChanged();
 };
index 517010e..6e520be 100644 (file)
@@ -111,11 +111,6 @@ int ScrollbarThemeIOS::minimumThumbLength(Scrollbar&)
     return 0;
 }
 
-bool ScrollbarThemeIOS::shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent&)
-{
-    return false;
-}
-
 bool ScrollbarThemeIOS::paint(Scrollbar&, GraphicsContext&, const IntRect& /*damageRect*/)
 {
     return true;
index dcd8619..a91adba 100644 (file)
@@ -84,7 +84,7 @@ protected:
 
     virtual int minimumThumbLength(Scrollbar&) override;
     
-    virtual bool shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent&) override;
+    virtual ScrollbarButtonPressAction handleMousePressEvent(Scrollbar&, const PlatformMouseEvent&, ScrollbarPart) override;
     virtual bool shouldDragDocumentInsteadOfThumb(Scrollbar&, const PlatformMouseEvent&) override;
     int scrollbarPartToHIPressedState(ScrollbarPart);
 
index 2a50f3a..882a84e 100644 (file)
@@ -424,7 +424,7 @@ int ScrollbarThemeMac::minimumThumbLength(Scrollbar& scrollbar)
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-bool ScrollbarThemeMac::shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent& evt)
+static bool shouldCenterOnThumb(const PlatformMouseEvent& evt)
 {
     if (evt.button() != LeftButton)
         return false;
@@ -433,6 +433,26 @@ bool ScrollbarThemeMac::shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent
     return evt.altKey();
 }
 
+ScrollbarButtonPressAction ScrollbarThemeMac::handleMousePressEvent(Scrollbar&, const PlatformMouseEvent& event, ScrollbarPart pressedPart)
+{
+    if (event.button() == RightButton)
+        return ScrollbarButtonPressAction::None;
+
+    switch (pressedPart) {
+    case BackTrackPart:
+    case ForwardTrackPart:
+        if (shouldCenterOnThumb(event))
+            return ScrollbarButtonPressAction::CenterOnThumb;
+        break;
+    case ThumbPart:
+        return ScrollbarButtonPressAction::StartDrag;
+    default:
+        break;
+    }
+
+    return ScrollbarButtonPressAction::Scroll;
+}
+
 bool ScrollbarThemeMac::shouldDragDocumentInsteadOfThumb(Scrollbar&, const PlatformMouseEvent& event)
 {
     return event.altKey();
index 28dfbfc..5a70de5 100644 (file)
@@ -193,9 +193,24 @@ IntRect ScrollbarThemeWin::trackRect(Scrollbar& scrollbar, bool)
     return IntRect(scrollbar.x(), scrollbar.y() + thickness, thickness, scrollbar.height() - 2 * thickness);
 }
 
-bool ScrollbarThemeWin::shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent& evt)
+ScrollbarButtonPressAction ScrollbarThemeWin::handleMousePressEvent(Scrollbar&, const PlatformMouseEvent& event, ScrollbarPart pressedPart)
 {
-    return evt.shiftKey() && evt.button() == LeftButton;
+    if (event.button() == RightButton)
+        return ScrollbarButtonPressAction::None;
+
+    switch (pressedPart) {
+    case BackTrackPart:
+    case ForwardTrackPart:
+        if (event.shiftKey() && event.button() == LeftButton)
+            return ScrollbarButtonPressAction::CenterOnThumb;
+        break;
+    case ThumbPart:
+        return ScrollbarButtonPressAction::StartDrag;
+    default:
+        break;
+    }
+
+    return ScrollbarButtonPressAction::Scroll;
 }
 
 bool ScrollbarThemeWin::shouldSnapBackToDragOrigin(Scrollbar& scrollbar, const PlatformMouseEvent& evt)
index 57523e1..bd05947 100644 (file)
@@ -49,7 +49,7 @@ protected:
     bool hasButtons(Scrollbar&) override { return true; }
     bool hasThumb(Scrollbar&) override;
 
-    bool shouldCenterOnThumb(Scrollbar&, const PlatformMouseEvent&) override;
+    virtual ScrollbarButtonPressAction handleMousePressEvent(Scrollbar&, const PlatformMouseEvent&, ScrollbarPart) override;
     bool shouldSnapBackToDragOrigin(Scrollbar&, const PlatformMouseEvent&) override;
 
     void paintTrackBackground(GraphicsContext&, Scrollbar&, const IntRect&) override;
index c099513..811a1dd 100644 (file)
@@ -46,8 +46,8 @@ public:
 
     virtual void paintScrollCorner(ScrollView*, GraphicsContext&, const IntRect& cornerRect) override;
 
-    virtual bool shouldCenterOnThumb(Scrollbar& scrollbar, const PlatformMouseEvent& event) override { return ScrollbarTheme::theme().shouldCenterOnThumb(scrollbar, event); }
-    
+    virtual ScrollbarButtonPressAction handleMousePressEvent(Scrollbar& scrollbar, const PlatformMouseEvent& event, ScrollbarPart pressedPart) override { return ScrollbarTheme::theme().handleMousePressEvent(scrollbar, event, pressedPart); }
+
     virtual double initialAutoscrollTimerDelay() override { return ScrollbarTheme::theme().initialAutoscrollTimerDelay(); }
     virtual double autoscrollTimerDelay() override { return ScrollbarTheme::theme().autoscrollTimerDelay(); }