зеркало из https://github.com/mozilla/gecko-dev.git
Bug 189308. Fire onscroll for all kinds of scrollling, and consolidate multiple scrolls into one event, and delay firing the event until we've returned to our PLevent loop. r+sr=dbaron
This commit is contained in:
Родитель
3621391cc9
Коммит
55d745e0bb
|
@ -71,12 +71,16 @@
|
|||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsReflowPath.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPresState.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
static const char kEventQueueServiceCID[] = NS_EVENTQUEUESERVICE_CONTRACTID;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------nsHTMLScrollFrame-------------------------------------------
|
||||
|
@ -1317,6 +1321,13 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aI
|
|||
{
|
||||
}
|
||||
|
||||
nsGfxScrollFrameInner::~nsGfxScrollFrameInner()
|
||||
{
|
||||
if (mScrollEventQueue) {
|
||||
mScrollEventQueue->RevokeEvents(this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::AddRef(void)
|
||||
{
|
||||
return 1;
|
||||
|
@ -1679,11 +1690,11 @@ nsGfxScrollFrameInner::ScrollPositionDidChange(nsIScrollableView* aScrollable, n
|
|||
NS_ASSERTION(!mViewInitiatedScroll, "Cannot reenter ScrollPositionDidChange");
|
||||
|
||||
mViewInitiatedScroll = PR_TRUE;
|
||||
|
||||
InternalScrollPositionDidChange(aX, aY);
|
||||
|
||||
mViewInitiatedScroll = PR_FALSE;
|
||||
|
||||
PostScrollEvent();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1768,25 +1779,75 @@ void nsGfxScrollFrameInner::CurPosAttributeChanged(nsIContent* aContent, PRInt32
|
|||
mFrameInitiatedScroll = PR_FALSE;
|
||||
}
|
||||
ScrollbarChanged(mOuter->GetPresContext(), x*mOnePixel, y*mOnePixel, isSmooth ? NS_VMREFRESH_SMOOTHSCROLL : 0);
|
||||
|
||||
// Fire the onScroll event now that we have scrolled
|
||||
nsIPresShell *presShell = mOuter->GetPresContext()->GetPresShell();
|
||||
if (presShell) {
|
||||
nsScrollbarEvent event(PR_TRUE, NS_SCROLL_EVENT, nsnull);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
// note if hcontent is non-null then hframe must be non-null.
|
||||
// likewise for vcontent and vframe. Thus targetFrame will always
|
||||
// be non-null in here.
|
||||
nsIFrame* targetFrame =
|
||||
hcontent == aContent ? mHScrollbarBox : mVScrollbarBox;
|
||||
presShell->HandleEventWithTarget(&event, targetFrame,
|
||||
aContent,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ============= Scroll events ========== */
|
||||
struct ScrollEvent : public PLEvent {
|
||||
nsGfxScrollFrameInner* mInner;
|
||||
ScrollEvent(nsGfxScrollFrameInner* aInner);
|
||||
};
|
||||
|
||||
static void* PR_CALLBACK HandleScrollEvent(PLEvent* aEvent)
|
||||
{
|
||||
NS_ASSERTION(nsnull != aEvent,"Event is null");
|
||||
ScrollEvent *event = NS_STATIC_CAST(ScrollEvent*, aEvent);
|
||||
event->mInner->FireScrollEvent();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static void PR_CALLBACK DestroyScrollEvent(PLEvent* aEvent)
|
||||
{
|
||||
NS_ASSERTION(nsnull != aEvent,"Event is null");
|
||||
ScrollEvent *event = NS_STATIC_CAST(ScrollEvent*, aEvent);
|
||||
delete event;
|
||||
}
|
||||
|
||||
ScrollEvent::ScrollEvent(nsGfxScrollFrameInner* aInner)
|
||||
{
|
||||
NS_ASSERTION(aInner, "null parameter");
|
||||
mInner = aInner;
|
||||
PL_InitEvent(this, aInner, ::HandleScrollEvent, ::DestroyScrollEvent);
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::FireScrollEvent()
|
||||
{
|
||||
mScrollEventQueue = nsnull;
|
||||
nsIPresShell *presShell = mOuter->GetPresContext()->GetPresShell();
|
||||
if (!presShell)
|
||||
return;
|
||||
nsScrollbarEvent event(PR_TRUE, NS_SCROLL_EVENT, nsnull);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
presShell->HandleEventWithTarget(&event, mOuter, mOuter->GetContent(),
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::PostScrollEvent()
|
||||
{
|
||||
nsCOMPtr<nsIEventQueueService> service = do_GetService(kEventQueueServiceCID);
|
||||
NS_ASSERTION(service, "No event service");
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
service->GetSpecialEventQueue(
|
||||
nsIEventQueueService::UI_THREAD_EVENT_QUEUE, getter_AddRefs(eventQueue));
|
||||
NS_ASSERTION(eventQueue, "Event queue is null");
|
||||
|
||||
if (eventQueue == mScrollEventQueue)
|
||||
return;
|
||||
|
||||
ScrollEvent* ev = new ScrollEvent(this);
|
||||
if (!ev)
|
||||
return;
|
||||
|
||||
if (mScrollEventQueue) {
|
||||
mScrollEventQueue->RevokeEvents(this);
|
||||
}
|
||||
eventQueue->PostEvent(ev);
|
||||
mScrollEventQueue = eventQueue;
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::AdjustHorizontalScrollbar()
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIEventQueue.h"
|
||||
|
||||
class nsISupportsArray;
|
||||
class nsIScrollableView;
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aIsRoot);
|
||||
~nsGfxScrollFrameInner();
|
||||
|
||||
typedef nsIScrollableFrame::ScrollbarStyles ScrollbarStyles;
|
||||
ScrollbarStyles GetScrollbarStylesFromFrame() const;
|
||||
|
@ -91,6 +93,8 @@ public:
|
|||
|
||||
// This gets called when the 'curpos' attribute on one of the scrollbars changes
|
||||
void CurPosAttributeChanged(nsIContent* aChild, PRInt32 aModType);
|
||||
void PostScrollEvent();
|
||||
void FireScrollEvent();
|
||||
|
||||
void SetScrollbarEnabled(nsIBox* aBox, nscoord aMaxPos, PRBool aReflow=PR_TRUE);
|
||||
PRBool SetAttribute(nsIBox* aBox, nsIAtom* aAtom, nscoord aSize, PRBool aReflow=PR_TRUE);
|
||||
|
@ -129,6 +133,7 @@ public:
|
|||
const nsRect& aOldScrollArea,
|
||||
const nsRect& aScrollArea);
|
||||
|
||||
nsCOMPtr<nsIEventQueue> mScrollEventQueue;
|
||||
nsIScrollableView* mScrollableView;
|
||||
nsIBox* mHScrollbarBox;
|
||||
nsIBox* mVScrollbarBox;
|
||||
|
|
Загрузка…
Ссылка в новой задаче