Diff
Modified: trunk/Source/WebCore/ChangeLog (195809 => 195810)
--- trunk/Source/WebCore/ChangeLog 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/ChangeLog 2016-01-29 10:58:17 UTC (rev 195810)
@@ -1,3 +1,116 @@
+2016-01-29 Carlos Garcia Campos <[email protected]>
+
+ [GTK] Implement overlay scrollbars
+ https://bugs.webkit.org/show_bug.cgi?id=153405
+
+ Reviewed by Michael Catanzaro.
+
+ Add support for overlay scrollbars to GTK+ platform following the
+ same style and behavior than GtkScrolledWindow. They are only
+ available for GTK+ >= 3.19, but honoring the GTK_OVERLAY_SCROLLING
+ environment variable, so they could be disable at run time, except
+ when threaded compositor is enabled. A new ScrollAnimator class
+ has been added for GTK+ to implement overlay scrollbars and still
+ allow smooth scrolling when available.
+
+ * PlatformGTK.cmake: Add ScrollAnimatorGtk and stop building ScrollAnimatorSmooth.
+ * platform/ScrollAnimator.h:
+ (WebCore::ScrollAnimator::ScrollAnimator::mouseEnteredContentArea):
+ Remove const to allow the ScrollAnimator to be updated.
+ (WebCore::ScrollAnimator::ScrollAnimator::mouseExitedContentArea): Ditto.
+ (WebCore::ScrollAnimator::ScrollAnimator::mouseMovedInContentArea): Ditto.
+ (WebCore::ScrollAnimator::ScrollAnimator::contentAreaDidShow): Ditto.
+ (WebCore::ScrollAnimator::ScrollAnimator::contentAreaDidHide): Ditto.
+ * platform/Scrollbar.h:
+ (WebCore::Scrollbar::opacity): Get scrollbar opacity.
+ (WebCore::Scrollbar::setOpacity): Set scrollbar opacity.
+ * platform/gtk/ScrollAnimatorGtk.cpp: Added.
+ (WebCore::ScrollAnimator::create): Create a ScrollAnimatorGtk.
+ (WebCore::ScrollAnimatorGtk::ScrollAnimatorGtk):
+ (WebCore::ScrollAnimatorGtk::~ScrollAnimatorGtk):
+ (WebCore::ScrollAnimatorGtk::ensureSmoothScrollingAnimation):
+ Initialize the ScrollAnimationSmooth if it doesn't exist.
+ (WebCore::ScrollAnimatorGtk::scroll): Ensure we have a
+ ScrollAnimationSmooth if smooth scrolling is enabled. This also
+ fixes the problem of having to reload the page after changing the
+ smooth scrolling setting.
+ (WebCore::ScrollAnimatorGtk::scrollToOffsetWithoutAnimation):
+ (WebCore::ScrollAnimatorGtk::willEndLiveResize):
+ (WebCore::ScrollAnimatorGtk::didAddVerticalScrollbar): Register
+ the scrollbar if it's an overlay scrollbar and make it visible
+ without animating it. Start the hide animation.
+ (WebCore::ScrollAnimatorGtk::didAddHorizontalScrollbar): Ditto.
+ (WebCore::ScrollAnimatorGtk::willRemoveVerticalScrollbar):
+ Unregister the scrollbar if it was registered and resrt the
+ animation state if it was the only scrollbar.
+ (WebCore::ScrollAnimatorGtk::willRemoveHorizontalScrollbar): Ditto.
+ (WebCore::ScrollAnimatorGtk::updateOverlayScrollbarsOpacity): Update
+ the scrollbars opacity and invalidate the indicator.
+ (WebCore::easeOutCubic):
+ (WebCore::ScrollAnimatorGtk::overlayScrollbarAnimationTimerFired):
+ Update the scrollbars opacity and schedule a next frame if the
+ animation didn't finish or start the hide animation otherwhise.
+ (WebCore::ScrollAnimatorGtk::showOverlayScrollbars): Start the
+ fade animation to show the scrollbars if needed.
+ (WebCore::ScrollAnimatorGtk::hideOverlayScrollbars): Start the
+ dafe animation to hide the scrollbars if needed.
+ (WebCore::ScrollAnimatorGtk::mouseEnteredContentArea): Call
+ showOverlayScrollbars().
+ (WebCore::ScrollAnimatorGtk::mouseExitedContentArea): Call
+ hideOverlayScrollbars().
+ (WebCore::ScrollAnimatorGtk::mouseMovedInContentArea): Call
+ showOverlayScrollbars().
+ (WebCore::ScrollAnimatorGtk::contentAreaDidShow): Ditto.
+ (WebCore::ScrollAnimatorGtk::contentAreaDidHide): Hide the
+ scrollbars without animations.
+ (WebCore::ScrollAnimatorGtk::notifyContentAreaScrolled): Call
+ showOverlayScrollbars().
+ (WebCore::ScrollAnimatorGtk::lockOverlayScrollbarStateToHidden):
+ Update the lock state and hide or show the scrollbars when locked
+ or unlocked.
+ * platform/gtk/ScrollAnimatorGtk.h: Added.
+ * platform/gtk/ScrollbarThemeGtk.cpp:
+ (WebCore::ScrollbarThemeGtk::backButtonRect): Pass
+ StyleContextMode to getOrCreateStyleContext depending on the
+ painting parameter.
+ (WebCore::ScrollbarThemeGtk::forwardButtonRect): Ditto.
+ (WebCore::ScrollbarThemeGtk::trackRect): Ditto.
+ (WebCore::ScrollbarThemeGtk::getOrCreateStyleContext): Add
+ StyleContextMode parameter to add the hovering class
+ unconditionally when using overlay scrollbars in layout mode. In
+ paint mode we add the hovering clas only when the scrollbar is
+ hovered. This way we always claim the size of the scrollbar when
+ hovered to be able to show the full scrollbar when the mouse is
+ close enough to the indicator.
+ (WebCore::ScrollbarThemeGtk::ScrollbarThemeGtk): Initialize
+ m_usesOverlayScrollbars.
+ (WebCore::ScrollbarThemeGtk::thumbRect): Pass the scrollbar to
+ getOrCreateStyleContext().
+ (WebCore::adjustRectAccordingToMargin): Fix the top margin.
+ (WebCore::ScrollbarThemeGtk::paintTrackBackground): Pass the
+ scrollbar and paint mode to getOrCreateStyleContext().
+ (WebCore::ScrollbarThemeGtk::paintScrollbarBackground): Ditto.
+ (WebCore::ScrollbarThemeGtk::paintThumb): Adjust the thumb
+ rectangle when overlay scrollbar is not hovered to its current
+ size, since we always claim the size of the scrollbar in hovered
+ mode.
+ (WebCore::ScrollbarThemeGtk::paintButton): Pass the scrollbar and
+ paint mode to getOrCreateStyleContext().
+ (WebCore::ScrollbarThemeGtk::paint): Take the scrollbar opacity
+ into account when rendering overlay scrollbars as indicators. Also
+ get the scrollbar opacity from the GTK+ theme and use a
+ transparency group when the global opacity is not full opaque.
+ (WebCore::ScrollbarThemeGtk::buttonSize): Pass the scrollbar to
+ getOrCreateStyleContext().
+ * platform/gtk/ScrollbarThemeGtk.h:
+ * platform/mac/ScrollAnimatorMac.h:
+ * platform/mac/ScrollAnimatorMac.mm:
+ (WebCore::ScrollAnimatorMac::mouseEnteredContentArea):
+ (WebCore::ScrollAnimatorMac::mouseExitedContentArea):
+ (WebCore::ScrollAnimatorMac::mouseMovedInContentArea):
+ (WebCore::ScrollAnimatorMac::contentAreaDidShow):
+ (WebCore::ScrollAnimatorMac::contentAreaDidHide):
+
2016-01-29 ChangSeok Oh <[email protected]>
[GStreamer] built-in media player doesn't update
Modified: trunk/Source/WebCore/PlatformGTK.cmake (195809 => 195810)
--- trunk/Source/WebCore/PlatformGTK.cmake 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/PlatformGTK.cmake 2016-01-29 10:58:17 UTC (rev 195810)
@@ -163,6 +163,7 @@
platform/gtk/LanguageGtk.cpp
platform/gtk/LoggingGtk.cpp
platform/gtk/MIMETypeRegistryGtk.cpp
+ platform/gtk/ScrollAnimatorGtk.cpp
platform/gtk/SharedBufferGtk.cpp
platform/gtk/TemporaryLinkStubs.cpp
platform/gtk/UserAgentGtk.cpp
@@ -936,7 +937,6 @@
if (ENABLE_SMOOTH_SCROLLING)
list(APPEND WebCore_SOURCES
platform/ScrollAnimationSmooth.cpp
- platform/ScrollAnimatorSmooth.cpp
)
endif ()
Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (195809 => 195810)
--- trunk/Source/WebCore/platform/ScrollAnimator.h 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h 2016-01-29 10:58:17 UTC (rev 195810)
@@ -91,17 +91,17 @@
virtual void serviceScrollAnimations() { }
virtual void contentAreaWillPaint() const { }
- virtual void mouseEnteredContentArea() const { }
- virtual void mouseExitedContentArea() const { }
- virtual void mouseMovedInContentArea() const { }
+ virtual void mouseEnteredContentArea() { }
+ virtual void mouseExitedContentArea() { }
+ virtual void mouseMovedInContentArea() { }
virtual void mouseEnteredScrollbar(Scrollbar*) const { }
virtual void mouseExitedScrollbar(Scrollbar*) const { }
virtual void mouseIsDownInScrollbar(Scrollbar*, bool) const { }
virtual void willStartLiveResize() { }
virtual void contentsResized() const { }
virtual void willEndLiveResize() { }
- virtual void contentAreaDidShow() const { }
- virtual void contentAreaDidHide() const { }
+ virtual void contentAreaDidShow() { }
+ virtual void contentAreaDidHide() { }
virtual void lockOverlayScrollbarStateToHidden(bool) { }
virtual bool scrollbarsCanBeActive() const { return true; }
Modified: trunk/Source/WebCore/platform/Scrollbar.h (195809 => 195810)
--- trunk/Source/WebCore/platform/Scrollbar.h 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/platform/Scrollbar.h 2016-01-29 10:58:17 UTC (rev 195810)
@@ -130,6 +130,9 @@
bool isAlphaLocked() const { return m_isAlphaLocked; }
void setIsAlphaLocked(bool flag) { m_isAlphaLocked = flag; }
+ float opacity() const { return m_opacity; }
+ void setOpacity(float opacity) { m_opacity = opacity; }
+
bool supportsUpdateOnSecondaryThread() const;
WeakPtr<Scrollbar> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
@@ -178,6 +181,8 @@
bool m_isCustomScrollbar;
+ float m_opacity { 1 };
+
private:
virtual bool isScrollbar() const override { return true; }
Added: trunk/Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp (0 => 195810)
--- trunk/Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp (rev 0)
+++ trunk/Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp 2016-01-29 10:58:17 UTC (rev 195810)
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2016 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollAnimatorGtk.h"
+
+#include "ScrollAnimationSmooth.h"
+#include "ScrollableArea.h"
+#include "ScrollbarTheme.h"
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+static const double overflowScrollbarsAnimationDuration = 1;
+static const double overflowScrollbarsAnimationHideDelay = 2;
+
+std::unique_ptr<ScrollAnimator> ScrollAnimator::create(ScrollableArea& scrollableArea)
+{
+ return std::make_unique<ScrollAnimatorGtk>(scrollableArea);
+}
+
+ScrollAnimatorGtk::ScrollAnimatorGtk(ScrollableArea& scrollableArea)
+ : ScrollAnimator(scrollableArea)
+ , m_overlayScrollbarAnimationTimer(*this, &ScrollAnimatorGtk::overlayScrollbarAnimationTimerFired)
+{
+#if ENABLE(SMOOTH_SCROLLING)
+ if (scrollableArea.scrollAnimatorEnabled())
+ ensureSmoothScrollingAnimation();
+#endif
+}
+
+ScrollAnimatorGtk::~ScrollAnimatorGtk()
+{
+}
+
+#if ENABLE(SMOOTH_SCROLLING)
+void ScrollAnimatorGtk::ensureSmoothScrollingAnimation()
+{
+ if (m_animation)
+ return;
+
+ m_animation = std::make_unique<ScrollAnimationSmooth>(m_scrollableArea, [this](FloatPoint&& position) {
+ FloatSize delta = position - m_currentPosition;
+ m_currentPosition = WTFMove(position);
+ notifyPositionChanged(delta);
+ });
+ m_animation->setCurrentPosition(m_currentPosition);
+}
+
+bool ScrollAnimatorGtk::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+{
+ if (!m_scrollableArea.scrollAnimatorEnabled() || granularity == ScrollByPrecisePixel)
+ return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
+
+ ensureSmoothScrollingAnimation();
+ return m_animation->scroll(orientation, granularity, step, multiplier);
+}
+
+void ScrollAnimatorGtk::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
+{
+ FloatPoint position = ScrollableArea::scrollPositionFromOffset(offset, toFloatSize(m_scrollableArea.scrollOrigin()));
+ if (m_animation)
+ m_animation->setCurrentPosition(position);
+
+ FloatSize delta = position - m_currentPosition;
+ m_currentPosition = position;
+ notifyPositionChanged(delta);
+}
+
+void ScrollAnimatorGtk::willEndLiveResize()
+{
+ if (m_animation)
+ m_animation->updateVisibleLengths();
+}
+#endif
+
+void ScrollAnimatorGtk::didAddVerticalScrollbar(Scrollbar* scrollbar)
+{
+#if ENABLE(SMOOTH_SCROLLING)
+ if (m_animation)
+ m_animation->updateVisibleLengths();
+#endif
+ if (!scrollbar->isOverlayScrollbar())
+ return;
+ m_verticalOverlayScrollbar = scrollbar;
+ if (!m_horizontalOverlayScrollbar)
+ m_overlayScrollbarAnimationCurrent = 1;
+ m_verticalOverlayScrollbar->setOpacity(m_overlayScrollbarAnimationCurrent);
+ hideOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::didAddHorizontalScrollbar(Scrollbar* scrollbar)
+{
+#if ENABLE(SMOOTH_SCROLLING)
+ if (m_animation)
+ m_animation->updateVisibleLengths();
+#endif
+ if (!scrollbar->isOverlayScrollbar())
+ return;
+ m_horizontalOverlayScrollbar = scrollbar;
+ if (!m_verticalOverlayScrollbar)
+ m_overlayScrollbarAnimationCurrent = 1;
+ m_horizontalOverlayScrollbar->setOpacity(m_overlayScrollbarAnimationCurrent);
+ hideOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::willRemoveVerticalScrollbar(Scrollbar* scrollbar)
+{
+ if (m_verticalOverlayScrollbar != scrollbar)
+ return;
+ m_verticalOverlayScrollbar = nullptr;
+ if (!m_horizontalOverlayScrollbar)
+ m_overlayScrollbarAnimationCurrent = 0;
+}
+
+void ScrollAnimatorGtk::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
+{
+ if (m_horizontalOverlayScrollbar != scrollbar)
+ return;
+ m_horizontalOverlayScrollbar = nullptr;
+ if (!m_verticalOverlayScrollbar)
+ m_overlayScrollbarAnimationCurrent = 0;
+}
+
+void ScrollAnimatorGtk::updateOverlayScrollbarsOpacity()
+{
+ if (m_verticalOverlayScrollbar && m_overlayScrollbarAnimationCurrent != m_verticalOverlayScrollbar->opacity()) {
+ m_verticalOverlayScrollbar->setOpacity(m_overlayScrollbarAnimationCurrent);
+ if (m_verticalOverlayScrollbar->hoveredPart() == NoPart)
+ ScrollbarTheme::theme().invalidatePart(*m_verticalOverlayScrollbar, ThumbPart);
+ }
+
+ if (m_horizontalOverlayScrollbar && m_overlayScrollbarAnimationCurrent != m_horizontalOverlayScrollbar->opacity()) {
+ m_horizontalOverlayScrollbar->setOpacity(m_overlayScrollbarAnimationCurrent);
+ if (m_horizontalOverlayScrollbar->hoveredPart() == NoPart)
+ ScrollbarTheme::theme().invalidatePart(*m_horizontalOverlayScrollbar, ThumbPart);
+ }
+}
+
+static inline double easeOutCubic(double t)
+{
+ double p = t - 1;
+ return p * p * p + 1;
+}
+
+void ScrollAnimatorGtk::overlayScrollbarAnimationTimerFired()
+{
+ if (!m_horizontalOverlayScrollbar && !m_verticalOverlayScrollbar)
+ return;
+ if (m_overlayScrollbarsLocked)
+ return;
+
+ double currentTime = monotonicallyIncreasingTime();
+ double progress = 1;
+ if (currentTime < m_overlayScrollbarAnimationEndTime)
+ progress = (currentTime - m_overlayScrollbarAnimationStartTime) / (m_overlayScrollbarAnimationEndTime - m_overlayScrollbarAnimationStartTime);
+ progress = m_overlayScrollbarAnimationSource + (easeOutCubic(progress) * (m_overlayScrollbarAnimationTarget - m_overlayScrollbarAnimationSource));
+ if (progress != m_overlayScrollbarAnimationCurrent) {
+ m_overlayScrollbarAnimationCurrent = progress;
+ updateOverlayScrollbarsOpacity();
+ }
+
+ if (m_overlayScrollbarAnimationCurrent != m_overlayScrollbarAnimationTarget) {
+ static const double frameRate = 60;
+ static const double tickTime = 1 / frameRate;
+ static const double minimumTimerInterval = .001;
+ double deltaToNextFrame = std::max(tickTime - (monotonicallyIncreasingTime() - currentTime), minimumTimerInterval);
+ m_overlayScrollbarAnimationTimer.startOneShot(deltaToNextFrame);
+ } else
+ hideOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::showOverlayScrollbars()
+{
+ if (m_overlayScrollbarsLocked)
+ return;
+
+ if (m_overlayScrollbarAnimationTimer.isActive() && m_overlayScrollbarAnimationTarget == 1)
+ return;
+ m_overlayScrollbarAnimationTimer.stop();
+
+ if (!m_horizontalOverlayScrollbar && !m_verticalOverlayScrollbar)
+ return;
+
+ m_overlayScrollbarAnimationSource = m_overlayScrollbarAnimationCurrent;
+ m_overlayScrollbarAnimationTarget = 1;
+ if (m_overlayScrollbarAnimationTarget != m_overlayScrollbarAnimationCurrent) {
+ m_overlayScrollbarAnimationStartTime = monotonicallyIncreasingTime();
+ m_overlayScrollbarAnimationEndTime = m_overlayScrollbarAnimationStartTime + overflowScrollbarsAnimationDuration;
+ m_overlayScrollbarAnimationTimer.startOneShot(0);
+ } else
+ hideOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::hideOverlayScrollbars()
+{
+ if (m_overlayScrollbarAnimationTimer.isActive() && !m_overlayScrollbarAnimationTarget)
+ return;
+ m_overlayScrollbarAnimationTimer.stop();
+
+ if (!m_horizontalOverlayScrollbar && !m_verticalOverlayScrollbar)
+ return;
+
+ m_overlayScrollbarAnimationSource = m_overlayScrollbarAnimationCurrent;
+ m_overlayScrollbarAnimationTarget = 0;
+ if (m_overlayScrollbarAnimationTarget == m_overlayScrollbarAnimationCurrent)
+ return;
+ m_overlayScrollbarAnimationStartTime = monotonicallyIncreasingTime() + overflowScrollbarsAnimationHideDelay;
+ m_overlayScrollbarAnimationEndTime = m_overlayScrollbarAnimationStartTime + overflowScrollbarsAnimationDuration + overflowScrollbarsAnimationHideDelay;
+ m_overlayScrollbarAnimationTimer.startOneShot(overflowScrollbarsAnimationHideDelay);
+}
+
+void ScrollAnimatorGtk::mouseEnteredContentArea()
+{
+ showOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::mouseExitedContentArea()
+{
+ hideOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::mouseMovedInContentArea()
+{
+ showOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::contentAreaDidShow()
+{
+ showOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::contentAreaDidHide()
+{
+ if (m_overlayScrollbarsLocked)
+ return;
+ m_overlayScrollbarAnimationTimer.stop();
+ if (m_overlayScrollbarAnimationCurrent) {
+ m_overlayScrollbarAnimationCurrent = 0;
+ updateOverlayScrollbarsOpacity();
+ }
+}
+
+void ScrollAnimatorGtk::notifyContentAreaScrolled(const FloatSize&)
+{
+ showOverlayScrollbars();
+}
+
+void ScrollAnimatorGtk::lockOverlayScrollbarStateToHidden(bool shouldLockState)
+{
+ if (m_overlayScrollbarsLocked == shouldLockState)
+ return;
+ m_overlayScrollbarsLocked = shouldLockState;
+
+ if (!m_horizontalOverlayScrollbar && !m_verticalOverlayScrollbar)
+ return;
+
+ if (m_overlayScrollbarsLocked) {
+ m_overlayScrollbarAnimationTimer.stop();
+ if (m_horizontalOverlayScrollbar)
+ m_horizontalOverlayScrollbar->setOpacity(0);
+ if (m_verticalOverlayScrollbar)
+ m_verticalOverlayScrollbar->setOpacity(0);
+ } else {
+ if (m_overlayScrollbarAnimationCurrent == 1)
+ updateOverlayScrollbarsOpacity();
+ else
+ showOverlayScrollbars();
+ }
+}
+
+} // namespace WebCore
+
Added: trunk/Source/WebCore/platform/gtk/ScrollAnimatorGtk.h (0 => 195810)
--- trunk/Source/WebCore/platform/gtk/ScrollAnimatorGtk.h (rev 0)
+++ trunk/Source/WebCore/platform/gtk/ScrollAnimatorGtk.h 2016-01-29 10:58:17 UTC (rev 195810)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScrollAnimatorGtk_h
+#define ScrollAnimatorGtk_h
+
+#include "ScrollAnimator.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+class ScrollAnimation;
+
+class ScrollAnimatorGtk final : public ScrollAnimator {
+public:
+ explicit ScrollAnimatorGtk(ScrollableArea&);
+ virtual ~ScrollAnimatorGtk();
+
+private:
+#if ENABLE(SMOOTH_SCROLLING)
+ virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier) override;
+ virtual void scrollToOffsetWithoutAnimation(const FloatPoint&) override;
+ virtual void willEndLiveResize() override;
+#endif
+
+ virtual void didAddVerticalScrollbar(Scrollbar*) override;
+ virtual void didAddHorizontalScrollbar(Scrollbar*) override;
+ virtual void willRemoveVerticalScrollbar(Scrollbar*) override;
+ virtual void willRemoveHorizontalScrollbar(Scrollbar*) override;
+
+ virtual void mouseEnteredContentArea() override;
+ virtual void mouseExitedContentArea() override;
+ virtual void mouseMovedInContentArea() override;
+ virtual void contentAreaDidShow() override;
+ virtual void contentAreaDidHide() override;
+ virtual void notifyContentAreaScrolled(const FloatSize& delta) override;
+ virtual void lockOverlayScrollbarStateToHidden(bool) override;
+
+ void overlayScrollbarAnimationTimerFired();
+ void showOverlayScrollbars();
+ void hideOverlayScrollbars();
+ void updateOverlayScrollbarsOpacity();
+
+#if ENABLE(SMOOTH_SCROLLING)
+ void ensureSmoothScrollingAnimation();
+
+ std::unique_ptr<ScrollAnimation> m_animation;
+#endif
+ Scrollbar* m_horizontalOverlayScrollbar { nullptr };
+ Scrollbar* m_verticalOverlayScrollbar { nullptr };
+ bool m_overlayScrollbarsLocked { false };
+ Timer m_overlayScrollbarAnimationTimer;
+ double m_overlayScrollbarAnimationSource { 0 };
+ double m_overlayScrollbarAnimationTarget { 0 };
+ double m_overlayScrollbarAnimationCurrent { 0 };
+ double m_overlayScrollbarAnimationStartTime { 0 };
+ double m_overlayScrollbarAnimationEndTime { 0 };
+};
+
+} // namespace WebCore
+
+#endif // ScrollAnimatorGtk_h
Modified: trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp (195809 => 195810)
--- trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp 2016-01-29 10:58:17 UTC (rev 195810)
@@ -59,7 +59,7 @@
#endif
}
-IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool)
+IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool painting)
{
#ifndef GTK_API_VERSION_2
if (part == BackButtonEndPart && !m_hasBackButtonEndPart)
@@ -67,7 +67,7 @@
if (part == BackButtonStartPart && !m_hasBackButtonStartPart)
return IntRect();
- GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext();
+ GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(&scrollbar, painting ? StyleContextMode::Paint : StyleContextMode::Layout);
int x = scrollbar.x() + m_cachedProperties.troughBorderWidth;
int y = scrollbar.y() + m_cachedProperties.troughBorderWidth;
IntSize size = buttonSize(scrollbar);
@@ -83,11 +83,12 @@
#else
UNUSED_PARAM(scrollbar);
UNUSED_PARAM(part);
+ UNUSED_PARAM(painting);
return IntRect();
#endif
}
-IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool)
+IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool painting)
{
#ifndef GTK_API_VERSION_2
if (part == ForwardButtonStartPart && !m_hasForwardButtonStartPart)
@@ -95,7 +96,7 @@
if (part == ForwardButtonEndPart && !m_hasForwardButtonEndPart)
return IntRect();
- GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext();
+ GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(&scrollbar, painting ? StyleContextMode::Paint : StyleContextMode::Layout);
IntSize size = buttonSize(scrollbar);
if (scrollbar.orientation() == HorizontalScrollbar) {
int y = scrollbar.y() + m_cachedProperties.troughBorderWidth;
@@ -116,14 +117,15 @@
#else
UNUSED_PARAM(scrollbar);
UNUSED_PARAM(part);
+ UNUSED_PARAM(painting);
return IntRect();
#endif
}
-IntRect ScrollbarThemeGtk::trackRect(Scrollbar& scrollbar, bool)
+IntRect ScrollbarThemeGtk::trackRect(Scrollbar& scrollbar, bool painting)
{
#ifndef GTK_API_VERSION_2
- GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext();
+ GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(&scrollbar, painting ? StyleContextMode::Paint : StyleContextMode::Layout);
// The padding along the thumb movement axis includes the trough border
// plus the size of stepper spacing (the space between the stepper and
// the place where the thumb stops). There is often no stepper spacing.
@@ -162,6 +164,7 @@
thickness, scrollbar.height() - (2 * movementAxisPadding) - buttonsWidth);
#else
UNUSED_PARAM(scrollbar);
+ UNUSED_PARAM(painting);
return IntRect();
#endif
}
@@ -175,8 +178,9 @@
// The GtkStyleContext returned by this function is cached by ScrollbarThemeGtk::paint for the
// duration of its scope, so a different GtkStyleContext with updated theme properties will be
// used for each call to paint.
-GRefPtr<GtkStyleContext> ScrollbarThemeGtk::getOrCreateStyleContext(ScrollbarOrientation orientation)
+GRefPtr<GtkStyleContext> ScrollbarThemeGtk::getOrCreateStyleContext(Scrollbar* scrollbar, StyleContextMode mode)
{
+ ASSERT(scrollbar || mode == StyleContextMode::Layout);
if (m_cachedStyleContext)
return m_cachedStyleContext;
@@ -185,10 +189,15 @@
gtk_widget_path_append_type(path.get(), GTK_TYPE_SCROLLBAR);
#if GTK_CHECK_VERSION(3, 19, 2)
gtk_widget_path_iter_set_object_name(path.get(), -1, "scrollbar");
+ if (m_usesOverlayScrollbars) {
+ gtk_widget_path_iter_add_class(path.get(), -1, "overlay-indicator");
+ if (mode == StyleContextMode::Layout || scrollbar->hoveredPart() != NoPart)
+ gtk_widget_path_iter_add_class(path.get(), -1, "hovering");
+ }
#else
gtk_widget_path_iter_add_class(path.get(), -1, "scrollbar");
#endif
- gtk_widget_path_iter_add_class(path.get(), -1, orientationStyleClass(orientation));
+ gtk_widget_path_iter_add_class(path.get(), -1, orientationStyleClass(scrollbar ? scrollbar->orientation() : VerticalScrollbar));
gtk_style_context_set_path(styleContext.get(), path.get());
gtk_style_context_get_style(
@@ -222,6 +231,15 @@
ScrollbarThemeGtk::ScrollbarThemeGtk()
{
+#if GTK_CHECK_VERSION(3, 19, 2)
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ m_usesOverlayScrollbars = true;
+#else
+ // FIXME: Disable overlay scrollbars by default for now due to bug #153404.
+ // Invert the logic here once bug #153404 is fixed.
+ m_usesOverlayScrollbars = !g_strcmp0(g_getenv("GTK_OVERLAY_SCROLLING"), "1");
+#endif
+#endif
updateThemeProperties();
}
@@ -245,7 +263,7 @@
IntRect ScrollbarThemeGtk::thumbRect(Scrollbar& scrollbar, const IntRect& unconstrainedTrackRect)
{
- GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(scrollbar.orientation());
+ GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(&scrollbar);
IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrainedTrackRect);
int thumbPos = thumbPosition(scrollbar);
if (scrollbar.orientation() == HorizontalScrollbar)
@@ -259,13 +277,13 @@
{
GtkBorder margin;
gtk_style_context_get_margin(context, gtk_style_context_get_state(context), &margin);
- rect.move(margin.left, margin.right);
+ rect.move(margin.left, margin.top);
rect.contract(margin.left + margin.right, margin.top + margin.bottom);
}
void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
{
- GRefPtr<GtkStyleContext> parentStyleContext = getOrCreateStyleContext(scrollbar.orientation());
+ GRefPtr<GtkStyleContext> parentStyleContext = getOrCreateStyleContext(&scrollbar, StyleContextMode::Paint);
// Paint the track background. If the trough-under-steppers property is true, this
// should be the full size of the scrollbar, but if is false, it should only be the
// track rect.
@@ -281,14 +299,14 @@
void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext& context, Scrollbar& scrollbar)
{
- GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(scrollbar.orientation());
+ GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(&scrollbar, StyleContextMode::Paint);
gtk_render_frame(styleContext.get(), context.platformContext()->cr(), scrollbar.x(), scrollbar.y(), scrollbar.width(), scrollbar.height());
}
void ScrollbarThemeGtk::paintThumb(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
{
ScrollbarOrientation orientation = scrollbar.orientation();
- GRefPtr<GtkStyleContext> parentStyleContext = getOrCreateStyleContext(orientation);
+ GRefPtr<GtkStyleContext> parentStyleContext = getOrCreateStyleContext(&scrollbar, StyleContextMode::Paint);
GRefPtr<GtkStyleContext> troughStyleContext = createChildStyleContext(parentStyleContext.get(), "trough");
GRefPtr<GtkStyleContext> styleContext = createChildStyleContext(troughStyleContext.get(), "slider");
@@ -300,6 +318,14 @@
gtk_style_context_set_state(styleContext.get(), static_cast<GtkStateFlags>(flags));
IntRect thumbRect(rect);
+ if (m_usesOverlayScrollbars && scrollbar.hoveredPart() == NoPart) {
+ // When using overlay scrollbars we always claim the size of the scrollbar when hovered, so when
+ // drawing the indicator we need to adjust the rectangle to its actual size in indicator mode.
+ if (orientation == VerticalScrollbar)
+ thumbRect.move(scrollbar.width() - m_cachedProperties.thumbFatness, 0);
+ else
+ thumbRect.move(0, scrollbar.height() - m_cachedProperties.thumbFatness);
+ }
adjustRectAccordingToMargin(styleContext.get(), thumbRect);
gtk_render_slider(styleContext.get(), context.platformContext()->cr(), thumbRect.x(), thumbRect.y(), thumbRect.width(), thumbRect.height(),
orientation == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
@@ -308,7 +334,7 @@
void ScrollbarThemeGtk::paintButton(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart part)
{
ScrollbarOrientation orientation = scrollbar.orientation();
- GRefPtr<GtkStyleContext> parentStyleContext = getOrCreateStyleContext(orientation);
+ GRefPtr<GtkStyleContext> parentStyleContext = getOrCreateStyleContext(&scrollbar, StyleContextMode::Paint);
GRefPtr<GtkStyleContext> styleContext = createChildStyleContext(parentStyleContext.get(), "button");
unsigned flags = 0;
@@ -355,8 +381,12 @@
if (graphicsContext.paintingDisabled())
return false;
+ double opacity = scrollbar.hoveredPart() == NoPart ? scrollbar.opacity() : 1;
+ if (!opacity)
+ return true;
+
// Cache a new GtkStyleContext for the duration of this scope.
- TemporaryChange<GRefPtr<GtkStyleContext>> tempStyleContext(m_cachedStyleContext, getOrCreateStyleContext(scrollbar.orientation()));
+ TemporaryChange<GRefPtr<GtkStyleContext>> tempStyleContext(m_cachedStyleContext, getOrCreateStyleContext(&scrollbar, StyleContextMode::Paint));
// Create the ScrollbarControlPartMask based on the damageRect
ScrollbarControlPartMask scrollMask = NoPart;
@@ -399,6 +429,31 @@
scrollMask |= ThumbPart;
}
+ if (m_usesOverlayScrollbars) {
+ // FIXME: Remove this check once 3.20 is released.
+#if GTK_CHECK_VERSION(3, 19, 8)
+ unsigned flags = 0;
+ if (scrollbar.hoveredPart() != NoPart)
+ flags |= GTK_STATE_FLAG_PRELIGHT;
+ if (scrollbar.pressedPart() != NoPart)
+ flags |= GTK_STATE_FLAG_ACTIVE;
+ double styleOpacity;
+ gtk_style_context_set_state(m_cachedStyleContext.get(), static_cast<GtkStateFlags>(flags));
+ gtk_style_context_get(m_cachedStyleContext.get(), gtk_style_context_get_state(m_cachedStyleContext.get()), "opacity", &styleOpacity, nullptr);
+ opacity *= styleOpacity;
+#else
+ opacity *= scrollbar.hoveredPart() == NoPart ? 0.4 : 0.7;
+#endif
+ }
+ if (!opacity)
+ return true;
+
+ if (opacity != 1) {
+ graphicsContext.save();
+ graphicsContext.clip(damageRect);
+ graphicsContext.beginTransparencyLayer(opacity);
+ }
+
ScrollbarControlPartMask allButtons = BackButtonStartPart | BackButtonEndPart | ForwardButtonStartPart | ForwardButtonEndPart;
if (scrollMask & TrackBGPart || scrollMask & ThumbPart || scrollMask & allButtons)
paintScrollbarBackground(graphicsContext, scrollbar);
@@ -418,6 +473,11 @@
if (scrollMask & ThumbPart)
paintThumb(graphicsContext, scrollbar, currentThumbRect);
+ if (opacity != 1) {
+ graphicsContext.endTransparencyLayer();
+ graphicsContext.restore();
+ }
+
return true;
}
@@ -434,7 +494,7 @@
IntSize ScrollbarThemeGtk::buttonSize(Scrollbar& scrollbar)
{
- GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(scrollbar.orientation());
+ GRefPtr<GtkStyleContext> styleContext = getOrCreateStyleContext(&scrollbar);
if (scrollbar.orientation() == VerticalScrollbar)
return IntSize(m_cachedProperties.thumbFatness, m_cachedProperties.stepperSize);
Modified: trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.h (195809 => 195810)
--- trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.h 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/platform/gtk/ScrollbarThemeGtk.h 2016-01-29 10:58:17 UTC (rev 195810)
@@ -61,10 +61,14 @@
virtual double initialAutoscrollTimerDelay() override { return 0.20; }
virtual double autoscrollTimerDelay() override { return 0.02; }
virtual void themeChanged() override;
+ virtual bool usesOverlayScrollbars() const override { return m_usesOverlayScrollbars; }
+ // When using overlay scrollbars, always invalidate the whole scrollbar when entering/leaving.
+ virtual bool invalidateOnMouseEnterExit() override { return m_usesOverlayScrollbars; }
private:
void updateThemeProperties();
- GRefPtr<GtkStyleContext> getOrCreateStyleContext(ScrollbarOrientation = VerticalScrollbar);
+ enum class StyleContextMode { Layout, Paint };
+ GRefPtr<GtkStyleContext> getOrCreateStyleContext(Scrollbar* = nullptr, StyleContextMode = StyleContextMode::Layout);
IntSize buttonSize(Scrollbar&);
@@ -83,6 +87,7 @@
gboolean m_hasForwardButtonEndPart;
gboolean m_hasBackButtonStartPart;
gboolean m_hasBackButtonEndPart;
+ bool m_usesOverlayScrollbars { false };
#endif // GTK_API_VERSION_2
};
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h (195809 => 195810)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h 2016-01-29 10:58:17 UTC (rev 195810)
@@ -95,17 +95,17 @@
virtual void notifyPositionChanged(const FloatSize& delta) override;
virtual void contentAreaWillPaint() const override;
- virtual void mouseEnteredContentArea() const override;
- virtual void mouseExitedContentArea() const override;
- virtual void mouseMovedInContentArea() const override;
+ virtual void mouseEnteredContentArea() override;
+ virtual void mouseExitedContentArea() override;
+ virtual void mouseMovedInContentArea() override;
virtual void mouseEnteredScrollbar(Scrollbar*) const override;
virtual void mouseExitedScrollbar(Scrollbar*) const override;
virtual void mouseIsDownInScrollbar(Scrollbar*, bool) const override;
virtual void willStartLiveResize() override;
virtual void contentsResized() const override;
virtual void willEndLiveResize() override;
- virtual void contentAreaDidShow() const override;
- virtual void contentAreaDidHide() const override;
+ virtual void contentAreaDidShow() override;
+ virtual void contentAreaDidHide() override;
void didBeginScrollGesture() const;
void didEndScrollGesture() const;
void mayBeginScrollGesture() const;
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm (195809 => 195810)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2016-01-29 09:58:02 UTC (rev 195809)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2016-01-29 10:58:17 UTC (rev 195810)
@@ -806,7 +806,7 @@
[m_scrollbarPainterController contentAreaWillDraw];
}
-void ScrollAnimatorMac::mouseEnteredContentArea() const
+void ScrollAnimatorMac::mouseEnteredContentArea()
{
if ([m_scrollbarPainterController overlayScrollerStateIsLocked])
return;
@@ -814,7 +814,7 @@
[m_scrollbarPainterController mouseEnteredContentArea];
}
-void ScrollAnimatorMac::mouseExitedContentArea() const
+void ScrollAnimatorMac::mouseExitedContentArea()
{
if ([m_scrollbarPainterController overlayScrollerStateIsLocked])
return;
@@ -822,7 +822,7 @@
[m_scrollbarPainterController mouseExitedContentArea];
}
-void ScrollAnimatorMac::mouseMovedInContentArea() const
+void ScrollAnimatorMac::mouseMovedInContentArea()
{
if ([m_scrollbarPainterController overlayScrollerStateIsLocked])
return;
@@ -898,7 +898,7 @@
[m_scrollbarPainterController endLiveResize];
}
-void ScrollAnimatorMac::contentAreaDidShow() const
+void ScrollAnimatorMac::contentAreaDidShow()
{
if ([m_scrollbarPainterController overlayScrollerStateIsLocked])
return;
@@ -906,7 +906,7 @@
[m_scrollbarPainterController windowOrderedIn];
}
-void ScrollAnimatorMac::contentAreaDidHide() const
+void ScrollAnimatorMac::contentAreaDidHide()
{
if ([m_scrollbarPainterController overlayScrollerStateIsLocked])
return;