| Index: webkit/glue/webinputevent_mac.mm
|
| ===================================================================
|
| --- webkit/glue/webinputevent_mac.mm (revision 12444)
|
| +++ webkit/glue/webinputevent_mac.mm (working copy)
|
| @@ -24,6 +24,7 @@
|
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| */
|
|
|
| +#include <ApplicationServices/ApplicationServices.h>
|
| #import <Cocoa/Cocoa.h>
|
|
|
| #include "config.h"
|
| @@ -37,7 +38,7 @@
|
|
|
| // WebMouseEvent --------------------------------------------------------------
|
|
|
| -WebMouseEvent::WebMouseEvent(NSEvent *event, NSView* view) {
|
| +WebMouseEvent::WebMouseEvent(NSEvent* event, NSView* view) {
|
| switch ([event type]) {
|
| case NSMouseExited:
|
| type = MOUSE_LEAVE;
|
| @@ -113,7 +114,7 @@
|
|
|
| // WebMouseWheelEvent ---------------------------------------------------------
|
|
|
| -WebMouseWheelEvent::WebMouseWheelEvent(NSEvent *event, NSView* view) {
|
| +WebMouseWheelEvent::WebMouseWheelEvent(NSEvent* event, NSView* view) {
|
| type = MOUSE_WHEEL;
|
| button = BUTTON_NONE;
|
|
|
| @@ -134,17 +135,133 @@
|
| x = location.x;
|
| y = [view frame].size.height - location.y; // flip y
|
|
|
| - // Convert wheel delta amount to a number of pixels to scroll.
|
| - // Cocoa sets deltaX instead of deltaY if shift is pressed when scrolling
|
| - // with a scroll wheel, no need to do that ourselves.
|
| - static const float kScrollbarPixelsPerTick = 40.0f;
|
| + // Of Mice and Men
|
| + // ---------------
|
| + //
|
| + // There are three types of scroll data available on a scroll wheel CGEvent.
|
| + // Apple's documentation ([1]) is rather vague in their differences, and not
|
| + // terribly helpful in deciding which to use. This is what's really going on.
|
| + //
|
| + // First, these events behave very differently depending on whether a standard
|
| + // wheel mouse is used (one that scrolls in discrete units) or a
|
| + // trackpad/Mighty Mouse is used (which both provide continuous scrolling).
|
| + // You must check to see which was used for the event by testing the
|
| + // kCGScrollWheelEventIsContinuous field.
|
| + //
|
| + // Second, these events refer to "axes". Axis 1 is the y-axis, and axis 2 is
|
| + // the x-axis.
|
| + //
|
| + // Third, there is a concept of mouse acceleration. Scrolling the same amount
|
| + // of physical distance will give you different results logically depending on
|
| + // whether you scrolled a little at a time or in one continuous motion. Some
|
| + // fields account for this while others do not.
|
| + //
|
| + // Fourth, for trackpads there is a concept of chunkiness. When scrolling
|
| + // continuously, events can be delivered in chunks. That is to say, lots of
|
| + // scroll events with delta 0 will be delivered, and every so often an event
|
| + // with a non-zero delta will be delivered, containing the accumulated deltas
|
| + // from all the intermediate moves. [2]
|
| + //
|
| + // For notchy wheel mice (kCGScrollWheelEventIsContinuous == 0)
|
| + // ------------------------------------------------------------
|
| + //
|
| + // kCGScrollWheelEventDeltaAxis*
|
| + // This is the rawest of raw events. For each mouse notch you get a value of
|
| + // +1/-1. This does not take acceleration into account and thus is less
|
| + // useful for building UIs.
|
| + //
|
| + // kCGScrollWheelEventPointDeltaAxis*
|
| + // This is smarter. In general, for each mouse notch you get a value of
|
| + // +1/-1, but this _does_ take acceleration into account, so you will get
|
| + // larger values on longer scrolls. This field would be ideal for building
|
| + // UIs except for one nasty bug: when the shift key is pressed, this set of
|
| + // fields fails to move the value into the axis2 field (the other two types
|
| + // of data do). This wouldn't be so bad except for the fact that while the
|
| + // number of axes is used in the creation of a CGScrollWheelEvent, there is
|
| + // no way to get that information out of the event once created.
|
| + //
|
| + // kCGScrollWheelEventFixedPtDeltaAxis*
|
| + // This is a fixed value, and for each mouse notch you get a value of
|
| + // +0.1/-0.1 (but, like above, scaled appropriately for acceleration). This
|
| + // value takes acceleration into account, and in fact is identical to the
|
| + // results you get from -[NSEvent delta*]. (That is, if you linked on Tiger
|
| + // or greater; see [2] for details.)
|
| + //
|
| + // A note about continuous devices
|
| + // -------------------------------
|
| + //
|
| + // There are two devices that provide continuous scrolling events (trackpads
|
| + // and Mighty Mouses) and they behave rather differently. The Mighty Mouse
|
| + // behaves a lot like a regular mouse. There is no chunking, and the
|
| + // FixedPtDelta values are the PointDelta values multiplied by 0.1. With the
|
| + // trackpad, though, there is chunking. While the FixedPtDelta values are
|
| + // reasonable (they occur about every fifth event but have values five times
|
| + // larger than usual) the Delta values are unreasonable. They don't appear to
|
| + // accumulate properly.
|
| + //
|
| + // For continuous devices (kCGScrollWheelEventIsContinuous != 0)
|
| + // -------------------------------------------------------------
|
| + //
|
| + // kCGScrollWheelEventDeltaAxis*
|
| + // This provides values with no acceleration. With a trackpad, these values
|
| + // are chunked but each non-zero value does not appear to be cumulative.
|
| + // This seems to be a bug.
|
| + //
|
| + // kCGScrollWheelEventPointDeltaAxis*
|
| + // This provides values with acceleration. With a trackpad, these values are
|
| + // not chunked and are highly accurate.
|
| + //
|
| + // kCGScrollWheelEventFixedPtDeltaAxis*
|
| + // This provides values with acceleration. With a trackpad, these values are
|
| + // chunked but unlike Delta events are properly cumulative.
|
| + //
|
| + // Summary
|
| + // -------
|
| + //
|
| + // In general the best approach to take is: determine if the event is
|
| + // continuous. If it is not, then use the FixedPtDelta events (or just stick
|
| + // with Cocoa events). They provide both acceleration and proper horizontal
|
| + // scrolling. If the event is continuous, then doing pixel scrolling with the
|
| + // PointDelta is the way to go. In general, avoid the Delta events. They're
|
| + // the oldest (dating back to 10.4, before CGEvents were public) but they lack
|
| + // acceleration and precision, making them useful only in specific edge cases.
|
| + //
|
| + // References
|
| + // ----------
|
| + //
|
| + // [1] <http://developer.apple.com/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html>
|
| + // [2] <http://developer.apple.com/releasenotes/Cocoa/AppKitOlderNotes.html>
|
| + // Scroll to the section headed "NSScrollWheel events".
|
| + //
|
| + // P.S. The "smooth scrolling" option in the system preferences is utterly
|
| + // unrelated to any of this.
|
|
|
| - wheel_ticks_x = [event deltaX];
|
| - delta_x = wheel_ticks_x * kScrollbarPixelsPerTick;
|
| + CGEventRef cg_event = [event CGEvent];
|
| + DCHECK(cg_event);
|
|
|
| - wheel_ticks_y = [event deltaY];
|
| - delta_y = wheel_ticks_y * kScrollbarPixelsPerTick;
|
| + // Wheel Ticks are supposed to be raw, unaccelerated values, one per physical
|
| + // mouse wheel notch. The delta event is perfect for this (being a good
|
| + // "specific edge case" as mentioned above). For trackpads, unfortunately, we
|
| + // don't have anything better.
|
|
|
| + wheel_ticks_y = CGEventGetIntegerValueField(cg_event,
|
| + kCGScrollWheelEventDeltaAxis1);
|
| + wheel_ticks_x = CGEventGetIntegerValueField(cg_event,
|
| + kCGScrollWheelEventDeltaAxis2);
|
| +
|
| + if (CGEventGetIntegerValueField(cg_event, kCGScrollWheelEventIsContinuous)) {
|
| + delta_y = CGEventGetIntegerValueField(cg_event,
|
| + kCGScrollWheelEventPointDeltaAxis1);
|
| + delta_x = CGEventGetIntegerValueField(cg_event,
|
| + kCGScrollWheelEventPointDeltaAxis2);
|
| + } else {
|
| + // Convert wheel delta amount to a number of pixels to scroll.
|
| + static const double kScrollbarPixelsPerCocoaTick = 40.0;
|
| +
|
| + delta_x = [event deltaX] * kScrollbarPixelsPerCocoaTick;
|
| + delta_y = [event deltaY] * kScrollbarPixelsPerCocoaTick;
|
| + }
|
| +
|
| scroll_by_page = false;
|
| }
|
|
|
| @@ -163,7 +280,7 @@
|
|
|
| namespace WebCore {
|
|
|
| -static inline bool isKeyUpEvent(NSEvent *event)
|
| +static inline bool isKeyUpEvent(NSEvent* event)
|
| {
|
| if ([event type] != NSFlagsChanged)
|
| return [event type] == NSKeyUp;
|
| @@ -643,7 +760,7 @@
|
| return @"";
|
| }
|
|
|
| - NSString *s = [event charactersIgnoringModifiers];
|
| + NSString* s = [event charactersIgnoringModifiers];
|
| if ([s length] != 1) {
|
| return @"Unidentified";
|
| }
|
| @@ -941,7 +1058,7 @@
|
| // End Apple code.
|
| // ---------------------------------------------------------------------
|
|
|
| -WebKeyboardEvent::WebKeyboardEvent(NSEvent *event) {
|
| +WebKeyboardEvent::WebKeyboardEvent(NSEvent* event) {
|
| system_key = false;
|
| type = WebCore::isKeyUpEvent(event) ? KEY_UP : KEY_DOWN;
|
|
|
|
|