diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 41d32463cde1..5bb1720d7e6d 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -64,6 +64,7 @@ nsSliderFrame::nsSliderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) nsBoxFrame(aPresShell, aContext), mCurPos(0), mChange(0), + mDragFinished(true), mUserChanged(false) { } @@ -417,6 +418,11 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, return NS_OK; } + if (!mDragFinished && !isDraggingThumb()) { + StopDrag(); + return NS_OK; + } + nsIFrame* scrollbarBox = GetScrollbar(); nsCOMPtr scrollbar; scrollbar = GetContentOfBox(scrollbarBox); @@ -487,13 +493,7 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, case NS_TOUCH_END: case NS_MOUSE_BUTTON_UP: if (ShouldScrollForEvent(aEvent)) { - // stop capturing - AddListener(); - DragThumb(false); - if (mChange) { - StopRepeat(); - mChange = 0; - } + StopDrag(); //we MUST call nsFrame HandleEvent for mouse ups to maintain the selection state and capture state. return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } @@ -876,9 +876,23 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aEvent) return NS_OK; } +nsresult +nsSliderFrame::StopDrag() +{ + AddListener(); + DragThumb(false); + if (mChange) { + StopRepeat(); + mChange = 0; + } + return NS_OK; +} + void nsSliderFrame::DragThumb(bool aGrabMouseEvents) { + mDragFinished = !aGrabMouseEvents; + // inform the parent that a drag is beginning or ending nsIFrame* parent = GetParent(); if (parent) { diff --git a/layout/xul/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index e952d49940a8..249e408b4526 100644 --- a/layout/xul/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -97,6 +97,7 @@ public: nsIFrame* aOldFrame) MOZ_OVERRIDE; nsresult StartDrag(nsIDOMEvent* aEvent); + nsresult StopDrag(); static int32_t GetCurrentPosition(nsIContent* content); static int32_t GetMinPosition(nsIContent* content); @@ -173,6 +174,8 @@ private: nscoord mChange; + bool mDragFinished; + // true if an attribute change has been caused by the user manipulating the // slider. This allows notifications to tell how a slider's current position // was changed.