mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 404766, right click on a bookmark menuitem closes it instead of opening another context menu, r+sr=roc
This commit is contained in:
parent
b8523ccc63
commit
1ff1ebff1c
@ -1285,7 +1285,8 @@ nsComboboxControlFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
||||
//nsIRollupListener
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsComboboxControlFrame::Rollup(nsIContent** aLastRolledUp)
|
||||
nsComboboxControlFrame::Rollup(PRUint32 aCount,
|
||||
nsIContent** aLastRolledUp)
|
||||
{
|
||||
if (aLastRolledUp)
|
||||
*aLastRolledUp = nsnull;
|
||||
|
@ -195,7 +195,7 @@ public:
|
||||
* Hide the dropdown menu and stop capturing mouse events.
|
||||
* @note This method might destroy |this|.
|
||||
*/
|
||||
NS_IMETHOD Rollup(nsIContent** aLastRolledUp);
|
||||
NS_IMETHOD Rollup(PRUint32 aCount, nsIContent** aLastRolledUp);
|
||||
/**
|
||||
* A combobox should roll up if a mousewheel event happens outside of
|
||||
* the popup area.
|
||||
|
@ -313,7 +313,7 @@ public:
|
||||
NS_DECL_NSIROLLUPLISTENER
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
virtual void GetSubmenuWidgetChain(nsTArray<nsIWidget*> *_retval);
|
||||
virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain);
|
||||
virtual void AdjustPopupsOnWindowChange(void);
|
||||
|
||||
static nsXULPopupManager* sInstance;
|
||||
@ -451,11 +451,14 @@ public:
|
||||
* aAsynchronous - true if the first popuphiding event should be sent
|
||||
* asynchrously. This should be true if HidePopup is called
|
||||
* from a frame.
|
||||
* aLastPopup - optional popup to close last when hiding a chain of menus.
|
||||
* If null, then all popups will be closed.
|
||||
*/
|
||||
void HidePopup(nsIContent* aPopup,
|
||||
PRBool aHideChain,
|
||||
PRBool aDeselectMenu,
|
||||
PRBool aAsynchronous);
|
||||
PRBool aAsynchronous,
|
||||
nsIContent* aLastPopup = nsnull);
|
||||
|
||||
/**
|
||||
* Hide a popup after a short delay. This is used when rolling over menu items.
|
||||
|
@ -170,7 +170,7 @@ nsXULPopupManager::GetInstance()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULPopupManager::Rollup(nsIContent** aLastRolledUp)
|
||||
nsXULPopupManager::Rollup(PRUint32 aCount, nsIContent** aLastRolledUp)
|
||||
{
|
||||
if (aLastRolledUp)
|
||||
*aLastRolledUp = nsnull;
|
||||
@ -192,7 +192,21 @@ nsXULPopupManager::Rollup(nsIContent** aLastRolledUp)
|
||||
if (first)
|
||||
NS_ADDREF(*aLastRolledUp = first->Content());
|
||||
}
|
||||
HidePopup(item->Content(), PR_TRUE, PR_TRUE, PR_FALSE);
|
||||
|
||||
// if a number of popups to close has been specified, determine the last
|
||||
// popup to close
|
||||
nsIContent* lastPopup = nsnull;
|
||||
if (aCount != PR_UINT32_MAX) {
|
||||
nsMenuChainItem* last = item;
|
||||
while (--aCount && last->GetParent()) {
|
||||
last = last->GetParent();
|
||||
}
|
||||
if (last) {
|
||||
lastPopup = last->Content();
|
||||
}
|
||||
}
|
||||
|
||||
HidePopup(item->Content(), PR_TRUE, PR_TRUE, PR_FALSE, lastPopup);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -214,28 +228,36 @@ NS_IMETHODIMP nsXULPopupManager::ShouldRollupOnMouseActivate(PRBool *aShouldRoll
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPopupManager::GetSubmenuWidgetChain(nsTArray<nsIWidget*> *_retval)
|
||||
PRUint32
|
||||
nsXULPopupManager::GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain)
|
||||
{
|
||||
// this method is used by the widget code to determine the list of popups
|
||||
// that are open. If a mouse click occurs outside one of these popups, the
|
||||
// panels will roll up. If the click is inside a popup, they will not roll up
|
||||
NS_ASSERTION(_retval, "null parameter");
|
||||
PRUint32 count = 0, sameTypeCount = 0;
|
||||
|
||||
NS_ASSERTION(aWidgetChain, "null parameter");
|
||||
nsMenuChainItem* item = GetTopVisibleMenu();
|
||||
while (item) {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
item->Frame()->GetWidget(getter_AddRefs(widget));
|
||||
NS_ASSERTION(widget, "open popup has no widget");
|
||||
_retval->AppendElement(widget.get());
|
||||
aWidgetChain->AppendElement(widget.get());
|
||||
// In the case when a menulist inside a panel is open, clicking in the
|
||||
// panel should still roll up the menu, so if a different type is found,
|
||||
// stop scanning.
|
||||
nsMenuChainItem* parent = item->GetParent();
|
||||
if (!parent || item->Frame()->PopupType() != parent->Frame()->PopupType() ||
|
||||
item->IsContextMenu() != parent->IsContextMenu())
|
||||
break;
|
||||
if (!sameTypeCount) {
|
||||
count++;
|
||||
if (!parent || item->Frame()->PopupType() != parent->Frame()->PopupType() ||
|
||||
item->IsContextMenu() != parent->IsContextMenu()) {
|
||||
sameTypeCount = count;
|
||||
}
|
||||
}
|
||||
item = parent;
|
||||
}
|
||||
|
||||
return sameTypeCount;
|
||||
}
|
||||
|
||||
void
|
||||
@ -605,7 +627,8 @@ void
|
||||
nsXULPopupManager::HidePopup(nsIContent* aPopup,
|
||||
PRBool aHideChain,
|
||||
PRBool aDeselectMenu,
|
||||
PRBool aAsynchronous)
|
||||
PRBool aAsynchronous,
|
||||
nsIContent* aLastPopup)
|
||||
{
|
||||
// if the popup is on the nohide panels list, remove it but don't close any
|
||||
// other panels
|
||||
@ -676,7 +699,7 @@ nsXULPopupManager::HidePopup(nsIContent* aPopup,
|
||||
if (parent && (aHideChain || topMenu != foundMenu))
|
||||
nextPopup = parent->Content();
|
||||
|
||||
lastPopup = aHideChain ? nsnull : aPopup;
|
||||
lastPopup = aLastPopup ? aLastPopup : (aHideChain ? nsnull : aPopup);
|
||||
}
|
||||
else if (foundPanel) {
|
||||
popupToHide = aPopup;
|
||||
@ -777,6 +800,7 @@ nsXULPopupManager::HidePopupCallback(nsIContent* aPopup,
|
||||
// closes the menu and not the panel as well.
|
||||
if (foundMenu &&
|
||||
(aLastPopup || aPopupType == foundMenu->PopupType())) {
|
||||
|
||||
nsCOMPtr<nsIContent> popupToHide = item->Content();
|
||||
nsMenuChainItem* parent = item->GetParent();
|
||||
|
||||
@ -1885,7 +1909,7 @@ nsXULPopupManager::KeyDown(nsIDOMEvent* aKeyEvent)
|
||||
// The access key just went down and no other
|
||||
// modifiers are already down.
|
||||
if (mPopups)
|
||||
Rollup(nsnull);
|
||||
Rollup(nsnull, nsnull);
|
||||
else if (mActiveMenuBar)
|
||||
mActiveMenuBar->MenuClosed();
|
||||
}
|
||||
@ -1960,7 +1984,7 @@ nsXULPopupManager::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
) {
|
||||
// close popups or deactivate menubar when Tab or F10 are pressed
|
||||
if (item)
|
||||
Rollup(nsnull);
|
||||
Rollup(nsnull, nsnull);
|
||||
else if (mActiveMenuBar)
|
||||
mActiveMenuBar->MenuClosed();
|
||||
}
|
||||
|
@ -43,20 +43,29 @@
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsIWidget;
|
||||
class nsIContent;
|
||||
|
||||
#define NS_IMENUROLLUP_IID \
|
||||
{0x2b65d177, 0xc3e4, 0x4564, \
|
||||
{ 0x8d, 0xed, 0x86, 0xd2, 0xfa, 0x2f, 0x65, 0x9a }}
|
||||
{0x61c9d01f, 0x8a4c, 0x4bb0, \
|
||||
{ 0xa9, 0x90, 0xeb, 0xf6, 0x65, 0x4c, 0xda, 0x61 }}
|
||||
|
||||
class nsIMenuRollup : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMENUROLLUP_IID)
|
||||
|
||||
/* void GetSubmenuWidgetChain (nsTArray<nsIWidget*>*); */
|
||||
virtual void GetSubmenuWidgetChain(nsTArray<nsIWidget*> *_retval) = 0;
|
||||
/*
|
||||
* Retrieve the widgets for open menus are store them in the array
|
||||
* aWidgetChain. The number of menus of the same type should be returned,
|
||||
* for example, if a context menu is open, return only the number of menus
|
||||
* that are part of the context menu chain. This allows closing up only
|
||||
* those menus in different situations.
|
||||
*/
|
||||
virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) = 0;
|
||||
|
||||
/* void AdjustPopupsOnWindowChange (); */
|
||||
/**
|
||||
* Adjust the position of open panels when a window is moved or resized.
|
||||
*/
|
||||
virtual void AdjustPopupsOnWindowChange(void) = 0;
|
||||
|
||||
};
|
||||
|
@ -43,15 +43,19 @@
|
||||
|
||||
interface nsIContent;
|
||||
|
||||
[uuid(ee6efe03-77dc-4aac-a6a8-905731a1796e)]
|
||||
[uuid(0CA103E5-80D4-4B81-A310-BE0708F8EAA9)]
|
||||
interface nsIRollupListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Notifies the object to rollup, optionally returning the node that
|
||||
* was just rolled up.
|
||||
*
|
||||
* aCount is the number of popups in a chain to close. If this is
|
||||
* PR_UINT32_MAX, then all popups are closed.
|
||||
*
|
||||
* @result NS_Ok if no errors
|
||||
*/
|
||||
nsIContent Rollup();
|
||||
nsIContent Rollup(in unsigned long aCount);
|
||||
|
||||
/**
|
||||
* Asks the RollupListener if it should rollup on mousevents
|
||||
|
@ -920,7 +920,7 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||
NSString *sender = [aNotification object];
|
||||
if (!sender || ![sender isEqualToString:@"org.mozilla.gecko.PopupWindow"]) {
|
||||
if (gRollupListener && gRollupWidget)
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
@ -3147,23 +3147,34 @@ static const PRInt32 sShadowInvalidationInterval = 100;
|
||||
// if we're dealing with menus, we probably have submenus and
|
||||
// we don't want to rollup if the click is in a parent menu of
|
||||
// the current submenu
|
||||
PRUint32 popupsToRollup = PR_UINT32_MAX;
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup;
|
||||
menuRollup = (do_QueryInterface(gRollupListener));
|
||||
if (menuRollup) {
|
||||
nsAutoTArray<nsIWidget*, 5> widgetChain;
|
||||
menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
for (PRUint32 i = 0; i < widgetChain.Length(); i++) {
|
||||
nsIWidget* widget = widgetChain[i];
|
||||
NSWindow* currWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if (nsCocoaUtils::IsEventOverWindow(theEvent, currWindow)) {
|
||||
shouldRollup = PR_FALSE;
|
||||
// don't roll up if the mouse event occured within a menu of the
|
||||
// same type. If the mouse event occured 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) {
|
||||
shouldRollup = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
popupsToRollup = sameTypeCount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldRollup) {
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(popupsToRollup, nsnull);
|
||||
consumeEvent = (BOOL)gConsumeRollupEvent;
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsCocoaWindow, Inherited, nsPIWidgetCocoa)
|
||||
static void RollUpPopups()
|
||||
{
|
||||
if (gRollupListener && gRollupWidget)
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
}
|
||||
|
||||
|
||||
|
@ -907,7 +907,7 @@ static pascal OSStatus MyMenuEventHandler(EventHandlerCallRef myHandler, EventRe
|
||||
}
|
||||
else if (kind == kEventMenuOpening || kind == kEventMenuClosed) {
|
||||
if (kind == kEventMenuOpening && gRollupListener && gRollupWidget) {
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
return userCanceledErr;
|
||||
}
|
||||
MenuRef menuRef;
|
||||
|
@ -248,7 +248,7 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEv
|
||||
// so would break the corresponding context menu).
|
||||
if (NSPointInRect(screenLocation, [ctxMenuWindow frame]))
|
||||
return event;
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
return event;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NULL);
|
||||
|
@ -736,7 +736,7 @@ nsWindow::Destroy(void)
|
||||
nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
|
||||
if (static_cast<nsIWidget *>(this) == rollupWidget.get()) {
|
||||
if (gRollupListener)
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
gRollupWindow = nsnull;
|
||||
gRollupListener = nsnull;
|
||||
}
|
||||
@ -4998,26 +4998,39 @@ check_for_rollup(GdkWindow *aWindow, gdouble aMouseX, gdouble aMouseY,
|
||||
// if we're dealing with menus, we probably have submenus and
|
||||
// we don't want to rollup if the clickis in a parent menu of
|
||||
// the current submenu
|
||||
PRUint32 popupsToRollup = PR_UINT32_MAX;
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup;
|
||||
menuRollup = (do_QueryInterface(gRollupListener));
|
||||
if (menuRollup) {
|
||||
nsAutoTArray<nsIWidget*, 5> widgetChain;
|
||||
menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
for (PRUint32 i=0; i<widgetChain.Length(); ++i) {
|
||||
nsIWidget* widget = widgetChain[i];
|
||||
nsIWidget* widget = widgetChain[i];
|
||||
GdkWindow* currWindow =
|
||||
(GdkWindow*) widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if (is_mouse_in_window(currWindow, aMouseX, aMouseY)) {
|
||||
rollup = PR_FALSE;
|
||||
break;
|
||||
// don't roll up if the mouse event occured within a
|
||||
// menu of the same type. If the mouse event occured
|
||||
// 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 = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
popupsToRollup = sameTypeCount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // foreach parent menu widget
|
||||
} // if rollup listener knows about menus
|
||||
|
||||
// if we've determined that we should still rollup, do it.
|
||||
if (rollup) {
|
||||
gRollupListener->Rollup(nsnull);
|
||||
retVal = PR_TRUE;
|
||||
gRollupListener->Rollup(popupsToRollup, nsnull);
|
||||
if (popupsToRollup == PR_UINT32_MAX) {
|
||||
retVal = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -603,15 +603,21 @@ nsWindow :: DealWithPopups ( ULONG inMsg, MRESULT* outResult )
|
||||
|
||||
// If we're dealing with menus, we probably have submenus and we don't
|
||||
// want to rollup if the click is in a parent menu of the current submenu.
|
||||
PRUint32 popupsToRollup = PR_UINT32_MAX;
|
||||
if (rollup) {
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup ( do_QueryInterface(gRollupListener) );
|
||||
if ( menuRollup ) {
|
||||
nsAutoTArray<nsIWidget*, 5> widgetChain;
|
||||
menuRollup->GetSubmenuWidgetChain ( &widgetChain );
|
||||
PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) {
|
||||
nsIWidget* widget = widgetChain[i];
|
||||
if ( nsWindow::EventIsInsideWindow((nsWindow*)widget) ) {
|
||||
rollup = PR_FALSE;
|
||||
if (i < sameTypeCount) {
|
||||
rollup = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
popupsToRollup = sameTypeCount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // foreach parent menu widget
|
||||
@ -621,7 +627,7 @@ nsWindow :: DealWithPopups ( ULONG inMsg, MRESULT* outResult )
|
||||
// if we've determined that we should still rollup everything, do it.
|
||||
if ( rollup ) {
|
||||
// only need to deal with the last rollup for left mouse down events.
|
||||
gRollupListener->Rollup(inMsg == WM_BUTTON1DOWN ? &mLastRollup : nsnull);
|
||||
gRollupListener->Rollup(popupsToRollup, inMsg == WM_BUTTON1DOWN ? &mLastRollup : nsnull);
|
||||
|
||||
// return TRUE tells Windows that the event is consumed,
|
||||
// false allows the event to be dispatched
|
||||
|
@ -651,13 +651,13 @@ int nsWindow::WindowWMHandler( PtWidget_t *widget, void *data, PtCallbackInfo_t
|
||||
case Ph_WM_CONSWITCH:
|
||||
gConsoleRectValid = PR_FALSE; /* force a call tp PhWindowQueryVisible() next time, since we might have moved this window into a different console */
|
||||
/* rollup the menus */
|
||||
if( gRollupWidget && gRollupListener ) gRollupListener->Rollup(nsnull);
|
||||
if( gRollupWidget && gRollupListener ) gRollupListener->Rollup(nsnull, nsnull);
|
||||
break;
|
||||
|
||||
case Ph_WM_FOCUS:
|
||||
if( we->event_state == Ph_WM_EVSTATE_FOCUSLOST ) {
|
||||
/* rollup the menus */
|
||||
if( gRollupWidget && gRollupListener ) gRollupListener->Rollup(nsnull);
|
||||
if( gRollupWidget && gRollupListener ) gRollupListener->Rollup(nsnull, nsnull);
|
||||
|
||||
if( sFocusWidget ) sFocusWidget->DispatchStandardEvent(NS_DEACTIVATE);
|
||||
}
|
||||
@ -902,7 +902,7 @@ NS_METHOD nsWindow::Move( PRInt32 aX, PRInt32 aY ) {
|
||||
int nsWindow::MenuRegionCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbinfo ) {
|
||||
if( gRollupWidget && gRollupListener ) {
|
||||
/* rollup the menu */
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
}
|
||||
return Pt_CONTINUE;
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ nsWindow::Destroy(void)
|
||||
nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
|
||||
if (static_cast<nsIWidget *>(this) == rollupWidget.get()) {
|
||||
if (gRollupListener)
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
gRollupWindow = nsnull;
|
||||
gRollupListener = nsnull;
|
||||
}
|
||||
@ -935,25 +935,31 @@ check_for_rollup(double aMouseX, double aMouseY,
|
||||
// if we're dealing with menus, we probably have submenus and
|
||||
// we don't want to rollup if the clickis in a parent menu of
|
||||
// the current submenu
|
||||
PRUint32 popupsToRollup = PR_UINT32_MAX;
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup;
|
||||
menuRollup = (do_QueryInterface(gRollupListener));
|
||||
if (menuRollup) {
|
||||
nsAutoTArray<nsIWidget*, 5> widgetChain;
|
||||
menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
for (PRUint32 i=0; i<widgetChain.Length(); ++i) {
|
||||
nsIWidget* widget = widgetChain[i];
|
||||
QWidget* currWindow =
|
||||
(QWidget*) widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
if (is_mouse_in_window(currWindow, aMouseX, aMouseY)) {
|
||||
rollup = PR_FALSE;
|
||||
break;
|
||||
if (i < sameTypeCount) {
|
||||
rollup = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
popupsToRollup = sameTypeCount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // foreach parent menu widget
|
||||
} // if rollup listener knows about menus
|
||||
|
||||
// if we've determined that we should still rollup, do it.
|
||||
if (rollup) {
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(popupsToRollup, nsnull);
|
||||
retVal = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1451,7 +1451,7 @@ NS_METHOD nsWindow::Destroy()
|
||||
// the rollup widget, rollup and turn off capture.
|
||||
if ( this == gRollupWidget ) {
|
||||
if ( gRollupListener )
|
||||
gRollupListener->Rollup(nsnull);
|
||||
gRollupListener->Rollup(nsnull, nsnull);
|
||||
CaptureRollupEvents(nsnull, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
@ -7321,15 +7321,25 @@ nsWindow :: DealWithPopups ( HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inL
|
||||
|
||||
// If we're dealing with menus, we probably have submenus and we don't
|
||||
// want to rollup if the click is in a parent menu of the current submenu.
|
||||
PRUint32 popupsToRollup = PR_UINT32_MAX;
|
||||
if (rollup) {
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup ( do_QueryInterface(gRollupListener) );
|
||||
if ( menuRollup ) {
|
||||
nsAutoTArray<nsIWidget*, 5> widgetChain;
|
||||
menuRollup->GetSubmenuWidgetChain ( &widgetChain );
|
||||
PRUint32 sameTypeCount = menuRollup->GetSubmenuWidgetChain(&widgetChain);
|
||||
for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) {
|
||||
nsIWidget* widget = widgetChain[i];
|
||||
if ( nsWindow::EventIsInsideWindow(inMsg, (nsWindow*)widget) ) {
|
||||
rollup = PR_FALSE;
|
||||
// don't roll up if the mouse event occured within a menu of the
|
||||
// same type. If the mouse event occured 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 = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
popupsToRollup = sameTypeCount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // foreach parent menu widget
|
||||
@ -7337,7 +7347,7 @@ nsWindow :: DealWithPopups ( HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inL
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
if (inMsg == WM_MOUSEACTIVATE) {
|
||||
if (inMsg == WM_MOUSEACTIVATE && popupsToRollup == PR_UINT32_MAX) {
|
||||
// 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 requests to activate the window while it is displayed. Windows
|
||||
@ -7370,7 +7380,7 @@ nsWindow :: DealWithPopups ( HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inL
|
||||
// nsIRollupListener::Rollup.
|
||||
PRBool consumeRollupEvent = gRollupConsumeRollupEvent;
|
||||
// only need to deal with the last rollup for left mouse down events.
|
||||
gRollupListener->Rollup(inMsg == WM_LBUTTONDOWN ? &mLastRollup : nsnull);
|
||||
gRollupListener->Rollup(popupsToRollup, inMsg == WM_LBUTTONDOWN ? &mLastRollup : nsnull);
|
||||
|
||||
// Tell hook to stop processing messages
|
||||
gProcessHook = PR_FALSE;
|
||||
@ -7385,6 +7395,13 @@ nsWindow :: DealWithPopups ( HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inL
|
||||
*outResult = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
// if we are only rolling up some popups, don't activate and don't let
|
||||
// the event go through. This prevents clicks menus higher in the
|
||||
// chain from opening when a context menu is open
|
||||
if (popupsToRollup != PR_UINT32_MAX && inMsg == WM_MOUSEACTIVATE) {
|
||||
*outResult = MA_NOACTIVATEANDEAT;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
} // if event that might trigger a popup to rollup
|
||||
} // if rollup listeners registered
|
||||
|
Loading…
Reference in New Issue
Block a user