diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index db1867d9335b..175013a135b9 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1392,7 +1392,8 @@ nsComboboxControlFrame::SetInitialChildList(ChildListID aListID, //nsIRollupListener //---------------------------------------------------------------------- bool -nsComboboxControlFrame::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) +nsComboboxControlFrame::Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* pos, nsIContent** aLastRolledUp) { if (!mDroppedDown) { return false; @@ -1411,6 +1412,14 @@ nsComboboxControlFrame::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIConten if (weakFrame.IsAlive()) { mListControlFrame->CaptureMouseEvents(false); } + + if (aFlush && weakFrame.IsAlive()) { + // The popup's visibility doesn't update until the minimize animation has + // finished, so call UpdateWidgetGeometry to update it right away. + nsViewManager* viewManager = mDropdownFrame->GetView()->GetViewManager(); + viewManager->UpdateWidgetGeometry(); + } + return consume; } diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 6d51c07aa548..cfa29eb2265a 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -166,7 +166,8 @@ public: * Hide the dropdown menu and stop capturing mouse events. * @note This method might destroy |this|. */ - virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE; + virtual bool Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE; virtual void NotifyGeometryChange() MOZ_OVERRIDE; /** diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index f2c9edd69eca..1330578f8fb3 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -180,7 +180,8 @@ nsXULPopupManager::GetInstance() } bool -nsXULPopupManager::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) +nsXULPopupManager::Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* pos, nsIContent** aLastRolledUp) { bool consume = false; @@ -248,7 +249,16 @@ nsXULPopupManager::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** a } } + nsPresContext* presContext = item->Frame()->PresContext(); + nsRefPtr viewManager = presContext->PresShell()->GetViewManager(); + HidePopup(item->Content(), true, true, false, true, lastPopup); + + if (aFlush) { + // The popup's visibility doesn't update until the minimize animation has + // finished, so call UpdateWidgetGeometry to update it right away. + viewManager->UpdateWidgetGeometry(); + } } return consume; @@ -2160,7 +2170,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( #endif // close popups or deactivate menubar when Tab or F10 are pressed if (aTopVisibleMenuItem) { - Rollup(0, nullptr, nullptr); + Rollup(0, false, nullptr, nullptr); } else if (mActiveMenuBar) { mActiveMenuBar->MenuClosed(); } @@ -2438,7 +2448,7 @@ nsXULPopupManager::KeyDown(nsIDOMKeyEvent* aKeyEvent) // The access key just went down and no other // modifiers are already down. if (mPopups) - Rollup(0, nullptr, nullptr); + Rollup(0, false, nullptr, nullptr); else if (mActiveMenuBar) mActiveMenuBar->MenuClosed(); } diff --git a/layout/xul/nsXULPopupManager.h b/layout/xul/nsXULPopupManager.h index 4d3821cf0efd..54583baceb57 100644 --- a/layout/xul/nsXULPopupManager.h +++ b/layout/xul/nsXULPopupManager.h @@ -288,7 +288,8 @@ public: NS_DECL_NSIDOMEVENTLISTENER // nsIRollupListener - virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE; + virtual bool Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE; virtual bool ShouldRollupOnMouseWheelEvent() MOZ_OVERRIDE; virtual bool ShouldConsumeOnMouseWheelEvent() MOZ_OVERRIDE; virtual bool ShouldRollupOnMouseActivate() MOZ_OVERRIDE; diff --git a/widget/cocoa/nsAppShell.mm b/widget/cocoa/nsAppShell.mm index d032902a846f..07fc05166e84 100644 --- a/widget/cocoa/nsAppShell.mm +++ b/widget/cocoa/nsAppShell.mm @@ -850,7 +850,7 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread, nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener(); nsCOMPtr rollupWidget = rollupListener->GetRollupWidget(); if (rollupWidget) - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, true, nullptr, nullptr); } NS_OBJC_END_TRY_ABORT_BLOCK; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 697b1622f668..527ace5fd2bf 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -3777,10 +3777,10 @@ NSEvent* gLastDragMouseDownEvent = nil; NSPoint point = [NSEvent mouseLocation]; FlipCocoaScreenCoordinate(point); nsIntPoint pos(point.x, point.y); - consumeEvent = (BOOL)rollupListener->Rollup(popupsToRollup, &pos, nullptr); + consumeEvent = (BOOL)rollupListener->Rollup(popupsToRollup, true, &pos, nullptr); } else { - consumeEvent = (BOOL)rollupListener->Rollup(popupsToRollup, nullptr, nullptr); + consumeEvent = (BOOL)rollupListener->Rollup(popupsToRollup, true, nullptr, nullptr); } } } diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index f09022f3f5bf..940e724afa0c 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -92,7 +92,7 @@ static void RollUpPopups() nsCOMPtr rollupWidget = rollupListener->GetRollupWidget(); if (!rollupWidget) return; - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, true, nullptr, nullptr); } nsCocoaWindow::nsCocoaWindow() diff --git a/widget/cocoa/nsMenuX.mm b/widget/cocoa/nsMenuX.mm index 8525d3cab9c7..c9e8ebd24a9a 100644 --- a/widget/cocoa/nsMenuX.mm +++ b/widget/cocoa/nsMenuX.mm @@ -826,7 +826,7 @@ nsresult nsMenuX::SetupIcon() if (rollupListener) { nsCOMPtr rollupWidget = rollupListener->GetRollupWidget(); if (rollupWidget) { - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, true, nullptr, nullptr); [menu cancelTracking]; return; } diff --git a/widget/cocoa/nsToolkit.mm b/widget/cocoa/nsToolkit.mm index eaa88e88d349..fbf12230a6ce 100644 --- a/widget/cocoa/nsToolkit.mm +++ b/widget/cocoa/nsToolkit.mm @@ -184,7 +184,7 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEv // so would break the corresponding context menu). if (NSPointInRect(screenLocation, [ctxMenuWindow frame])) return event; - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, false, nullptr, nullptr); return event; NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NULL); diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 4f7d571d7326..292532e05e4d 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -634,7 +634,7 @@ nsWindow::Destroy(void) if (rollupListener) { nsCOMPtr rollupWidget = rollupListener->GetRollupWidget(); if (static_cast(this) == rollupWidget) { - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, false, nullptr, nullptr); } } @@ -4832,7 +4832,7 @@ nsWindow::CheckForRollup(gdouble aMouseX, gdouble aMouseY, // if we've determined that we should still rollup, do it. bool usePoint = !aIsWheel && !aAlwaysRollup; nsIntPoint point(aMouseX, aMouseY); - if (rollup && rollupListener->Rollup(popupsToRollup, usePoint ? &point : nullptr, nullptr)) { + if (rollup && rollupListener->Rollup(popupsToRollup, true, usePoint ? &point : nullptr, nullptr)) { retVal = true; } } diff --git a/widget/nsIRollupListener.h b/widget/nsIRollupListener.h index a25f0bfec315..efb8e331a417 100644 --- a/widget/nsIRollupListener.h +++ b/widget/nsIRollupListener.h @@ -20,6 +20,8 @@ class nsIRollupListener { * Notifies the object to rollup, optionally returning the node that * was just rolled up. * + * If aFlush is true, then views should be flushed after the rollup. + * * aPoint is the mouse pointer position where the event that triggered the * rollup occurred, which may be nullptr. * @@ -30,7 +32,8 @@ class nsIRollupListener { * * Returns true if the event that the caller is processing should be consumed. */ - virtual bool Rollup(uint32_t aCount, const nsIntPoint* aPoint, nsIContent** aLastRolledUp) = 0; + virtual bool Rollup(uint32_t aCount, bool aFlush, + const nsIntPoint* aPoint, nsIContent** aLastRolledUp) = 0; /** * Asks the RollupListener if it should rollup on mouse wheel events diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 5c3cf407c1d5..193d39e22bef 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -269,7 +269,7 @@ nsWindow::Destroy(void) if (rollupListener) { nsCOMPtr rollupWidget = rollupListener->GetRollupWidget(); if (static_cast(this) == rollupWidget) { - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, false, nullptr, nullptr); } } @@ -1618,7 +1618,7 @@ nsWindow::CheckForRollup(double aMouseX, double aMouseY, // if we've determined that we should still rollup, do it. if (rollup) { nsIntPoint pos(aMouseX, aMouseY); - retVal = rollupListener->Rollup(popupsToRollup, &pos, nullptr); + retVal = rollupListener->Rollup(popupsToRollup, true, &pos, nullptr); } } diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index e9185a4b9514..258f15acf27a 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -6607,7 +6607,7 @@ void nsWindow::OnDestroy() } if (this == rollupWidget) { if ( rollupListener ) - rollupListener->Rollup(0, nullptr, nullptr); + rollupListener->Rollup(0, false, nullptr, nullptr); CaptureRollupEvents(nullptr, false); } @@ -7553,11 +7553,11 @@ nsWindow::DealWithPopups(HWND aWnd, UINT aMessage, nsIntPoint pos(pt.x, pt.y); consumeRollupEvent = - rollupListener->Rollup(popupsToRollup, &pos, &mLastRollup); + rollupListener->Rollup(popupsToRollup, true, &pos, &mLastRollup); NS_IF_ADDREF(mLastRollup); } else { consumeRollupEvent = - rollupListener->Rollup(popupsToRollup, nullptr, nullptr); + rollupListener->Rollup(popupsToRollup, true, nullptr, nullptr); } // Tell hook to stop processing messages