Bug 1102039, Ensure that the popup's widget visibility is updated after rollup, allows popups to disappear at the start of the minimize animation rather than after, r=tn

This commit is contained in:
Neil Deakin 2015-01-07 20:52:20 -05:00
parent 6be56d2934
commit a744e9625f
13 changed files with 44 additions and 20 deletions

View File

@ -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;
}

View File

@ -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;
/**

View File

@ -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<nsViewManager> 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();
}

View File

@ -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;

View File

@ -850,7 +850,7 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener();
nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
if (rollupWidget)
rollupListener->Rollup(0, nullptr, nullptr);
rollupListener->Rollup(0, true, nullptr, nullptr);
}
NS_OBJC_END_TRY_ABORT_BLOCK;

View File

@ -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);
}
}
}

View File

@ -92,7 +92,7 @@ static void RollUpPopups()
nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
if (!rollupWidget)
return;
rollupListener->Rollup(0, nullptr, nullptr);
rollupListener->Rollup(0, true, nullptr, nullptr);
}
nsCocoaWindow::nsCocoaWindow()

View File

@ -826,7 +826,7 @@ nsresult nsMenuX::SetupIcon()
if (rollupListener) {
nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
if (rollupWidget) {
rollupListener->Rollup(0, nullptr, nullptr);
rollupListener->Rollup(0, true, nullptr, nullptr);
[menu cancelTracking];
return;
}

View File

@ -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);

View File

@ -634,7 +634,7 @@ nsWindow::Destroy(void)
if (rollupListener) {
nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
if (static_cast<nsIWidget *>(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;
}
}

View File

@ -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

View File

@ -269,7 +269,7 @@ nsWindow::Destroy(void)
if (rollupListener) {
nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
if (static_cast<nsIWidget *>(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);
}
}

View File

@ -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