Still havent got a test case, but have dug into my code more. I had a form update triggered by scrolling, which calls BasicForm.markInvalid() and it turns out that triggered the scrolling problem!
So my clunky workaround is to do:
Before I markInvalid, and this after:
var originalScrollPosition = MeldUI.maingrid.getEl().down('.x-grid-view').getScroll();
That solves the problem thankfully.
var newPosition = MeldUI.maingrid.getEl().down('.x-grid-view').getScroll();
if (newPosition.top < 5 && originalScrollPosition.top > 5)
MeldUI.maingrid.getEl().down('.x-grid-view').scrollTo('top', originalScrollPosition.top, false);
Some other info: I'm using row editing. Inserted records go at the bottom. It only happens after the first insert, subsequent inserts are fine.