Skip navigation

iOS like "rubber band" scrolling in Lion - Safari

20473 Views 132 Replies Latest reply: Mar 6, 2014 9:09 AM by Alex Zavatone RSS
  • Fofer Level 1 Level 1 (115 points)

    Well, aint' that a kick in the head.  I mean, yeah, it's great, and I certainly appreciate it... but Safari is the one app where I notice it most (and am annoyed by it.)  LOL

     

    What the fudge?

  • Király Level 6 Level 6 (9,470 points)
    Currently Being Moderated
    May 9, 2012 7:24 PM (in response to Fofer)

    It doesn't seem to worn in iTunes either.

     

    But it works in every other app I have tried - Hallelujah!

  • Quala Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 9, 2012 7:25 PM (in response to Király)

    How about Chrome? Am I doing something wrong or it doesn't apply there either?

  • Alex Zavatone Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 9, 2012 9:44 PM (in response to baltwo)

    I have the Safari Webkit source so I'll see what I can look into.  Maybe do a custom build there, or a pList preference.

  • Alex Zavatone Level 1 Level 1 (0 points)

    That is probably because the WebView might have a superclass that is an NSScrollView and we would have to set it for the the parent view. 

     

    I'll see what I can look into tomorrow.  I don't have a Mac OS dev license, but just an iOS dev license.

  • ArcticMac Level 2 Level 2 (380 points)
    Currently Being Moderated
    May 10, 2012 8:27 AM (in response to baltwo)

    baltwo wrote:

     

     

    Fofer wrote:

     

    Indeed, I have just pasted the following command into Terminal.app:

     

    defaults write -g NSScrollViewRubberbanding -bool false

     

    And guess what?!?!? It works.  No more inane rubber-banding.  Hurrah! 

     

    But only in TextEdit. 

     

    It doesn't work in Safari, where we are wanting it most.  Boo!!!!

     

    One step closer, though?

     

    Interesting, since it's not documented anywhere that I can find.

     

    There's a key difference between what we're doing here (setting an undocumented preference) and anything you'll find in the documentation, which is that the latter is part of the programming API, and so will is documented, and will definitely work, but will require you to recompile the entire program to apply the change, essentially.  The nice thing about the undocumented preferences is that they will continue to work until either the code that checks them is removed or you set them to be otherwise; custom binaries require a lot of work to keep up with software updates and the like.

  • ArcticMac Level 2 Level 2 (380 points)

    Webkit (Safari, probably Chrome, possibly but probably not iTunes?) uses a custom scrolling implementation so that it can present a consistent scrolling API to other parts of the framework regardless of what platform you're working on.  This is implemented by having a platform-independent layer and then a bunch of platform-dependent parts that are hidden from a typical application.  It would seem that the elasticity is implemented in the Mac specific parts of this, (e.g. in Source/WebCore/platform/mac/ScrollAnimatorMac.mm).

     

    If you look through that file, you'll notice right away some large sections of code that are inside

    #if ENABLE(RUBBER_BANDING) ... #endif

    compiler directives.  So if you are willing to compile the source from scratch, it should be fairly easy to disable this.  The problem is that a) you don't want to be compiling the webkit code from scratch even once really, and b) they push updates to Safari/Chrome on a regular basis, and you _really_ don't want to have to be compiling new copies of it on a regular basis.  (obviously some people do this because they contribute code to webkit, but building webkit is no little task - the source repository is 1.8GB).  A better solution is really needed.

     

    I see two directions that make sense to pursue.  The first is the possibility of re-implementing a couple of key functions (I found a couple, like ScrollAnimatorMac::allowsHorizontalStretching, that essentially return flags for whether the elastic effects should be enabled or not) and then injecting this code into Safari or possibly others using the DYLD_INSERT_LIBRARIES environment variable.

     

    The second is that on my (older) machine, I actually don't have the elastic scrolling by default.  There might be some good way to change a config file here or there to trick your machine into thinking the same is true there.  I haven't managed to find where that happens in the WebKit code though.  It would also have the downside of disabling inertial scrolling, which is something that would actually be kinda nice to keep I'd think.

     

    All of this is made much harder for me to debug/explore/test because of the fact that my mac doesn't support it in the first place.  Gr...

  • ArcticMac Level 2 Level 2 (380 points)
    Currently Being Moderated
    May 10, 2012 9:08 AM (in response to ArcticMac)

    Had a third thought that's probably better: someone should figure out where the most appropriate place is to have WebKit read in the undocumented pref that we found for everything else, compile it once to test that it works, and then submit a bug report with the patch for the change attached.  If the WebKit team is willing to accept the patch, then you get the benefit of having updated the code, but without any of the hassle of needing to continually re-build and replace your local copy of Safari.  On the downside, they could always reject it, and you'd have a bit of a wait for the new build of webkit to make it out into Safari and the like.

  • Alex Zavatone Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 10, 2012 12:54 PM (in response to ArcticMac)

    Actually, the webView's parent is scrollview.  I think that we can just tell the parent to disable elasticity on veiwWillAppear, or in many other areas.  There is a custom ScrollView.h in the source tree.  But there also is this class called ScrollableArea.h.  So we might have to override a different class to fix this for Safari.

     

    Here's some info from the release notes (my emphasis in bold):

     

    2011-10-10  Andreas Kling  <kling@webkit.org>

     

     

            Shrink RenderLayer and ScrollableArea.

            https://bugs.webkit.org/show_bug.cgi?id=69759

     

     

            Reviewed by Antti Koivisto.

     

     

            Rearrange the members of RenderLayer and its base class ScrollableArea

            to maximize struct packing, shrinking RenderLayer by one CPU word on

            32-bit (and two on 64-bit.)

     

     

            This reduces memory consumption by 134 kB (on 64-bit) when loading the

            full HTML5 spec.

     

     

            * platform/ScrollableArea.h:

            (WebCore::ScrollableArea::verticalScrollElasticity):

            (WebCore::ScrollableArea::horizontalScrollElasticity):

  • Alex Zavatone Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 10, 2012 1:14 PM (in response to ArcticMac)

    Here's the area in the WebKit code where this unholy poison lies:

     

    ScrollableArea.h

     

    lines 212 and 213:

     

        unsigned m_verticalScrollElasticity : 2; // ScrollElasticity,

         unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity

     

    There are also enums (settings or definitions) for ScrollElasticityAutomatic and ScrollElasticityAllowed.

     

    Where these exist in the code can be changed to ScrollElasticityNone and the app rebuilt.  OR, we can find out how to write this to a defaults or Safari preference pList.

     

    In ScrollAnimatorMac.mm, there is a section that responds to ScrollElasticityAutomatic and this can be pulled and simply replaced with return false;

     

    There also is a ScrollElasticityController.h file and it is referenced from ScrollAnimatorMac.mm.  In it is #if ENABLE(RUBBER_BANDING) which handles how to respond to that lameness. 

     

    AHA.  This leads me to platform.h (there are more than one of these) which defines ENABLE_RUBBER_BANDING as 1

     

    There might be a few areas in Safari where we need to turn this off and redefining RUBBER_BANDING to 0 might need to happen too.

  • ArcticMac Level 2 Level 2 (380 points)

    That may be the best place to put it; but again, there aren't any NSScrollView objects involved (WebCore::ScrollView is a different beast), so the mechanism for disabling it is different from NSScrollView.

  • Alex Zavatone Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 10, 2012 5:08 PM (in response to ArcticMac)

    Yeah, on iOS, WebView inherits from UIScrollView and that's where the "bounces" thing is enabled, I was basing my decisions off of that model.  Looks like reality on the Mac is somewhat different than plain old UIWebViews on iOS.

  • Alex Zavatone Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 11, 2012 10:30 AM (in response to Király)

    K, just a note, it is SO NICE to not be irritated every time I scroll to the end of a document, that I'm almost ready to actually use Lion.

     

    It just boggles my mind that Apple didn't put in a publicly available switch for this.

     

    What is terribly annoying though is the Safari view "wobbling" as I mouse with my left hand and Safari thinks that it needs to wobble my page's contents to let me know "I can scroll if you want me to".  Just so horrible, since this happens by mistake all the time AND I have the scroll bars set to display all the time.

     

    I have no idea why Apple doesn't automatically disable this view bouncing and view wobbling if you have scrollbars set to display all the time.

     

    We still have work to do though.

     

    I hope to build WebKit tonight under Lion to see if I can kill this annoying behaviour for good.  I'll bet that iTunes uses the same aproach, so we can then find which variable needs to be written to defaults through the terminal to disable this behaviour as well. 

  • Quala Level 1 Level 1 (0 points)
    Currently Being Moderated
    May 11, 2012 10:40 AM (in response to tbonecopper)

    Happy to see that the issue is getting featured on a number of sites around the interwebs:

     

    Lifehacker: http://lifehacker.com/5909402/turn-off-elastic-scrolling-in-os-x-lion?tag=macosx

    Macworld: http://hints.macworld.com/article.php?story=20120509063823940

  • Király Level 6 Level 6 (9,470 points)
    Currently Being Moderated
    May 11, 2012 10:43 AM (in response to Quala)

    Yeah no kidding - it's gone viral. Do a Google search on NSScrollViewRubberbanding and you'll see that is has spread like wildfire. Many thanks Alex.

1 ... 5 6 7 8 9 Previous Next

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.