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