@@ -589,11 +589,10 @@ bool dispatch_mouse_wheel(uint64_t timestamp, CGEventRef event_ref) {
589589 bool consumed = false;
590590
591591 // Reset the click count and previous button.
592- click_count = 1 ;
592+ click_count = 0 ;
593593 click_button = MOUSE_NOBUTTON ;
594594
595595 // Check to see what axis was rotated, we only care about axis 1 for vertical rotation.
596- // TODO Implement horizontal scrolling by examining axis 2.
597596 // NOTE kCGScrollWheelEventDeltaAxis3 is currently unused.
598597 if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 ) != 0
599598 || CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis2 ) != 0 ) {
@@ -606,55 +605,60 @@ bool dispatch_mouse_wheel(uint64_t timestamp, CGEventRef event_ref) {
606605 uio_event .type = EVENT_MOUSE_WHEEL ;
607606 uio_event .mask = get_modifiers ();
608607
609- uio_event .data .wheel .clicks = click_count ;
610608 uio_event .data .wheel .x = event_point .x ;
611609 uio_event .data .wheel .y = event_point .y ;
612610
613- // TODO Figure out if kCGScrollWheelEventDeltaAxis2 causes mouse events with zero rotation.
614- if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventIsContinuous ) == 0 ) {
615- // Scrolling data is line-based.
616- uio_event .data .wheel .type = WHEEL_BLOCK_SCROLL ;
617- } else {
618- // Scrolling data is pixel-based.
619- uio_event .data .wheel .type = WHEEL_UNIT_SCROLL ;
620- }
621-
622- // TODO The result of kCGScrollWheelEventIsContinuous may effect this value.
623- // Calculate the amount based on the Point Delta / Event Delta. Integer sign should always be homogeneous resulting in a positive result.
624- // NOTE kCGScrollWheelEventFixedPtDeltaAxis1 a floating point value (+0.1/-0.1) that takes acceleration into account.
625- // NOTE kCGScrollWheelEventPointDeltaAxis1 will not build on OS X < 10.5
626-
627- if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 ) != 0 ) {
628- uio_event .data .wheel .amount = CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventPointDeltaAxis1 ) / CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 );
611+ uio_event .data .wheel .delta = 0 ;
612+ uio_event .data .wheel .rotation = 0 ;
629613
630- // Scrolling data uses a fixed-point 16.16 signed integer format (Ex: 1.0 = 0x00010000).
631- uio_event .data .wheel .rotation = CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 ) * -1 ;
614+ /* This function returns the scale of pixels per line in the specified event source. For example, if the
615+ * scale in the event source is 10.5 pixels per line, this function would return 10.5. Every scrolling event
616+ * can be interpreted to be scrolling by pixel or by line. By default, the scale is about ten pixels per
617+ * line. You can alter the scale with the function CGEventSourceSetPixelsPerLine.
618+ * See: https://gist.github.com/svoisen/5215826 */
619+ CGEventSourceRef source = CGEventCreateSourceFromEvent (event_ref );
620+ double ppl = CGEventSourceGetPixelsPerLine (source );
632621
633- } else if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis2 ) != 0 ) {
634- uio_event .data .wheel .amount = CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventPointDeltaAxis2 ) / CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis2 );
622+ if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventIsContinuous ) != 0 ) {
623+ // continuous device (trackpad)
624+ ppl *= 1 ;
625+ uio_event .data .wheel .type = WHEEL_BLOCK_SCROLL ;
635626
636- // Scrolling data uses a fixed-point 16.16 signed integer format (Ex: 1.0 = 0x00010000).
637- uio_event .data .wheel .rotation = CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis2 ) * -1 ;
627+ if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 ) != 0 ) {
628+ uio_event .data .wheel .direction = WHEEL_VERTICAL_DIRECTION ;
629+ uio_event .data .wheel .rotation = (int16_t ) (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventPointDeltaAxis1 ) * ppl * 1 );
630+ } else if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis2 ) != 0 ) {
631+ uio_event .data .wheel .direction = WHEEL_HORIZONTAL_DIRECTION ;
632+ uio_event .data .wheel .rotation = (int16_t ) (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventPointDeltaAxis2 ) * ppl * 1 );
633+ }
638634 } else {
639- //Fail Silently if a 3rd axis gets added without changing this section of code.
640- uio_event .data .wheel .amount = 0 ;
641- uio_event .data .wheel .rotation = 0 ;
635+ // non-continuous device (wheel mice)
636+ ppl *= 10 ;
637+ uio_event .data .wheel .type = WHEEL_UNIT_SCROLL ;
638+
639+ if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 ) != 0 ) {
640+ uio_event .data .wheel .direction = WHEEL_VERTICAL_DIRECTION ;
641+ uio_event .data .wheel .rotation = (int16_t ) (CGEventGetDoubleValueField (event_ref , kCGScrollWheelEventFixedPtDeltaAxis1 ) * ppl * 10 );
642+ } else if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis2 ) != 0 ) {
643+ uio_event .data .wheel .direction = WHEEL_HORIZONTAL_DIRECTION ;
644+ uio_event .data .wheel .rotation = (int16_t ) (CGEventGetDoubleValueField (event_ref , kCGScrollWheelEventFixedPtDeltaAxis2 ) * ppl * 10 );
645+ }
642646 }
643647
648+ uio_event .data .wheel .delta = (uint16_t ) ppl ;
644649
645- if (CGEventGetIntegerValueField (event_ref , kCGScrollWheelEventDeltaAxis1 ) != 0 ) {
646- // Wheel Rotated Up or Down.
647- uio_event .data .wheel .direction = WHEEL_VERTICAL_DIRECTION ;
648- } else { // data->event.u.u.detail == WheelLeft || data->event.u.u.detail == WheelRight
649- // Wheel Rotated Left or Right.
650- uio_event .data .wheel .direction = WHEEL_HORIZONTAL_DIRECTION ;
650+ if (source ) {
651+ CFRelease (source );
651652 }
652653
653- logger (LOG_LEVEL_DEBUG , "%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n" ,
654- __FUNCTION__ , __LINE__ , uio_event .data .wheel .type ,
655- uio_event .data .wheel .amount * uio_event .data .wheel .rotation ,
654+ logger (LOG_LEVEL_DEBUG , "%s [%u]: Mouse wheel %i / %u of type %u in the %u direction at %u, %u.\n" ,
655+ __FUNCTION__ , __LINE__ ,
656+ uio_event .data .wheel .rotation ,
657+ uio_event .data .wheel .delta ,
658+ uio_event .data .wheel .type ,
656659 uio_event .data .wheel .direction ,
657- uio_event .data .wheel .x , uio_event .data .wheel .y );
660+ uio_event .data .wheel .x ,
661+ uio_event .data .wheel .y );
658662
659663 // Fire mouse wheel event.
660664 dispatch_event (& uio_event );
0 commit comments