#1522 Cocoa scroll wheel too slow

Bug
closed-fixed
Neil Hodgson
5
2013-10-15
2013-09-05
chinhster
No

Scrolling content with a trackpad or a Magic Mouse is fine. However, scrolling content using a mouse with a scroll wheel is very slow and requires furious scrolling with the scroll wheel just to scroll a few lines. I'm guessing it's because the InnerView class ensures scrolling is aligned to whole lines but the y-coordinate change for a scroll wheel can be very small.

Here's my fix to ScintillaView.mm:

  • (void) scrollWheel: (NSEvent *) theEvent
    {
    if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
    mOwner.backend->MouseWheel(theEvent);
    } else {
    int deltaX = theEvent.deltaX < 0. ? -floorf(theEvent.deltaX) : -ceilf(theEvent.deltaX);
    int deltaY = theEvent.deltaY < 0. ? -floorf(theEvent.deltaY) : -ceilf(theEvent.deltaY);
    mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
    }
    }

Related

Bugs: #1522

Discussion

  • Neil Hodgson
    Neil Hodgson
    2013-09-05

    The proposed change disables kinetic scrolling and makes scrolling with a Magic Mouse work poorly.

    Plugged in a wheel mouse and mostly it worked well. Its common to see 15-20 lines scrolled for a full wheel scroll gesture. The only problem was that small movements of the mouse wheel had no effect.

    Tested on 10.7 and there could be differences between OS X releases.

     
  • chinhster
    chinhster
    2013-09-05

    Sorry about that, I'll look at it again when I get back to the office. I
    tried it both with a Magic Mouse and wheel mouse and it worked just fine
    even with small wheel movements. I didn't verify kinetic scrolling though.

    -Chinh Nguyen

    On Sep 5, 2013, at 4:49 PM, Neil Hodgson nyamatongwe@users.sf.net wrote:

    The proposed change disables kinetic scrolling and makes scrolling with a
    Magic Mouse work poorly.

    Plugged in a wheel mouse and mostly it worked well. Its common to see 15-20
    lines scrolled for a full wheel scroll gesture. The only problem was that
    small movements of the mouse wheel had no effect.

    Tested on 10.7 and there could be differences between OS X releases.

    Status: open
    Labels: scroll wheel scrollWheel
    Created: Thu Sep 05, 2013 02:49 PM UTC by chinhster
    Last Updated: Thu Sep 05, 2013 02:49 PM UTC
    Owner: nobody

    Scrolling content with a trackpad or a Magic Mouse is fine. However,
    scrolling content using a mouse with a scroll wheel is very slow and
    requires furious scrolling with the scroll wheel just to scroll a few
    lines. I'm guessing it's because the InnerView class ensures scrolling is
    aligned to whole lines but the y-coordinate change for a scroll wheel can
    be very small.

    Here's my fix to ScintillaView.mm:

    • (void) scrollWheel: (NSEvent *) theEvent
      {
      if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
      mOwner.backend->MouseWheel(theEvent);
      } else {
      int deltaX = theEvent.deltaX < 0. ? -floorf(theEvent.deltaX) :
      -ceilf(theEvent.deltaX);
      int deltaY = theEvent.deltaY < 0. ? -floorf(theEvent.deltaY) :
      -ceilf(theEvent.deltaY);
      mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
      }
      }

    Sent from sourceforge.net because you indicated interest in
    https://sourceforge.net/p/scintilla/bugs/1522/

    To unsubscribe from further messages, please visit
    https://sourceforge.net/auth/subscriptions/

     

    Related

    Bugs: #1522

    • Neil Hodgson
      Neil Hodgson
      2013-09-05

      I meant that the current release code worked well for me with a wheel mouse.

       
  • chinhster
    chinhster
    2013-09-06

    You're right, ScintillaTest scrolls just fine with a scroll wheel but for
    some reason, my ScintillaView only scrolls about 3 lines with a full turn
    of the scroll wheel. I'll take a look. Thanks.

    -Chinh Nguyen

    On Sep 5, 2013, at 5:32 PM, Neil Hodgson nyamatongwe@users.sf.net wrote:

    I meant that the current release code worked well for me with a wheel mouse.

    Status: open
    Labels: scroll wheel scrollWheel
    Created: Thu Sep 05, 2013 02:49 PM UTC by chinhster
    Last Updated: Thu Sep 05, 2013 09:49 PM UTC
    Owner: nobody

    Scrolling content with a trackpad or a Magic Mouse is fine. However,
    scrolling content using a mouse with a scroll wheel is very slow and
    requires furious scrolling with the scroll wheel just to scroll a few
    lines. I'm guessing it's because the InnerView class ensures scrolling is
    aligned to whole lines but the y-coordinate change for a scroll wheel can
    be very small.

    Here's my fix to ScintillaView.mm:

    • (void) scrollWheel: (NSEvent *) theEvent
      {
      if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
      mOwner.backend->MouseWheel(theEvent);
      } else {
      int deltaX = theEvent.deltaX < 0. ? -floorf(theEvent.deltaX) :
      -ceilf(theEvent.deltaX);
      int deltaY = theEvent.deltaY < 0. ? -floorf(theEvent.deltaY) :
      -ceilf(theEvent.deltaY);
      mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
      }
      }

    Sent from sourceforge.net because you indicated interest in
    https://sourceforge.net/p/scintilla/bugs/1522/

    To unsubscribe from further messages, please visit
    https://sourceforge.net/auth/subscriptions/

     

    Related

    Bugs: #1522

  • chinhster
    chinhster
    2013-09-06

    I figured out what the problem is. I have an observer for
    NSTextViewDidChangeSelectionNotification. The method for the observer
    hides the caret when there is a selection (typical Mac behavior)
    using SCI_SETCARETWIDTH, and does hides the highlight for the caret line
    when a selection spans multiple lines using SCI_SETCARETLINEVISIBLE. The
    problem is that NSTextViewDidChangeSelectionNotification is posted for
    every SCN_UPDATEUI. An SCN_UPDATEUI notification is posted while
    scrolling. Using either SCI_SETCARETWIDTH or SCI_SETCARETLINEVISIBLE will
    cause the slow scrolling during an SCN_UPDATEUI notification.

    Caching the selected range and checking the current selection against the
    previous selection in my observer method seems to clear the problem up but
    I'll have to do more testing. I'm curious as to why modifying the caret is
    having an effect on scrolling though.

    Here's a different proposed change that allows small movements of the mouse
    wheel to scroll while not, as far as I can tell, affecting kinetic
    scrolling:

    • (void) scrollWheel: (NSEvent *) theEvent

    {

    if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {

    mOwner.backend->MouseWheel(theEvent);
    

    } else {

      BOOL hasPreciseScrollingDeltas = NO;
    
      if ([theEvent respondsToSelector:@selector(hasPreciseScrollingDeltas)])
    

    {

        hasPreciseScrollingDeltas = theEvent.hasPreciseScrollingDeltas;
    
      }
    
      if (!hasPreciseScrollingDeltas && (((int)theEvent.deltaX == 0 &&
    

    theEvent.deltaX != 0.) || ((int)theEvent.deltaY == 0 && theEvent.deltaY !=
    0.))) {

        int deltaX = theEvent.deltaX < 0. ? 1 : -1;
    
        int deltaY = theEvent.deltaY < 0. ? 1 : -1;
    
        mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
    
      }
    
      else {
    
        [super scrollWheel:theEvent];
    
      }
    

    }

    }

    I found that this change duplicates the previous scrolling behavior (not
    scrolling any faster or slower) with the added benefit of handling the
    small scroll wheel movements. The flaw of course is that if either deltaX
    or deltaY is less than 1 and greater than 0, it'll only scroll a line or
    column at a time but I didn't notice that being a problem. I found that
    hasPreciseScrollingDeltas is true for a Magic Mouse and trackpad so it
    doesn't affect them. The only possible mouse I can see being affected
    would be a Mighty Mouse assuming that hasPreciseScrollingDeltas is false
    for it. But I didn't notice any issues with a Magic Mouse even when I
    didn't check hasPreciseScrollingDeltas.

    Obviously, you can ignore the code if you don't find it useful.

    On Thu, Sep 5, 2013 at 4:49 PM, Neil Hodgson nyamatongwe@users.sf.netwrote:

    The proposed change disables kinetic scrolling and makes scrolling with a
    Magic Mouse work poorly.

    Plugged in a wheel mouse and mostly it worked well. Its common to see
    15-20 lines scrolled for a full wheel scroll gesture. The only problem was
    that small movements of the mouse wheel had no effect.

    Tested on 10.7 and there could be differences between OS X releases.

    Status: open
    Labels: scroll wheel scrollWheel
    Created: Thu Sep 05, 2013 02:49 PM UTC by chinhster
    Last Updated: Thu Sep 05, 2013 02:49 PM UTC
    Owner: nobody

    Scrolling content with a trackpad or a Magic Mouse is fine. However,
    scrolling content using a mouse with a scroll wheel is very slow and
    requires furious scrolling with the scroll wheel just to scroll a few
    lines. I'm guessing it's because the InnerView class ensures scrolling is
    aligned to whole lines but the y-coordinate change for a scroll wheel can
    be very small.

    Here's my fix to ScintillaView.mm:

    • (void) scrollWheel: (NSEvent *) theEvent
      {
      if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
      mOwner.backend->MouseWheel(theEvent);
      } else {
      int deltaX = theEvent.deltaX < 0. ? -floorf(theEvent.deltaX) :
      -ceilf(theEvent.deltaX);
      int deltaY = theEvent.deltaY < 0. ? -floorf(theEvent.deltaY) :
      -ceilf(theEvent.deltaY);
      mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
      }
      }

    Sent from sourceforge.net because you indicated interest in
    https://sourceforge.net/p/scintilla/bugs/1522/

    To unsubscribe from further messages, please visit
    https://sourceforge.net/auth/subscriptions/

     

    Related

    Bugs: #1522

    • Neil Hodgson
      Neil Hodgson
      2013-09-06

      The problem is that NSTextViewDidChangeSelectionNotification is posted for
      every SCN_UPDATEUI. An SCN_UPDATEUI notification is posted while scrolling.

      There are 4 reasons for SCN_UPDATEUI reported as bit flags in the updated field: content change, update selection, x scroll, and v scroll. The two scrolling bits could be masked out to see if NSTextViewDidChangeSelectionNotification should be sent.

       
  • chinhster
    chinhster
    2013-09-06

    Will give it a try, thanks!

    -Chinh Nguyen

    On Sep 6, 2013, at 5:21 PM, Neil Hodgson nyamatongwe@users.sf.net wrote:

    The problem is that NSTextViewDidChangeSelectionNotification is posted for
    every SCN_UPDATEUI. An SCN_UPDATEUI notification is posted while scrolling.

    There are 4 reasons for SCN_UPDATEUI reported as bit flags in the updated
    field: content change, update selection, x scroll, and v scroll. The two
    scrolling bits could be masked out to see if
    NSTextViewDidChangeSelectionNotification should be sent.


    Status: open
    Labels: scroll wheel scrollWheel
    Created: Thu Sep 05, 2013 02:49 PM UTC by chinhster
    Last Updated: Thu Sep 05, 2013 09:49 PM UTC
    Owner: nobody

    Scrolling content with a trackpad or a Magic Mouse is fine. However,
    scrolling content using a mouse with a scroll wheel is very slow and
    requires furious scrolling with the scroll wheel just to scroll a few
    lines. I'm guessing it's because the InnerView class ensures scrolling is
    aligned to whole lines but the y-coordinate change for a scroll wheel can
    be very small.

    Here's my fix to ScintillaView.mm:

    • (void) scrollWheel: (NSEvent *) theEvent
      {
      if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
      mOwner.backend->MouseWheel(theEvent);
      } else {
      int deltaX = theEvent.deltaX < 0. ? -floorf(theEvent.deltaX) :
      -ceilf(theEvent.deltaX);
      int deltaY = theEvent.deltaY < 0. ? -floorf(theEvent.deltaY) :
      -ceilf(theEvent.deltaY);
      mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
      }
      }

    Sent from sourceforge.net because you indicated interest in
    https://sourceforge.net/p/scintilla/bugs/1522/

    To unsubscribe from further messages, please visit
    https://sourceforge.net/auth/subscriptions/

     

    Related

    Bugs: #1522

  • Neil Hodgson
    Neil Hodgson
    2013-09-07

    The change to SCN_UPDATEUI is worthwhile since it will reduce overhead for many clients so will be committed if it works for you.

    Another issue is that changing visual style attributes like caret width causes caches to be flushed and a redraw scheduled. Its fairly heavy and can be avoided when the attribute is being set to the value it currently has. Because style attributes are often set up once and to avoid a lot of extra checking code the style change work including redraw is unconditional. In your application code you could check the current caret width and only call Scintilla if it really needs to change.

     
  • chinhster
    chinhster
    2013-09-07

    Good suggestion on checking the caret width. I did look through the code
    and noticed the style redraw and it should've occurred to me to check if
    the caret width value was changing.

    -Chinh Nguyen

    On Sep 6, 2013, at 7:27 PM, Neil Hodgson nyamatongwe@users.sf.net wrote:

    The change to SCN_UPDATEUI is worthwhile since it will reduce overhead for
    many clients so will be committed if it works for you.

    Another issue is that changing visual style attributes like caret width
    causes caches to be flushed and a redraw scheduled. Its fairly heavy and
    can be avoided when the attribute is being set to the value it currently
    has. Because style attributes are often set up once and to avoid a lot of
    extra checking code the style change work including redraw is
    unconditional. In your application code you could check the current caret
    width and only call Scintilla if it really needs to change.


    Status: open
    Labels: scroll wheel scrollWheel
    Created: Thu Sep 05, 2013 02:49 PM UTC by chinhster
    Last Updated: Thu Sep 05, 2013 09:49 PM UTC
    Owner: nobody

    Scrolling content with a trackpad or a Magic Mouse is fine. However,
    scrolling content using a mouse with a scroll wheel is very slow and
    requires furious scrolling with the scroll wheel just to scroll a few
    lines. I'm guessing it's because the InnerView class ensures scrolling is
    aligned to whole lines but the y-coordinate change for a scroll wheel can
    be very small.

    Here's my fix to ScintillaView.mm:

    • (void) scrollWheel: (NSEvent *) theEvent
      {
      if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) {
      mOwner.backend->MouseWheel(theEvent);
      } else {
      int deltaX = theEvent.deltaX < 0. ? -floorf(theEvent.deltaX) :
      -ceilf(theEvent.deltaX);
      int deltaY = theEvent.deltaY < 0. ? -floorf(theEvent.deltaY) :
      -ceilf(theEvent.deltaY);
      mOwner.backend->WndProc(SCI_LINESCROLL, deltaX, deltaY) ;
      }
      }

    Sent from sourceforge.net because you indicated interest in
    https://sourceforge.net/p/scintilla/bugs/1522/

    To unsubscribe from further messages, please visit
    https://sourceforge.net/auth/subscriptions/

     

    Related

    Bugs: #1522

  • chinhster
    chinhster
    2013-09-09

    Checking the caret width and the caret visible line settings before changing them worked. In addition, I changed the notification() function to only post a NSTextViewDidChangeSelectionNotification notification for an SC_UPDATEUI if the SC_UPDATE_SELECTION bit is true.

    Each change individually solved the slow scrolling problem but I'm going ahead and using them both.

     
  • Neil Hodgson
    Neil Hodgson
    2013-09-12

    Fix committed as [acd8c1].

     

    Related

    Commit: [acd8c1]

  • Neil Hodgson
    Neil Hodgson
    2013-09-12

    • labels: scroll wheel scrollWheel --> scroll wheel scrollWheel, cocoa
    • status: open --> open-fixed
    • assigned_to: Neil Hodgson
     
  • Neil Hodgson
    Neil Hodgson
    2013-10-15

    • status: open-fixed --> closed-fixed