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.
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...
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.
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 <firstname.lastname@example.org>
Shrink RenderLayer and ScrollableArea.
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.
Here's the area in the WebKit code where this unholy poison lies:
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.
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.
Happy to see that the issue is getting featured on a number of sites around the interwebs: