Skip to content

Commit

Permalink
Bug 953146 part.4 Separate counting pupups to rollup from nsWindow::D…
Browse files Browse the repository at this point in the history
…ealWithPopups() r=jimm
  • Loading branch information
masayuki-nakano committed Dec 31, 2013
1 parent 708ef81 commit dbb7c2c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 30 deletions.
71 changes: 41 additions & 30 deletions widget/windows/nsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7274,6 +7274,36 @@ nsWindow::EventIsInsideWindow(nsWindow* aWindow)
return static_cast<bool>(::PtInRect(&r, mp));
}

// static
bool
nsWindow::GetPopupsToRollup(nsIRollupListener* aRollupListener,
uint32_t* aPopupsToRollup)
{
// If we're dealing with menus, we probably have submenus and we don't want
// to rollup some of them if the click is in a parent menu of the current
// submenu.
*aPopupsToRollup = UINT32_MAX;
nsAutoTArray<nsIWidget*, 5> widgetChain;
uint32_t sameTypeCount =
aRollupListener->GetSubmenuWidgetChain(&widgetChain);
for (uint32_t i = 0; i < widgetChain.Length(); ++i) {
nsIWidget* widget = widgetChain[i];
if (EventIsInsideWindow(static_cast<nsWindow*>(widget))) {
// Don't roll up if the mouse event occurred within a menu of the
// same type. If the mouse event occurred in a menu higher than that,
// roll up, but pass the number of popups to Rollup so that only those
// of the same type close up.
if (i < sameTypeCount) {
return false;
}

*aPopupsToRollup = sameTypeCount;
break;
}
}
return true;
}

// static
bool
nsWindow::DealWithPopups(HWND aWnd, UINT aMessage,
Expand All @@ -7296,6 +7326,7 @@ nsWindow::DealWithPopups(HWND aWnd, UINT aMessage,
}

bool rollup = false;
uint32_t popupsToRollup = UINT32_MAX;

nsWindow* popupWindow = static_cast<nsWindow*>(popup.get());
UINT nativeMessage = WinUtils::GetNativeMessage(aMessage);
Expand All @@ -7306,15 +7337,17 @@ nsWindow::DealWithPopups(HWND aWnd, UINT aMessage,
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
rollup = !EventIsInsideWindow(popupWindow);
rollup = !EventIsInsideWindow(popupWindow) &&
GetPopupsToRollup(rollupListener, &popupsToRollup);
break;

case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
// We need to check if the popup thinks that it should cause closing
// itself when mouse wheel events are fired outside the rollup widget.
if (!EventIsInsideWindow(popupWindow)) {
rollup = rollupListener->ShouldRollupOnMouseWheelEvent();
rollup = rollupListener->ShouldRollupOnMouseWheelEvent() &&
GetPopupsToRollup(rollupListener, &popupsToRollup);
*aResult = MA_ACTIVATE;
}
break;
Expand All @@ -7326,15 +7359,17 @@ nsWindow::DealWithPopups(HWND aWnd, UINT aMessage,
case WM_ACTIVATE:
case WM_MOUSEACTIVATE:
// XXX Why do we need to check the message pos?
rollup = !EventIsInsideWindow(popupWindow);
rollup = !EventIsInsideWindow(popupWindow) &&
GetPopupsToRollup(rollupListener, &popupsToRollup);
break;

case WM_KILLFOCUS:
// If focus moves to other window created in different process/thread,
// e.g., a plugin window, popups should be rolled up.
if (IsDifferentThreadWindow(reinterpret_cast<HWND>(aWParam))) {
// XXX Why do we need to check the message pos?
rollup = !EventIsInsideWindow(popupWindow);
rollup = !EventIsInsideWindow(popupWindow) &&
GetPopupsToRollup(rollupListener, &popupsToRollup);
break;
}
return false;
Expand All @@ -7343,38 +7378,14 @@ nsWindow::DealWithPopups(HWND aWnd, UINT aMessage,
case WM_SIZING:
case WM_MENUSELECT:
// XXX Why do we need to check the message pos?
rollup = !EventIsInsideWindow(popupWindow);
rollup = !EventIsInsideWindow(popupWindow) &&
GetPopupsToRollup(rollupListener, &popupsToRollup);
break;

default:
return false;
}

// If we're dealing with menus, we probably have submenus and we don't want
// to rollup some of them if the click is in a parent menu of the current
// submenu.
uint32_t popupsToRollup = UINT32_MAX;
if (rollup && nativeMessage != WM_ACTIVATEAPP) {
nsAutoTArray<nsIWidget*, 5> widgetChain;
uint32_t sameTypeCount =
rollupListener->GetSubmenuWidgetChain(&widgetChain);
for (uint32_t i = 0; i < widgetChain.Length(); ++i) {
nsIWidget* widget = widgetChain[i];
if (EventIsInsideWindow(static_cast<nsWindow*>(widget))) {
// don't roll up if the mouse event occurred within a menu of the
// same type. If the mouse event occurred in a menu higher than that,
// roll up, but pass the number of popups to Rollup so that only those
// of the same type close up.
if (i < sameTypeCount) {
rollup = false;
} else {
popupsToRollup = sameTypeCount;
}
break;
}
}
}

if (nativeMessage == WM_MOUSEACTIVATE) {
// Prevent the click inside the popup from causing a change in window
// activation. Since the popup is shown non-activated, we need to eat any
Expand Down
2 changes: 2 additions & 0 deletions widget/windows/nsWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ class nsWindow : public nsWindowBase
static void ScheduleHookTimer(HWND aWnd, UINT aMsgId);
static void RegisterSpecialDropdownHooks();
static void UnregisterSpecialDropdownHooks();
static bool GetPopupsToRollup(nsIRollupListener* aRollupListener,
uint32_t* aPopupsToRollup);
static bool DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inLParam, LRESULT* outResult);

/**
Expand Down

0 comments on commit dbb7c2c

Please sign in to comment.