Scroll latching logic can get stuck in 'scrollable="no"' iframes
[WebKit-https.git] / Source / WebCore / platform / PlatformWheelEvent.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef PlatformWheelEvent_h
27 #define PlatformWheelEvent_h
28
29 #include "IntPoint.h"
30 #include "PlatformEvent.h"
31 #include <wtf/WindowsExtras.h>
32
33 #if PLATFORM(GTK)
34 typedef struct _GdkEventScroll GdkEventScroll;
35 #endif
36
37 #if PLATFORM(EFL)
38 typedef struct _Evas_Event_Mouse_Wheel Evas_Event_Mouse_Wheel;
39 #endif
40
41 namespace WebCore {
42
43     class FloatPoint;
44     class FloatSize;
45
46     // Wheel events come in two flavors:
47     // The ScrollByPixelWheelEvent is a fine-grained event that specifies the precise number of pixels to scroll.  It is sent directly by MacBook touchpads on OS X,
48     // and synthesized in other cases where platforms generate line-by-line scrolling events.
49     // The ScrollByPageWheelEvent indicates that the wheel event should scroll an entire page.  In this case WebCore's built in paging behavior is used to page
50     // up and down (you get the same behavior as if the user was clicking in a scrollbar track to page up or page down).
51     enum PlatformWheelEventGranularity : uint8_t {
52         ScrollByPageWheelEvent,
53         ScrollByPixelWheelEvent,
54     };
55
56 #if PLATFORM(COCOA)
57     enum PlatformWheelEventPhase : uint8_t {
58         PlatformWheelEventPhaseNone        = 0,
59         PlatformWheelEventPhaseBegan       = 1 << 0,
60         PlatformWheelEventPhaseStationary  = 1 << 1,
61         PlatformWheelEventPhaseChanged     = 1 << 2,
62         PlatformWheelEventPhaseEnded       = 1 << 3,
63         PlatformWheelEventPhaseCancelled   = 1 << 4,
64         PlatformWheelEventPhaseMayBegin    = 1 << 5,
65     };
66 #endif
67
68     class PlatformWheelEvent : public PlatformEvent {
69     public:
70         PlatformWheelEvent()
71             : PlatformEvent(PlatformEvent::Wheel)
72             , m_deltaX(0)
73             , m_deltaY(0)
74             , m_wheelTicksX(0)
75             , m_wheelTicksY(0)
76             , m_granularity(ScrollByPixelWheelEvent)
77             , m_directionInvertedFromDevice(false)
78 #if PLATFORM(COCOA)
79             , m_hasPreciseScrollingDeltas(false)
80             , m_phase(PlatformWheelEventPhaseNone)
81             , m_momentumPhase(PlatformWheelEventPhaseNone)
82             , m_scrollCount(0)
83             , m_unacceleratedScrollingDeltaX(0)
84             , m_unacceleratedScrollingDeltaY(0)
85 #endif
86         {
87         }
88
89         PlatformWheelEvent(IntPoint position, IntPoint globalPosition, float deltaX, float deltaY, float wheelTicksX, float wheelTicksY, PlatformWheelEventGranularity granularity, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey)
90             : PlatformEvent(PlatformEvent::Wheel, shiftKey, ctrlKey, altKey, metaKey, 0)
91             , m_position(position)
92             , m_globalPosition(globalPosition)
93             , m_deltaX(deltaX)
94             , m_deltaY(deltaY)
95             , m_wheelTicksX(wheelTicksX)
96             , m_wheelTicksY(wheelTicksY)
97             , m_granularity(granularity)
98             , m_directionInvertedFromDevice(false)
99 #if PLATFORM(COCOA)
100             , m_hasPreciseScrollingDeltas(false)
101             , m_phase(PlatformWheelEventPhaseNone)
102             , m_momentumPhase(PlatformWheelEventPhaseNone)
103             , m_scrollCount(0)
104             , m_unacceleratedScrollingDeltaX(0)
105             , m_unacceleratedScrollingDeltaY(0)
106 #endif
107         {
108         }
109
110         PlatformWheelEvent copyTurningVerticalTicksIntoHorizontalTicks() const
111         {
112             PlatformWheelEvent copy = *this;
113
114             copy.m_deltaX = copy.m_deltaY;
115             copy.m_deltaY = 0;
116             copy.m_wheelTicksX = copy.m_wheelTicksY;
117             copy.m_wheelTicksY = 0;
118
119             return copy;
120         }
121
122         PlatformWheelEvent copyIgnoringHorizontalDelta() const
123         {
124             PlatformWheelEvent copy = *this;
125             copy.m_deltaX = 0;
126             return copy;
127         }
128
129         PlatformWheelEvent copyIgnoringVerticalDelta() const
130         {
131             PlatformWheelEvent copy = *this;
132             copy.m_deltaY = 0;
133             return copy;
134         }
135
136         const IntPoint& position() const { return m_position; } // PlatformWindow coordinates.
137         const IntPoint& globalPosition() const { return m_globalPosition; } // Screen coordinates.
138
139         float deltaX() const { return m_deltaX; }
140         float deltaY() const { return m_deltaY; }
141
142         float wheelTicksX() const { return m_wheelTicksX; }
143         float wheelTicksY() const { return m_wheelTicksY; }
144
145         PlatformWheelEventGranularity granularity() const { return m_granularity; }
146
147         bool directionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
148
149 #if PLATFORM(GTK)
150         explicit PlatformWheelEvent(GdkEventScroll*);
151 #endif
152
153 #if PLATFORM(EFL)
154         explicit PlatformWheelEvent(const Evas_Event_Mouse_Wheel*);
155 #endif
156
157 #if PLATFORM(COCOA)
158         bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; }
159         void setHasPreciseScrollingDeltas(bool b) { m_hasPreciseScrollingDeltas = b; }
160         PlatformWheelEventPhase phase() const { return m_phase; }
161         PlatformWheelEventPhase momentumPhase() const { return m_momentumPhase; }
162         unsigned scrollCount() const { return m_scrollCount; }
163         float unacceleratedScrollingDeltaX() const { return m_unacceleratedScrollingDeltaX; }
164         float unacceleratedScrollingDeltaY() const { return m_unacceleratedScrollingDeltaY; }
165         bool useLatchedEventElement() const
166         {
167             return m_phase == PlatformWheelEventPhaseBegan || m_phase == PlatformWheelEventPhaseChanged
168                 || m_momentumPhase == PlatformWheelEventPhaseBegan || m_momentumPhase == PlatformWheelEventPhaseChanged
169                 || (m_phase == PlatformWheelEventPhaseEnded && m_momentumPhase == PlatformWheelEventPhaseNone);
170         }
171         bool shouldConsiderLatching() const
172         {
173             return m_phase == PlatformWheelEventPhaseBegan || m_phase == PlatformWheelEventPhaseMayBegin;
174         }
175         bool shouldResetLatching() const
176         {
177             if (m_phase == PlatformWheelEventPhaseCancelled || m_phase == PlatformWheelEventPhaseMayBegin)
178                 return true;
179             
180             if (m_phase == PlatformWheelEventPhaseNone && m_momentumPhase == PlatformWheelEventPhaseEnded)
181                 return true;
182             
183             return false;
184         }
185 #else
186         bool useLatchedEventElement() const { return false; }
187 #endif
188
189 #if PLATFORM(WIN)
190         PlatformWheelEvent(HWND, WPARAM, LPARAM, bool isMouseHWheel);
191         PlatformWheelEvent(HWND, const FloatSize& delta, const FloatPoint& location);
192 #endif
193
194     protected:
195         IntPoint m_position;
196         IntPoint m_globalPosition;
197         float m_deltaX;
198         float m_deltaY;
199         float m_wheelTicksX;
200         float m_wheelTicksY;
201         PlatformWheelEventGranularity m_granularity;
202         bool m_directionInvertedFromDevice;
203 #if PLATFORM(COCOA)
204         bool m_hasPreciseScrollingDeltas;
205         PlatformWheelEventPhase m_phase;
206         PlatformWheelEventPhase m_momentumPhase;
207         unsigned m_scrollCount;
208         float m_unacceleratedScrollingDeltaX;
209         float m_unacceleratedScrollingDeltaY;
210 #endif
211     };
212
213 } // namespace WebCore
214
215 #endif // PlatformWheelEvent_h