From 589d12948defdde5cde3a838534e0e9c7af1d7d9 Mon Sep 17 00:00:00 2001 From: "hyatt%netscape.com" Date: Fri, 10 Sep 1999 08:47:12 +0000 Subject: [PATCH] Working on XP menus. git-svn-id: svn://10.0.0.236/trunk@46741 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/shared/public/nsXULAtomList.h | 3 +- mozilla/layout/base/nsCSSFrameConstructor.cpp | 7 +- .../html/style/src/nsCSSFrameConstructor.cpp | 7 +- mozilla/layout/xul/base/src/makefile.win | 2 + mozilla/layout/xul/base/src/nsMenuFrame.cpp | 24 +-- .../layout/xul/base/src/nsMenuPopupFrame.cpp | 92 ++++++++--- .../layout/xul/base/src/nsMenuPopupFrame.h | 13 +- .../layout/xul/base/src/nsPopupSetFrame.cpp | 150 +++++++++++++----- mozilla/layout/xul/base/src/nsPopupSetFrame.h | 15 +- .../layout/xul/content/src/nsXULAtomList.h | 3 +- 10 files changed, 225 insertions(+), 91 deletions(-) diff --git a/mozilla/content/shared/public/nsXULAtomList.h b/mozilla/content/shared/public/nsXULAtomList.h index 38ed37067fc..a23ab76ef51 100644 --- a/mozilla/content/shared/public/nsXULAtomList.h +++ b/mozilla/content/shared/public/nsXULAtomList.h @@ -73,7 +73,8 @@ XUL_ATOM(menupopup, "menupopup") // The XP menu's children. XUL_ATOM(menuactive, "menuactive") // Whether or not a menu is active (without necessarily being open) XUL_ATOM(accesskey, "accesskey") // The shortcut key for a menu or menu item XUL_ATOM(acceltext, "acceltext") // Text to use for the accelerator -XUL_ATOM(menupopupset, "menupopupset") // Contains popup menus, context menus, and tooltips +XUL_ATOM(popupset, "popupset") // Contains popup menus, context menus, and tooltips +XUL_ATOM(popup, "popup") // The popup for a context menu, popup menu, or tooltip XUL_ATOM(menugenerated, "menugenerated") // Internal XUL_ATOM(key, "key") // A key element diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 1c1e8b62c52..0eaf2f851fb 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -1941,7 +1941,8 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, (nsXULAtoms::menuitem == tag.get()) || (nsXULAtoms::menubar == tag.get()) || (nsXULAtoms::menupopup == tag.get()) || - (nsXULAtoms::menupopupset == tag.get()) || + (nsXULAtoms::popupset == tag.get()) || + (nsXULAtoms::popup == tag.get()) || (nsXULAtoms::toolbox == tag.get()) || (nsXULAtoms::toolbar == tag.get()) || (nsXULAtoms::toolbaritem == tag.get()) || @@ -3776,13 +3777,13 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, rv = NS_NewMenuBarFrame(&newFrame); #endif } - else if (aTag == nsXULAtoms::menupopupset) { + else if (aTag == nsXULAtoms::popupset) { // This frame contains child popups processChildren = PR_TRUE; isReplaced = PR_TRUE; rv = NS_NewPopupSetFrame(&newFrame); } - else if (aTag == nsXULAtoms::menupopup) { + else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) { // This is its own frame that derives from // box. processChildren = PR_TRUE; diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 1c1e8b62c52..0eaf2f851fb 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -1941,7 +1941,8 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, (nsXULAtoms::menuitem == tag.get()) || (nsXULAtoms::menubar == tag.get()) || (nsXULAtoms::menupopup == tag.get()) || - (nsXULAtoms::menupopupset == tag.get()) || + (nsXULAtoms::popupset == tag.get()) || + (nsXULAtoms::popup == tag.get()) || (nsXULAtoms::toolbox == tag.get()) || (nsXULAtoms::toolbar == tag.get()) || (nsXULAtoms::toolbaritem == tag.get()) || @@ -3776,13 +3777,13 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, rv = NS_NewMenuBarFrame(&newFrame); #endif } - else if (aTag == nsXULAtoms::menupopupset) { + else if (aTag == nsXULAtoms::popupset) { // This frame contains child popups processChildren = PR_TRUE; isReplaced = PR_TRUE; rv = NS_NewPopupSetFrame(&newFrame); } - else if (aTag == nsXULAtoms::menupopup) { + else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) { // This is its own frame that derives from // box. processChildren = PR_TRUE; diff --git a/mozilla/layout/xul/base/src/makefile.win b/mozilla/layout/xul/base/src/makefile.win index 06d0a778c72..ce594acfaff 100644 --- a/mozilla/layout/xul/base/src/makefile.win +++ b/mozilla/layout/xul/base/src/makefile.win @@ -55,6 +55,7 @@ CPPSRCS= \ nsMenuFrame.cpp \ nsMenuBarFrame.cpp \ nsMenuBarListener.cpp \ + nsMenuPopupEntryListener.cpp \ nsPopupSetFrame.cpp \ $(NULL) @@ -90,6 +91,7 @@ CPP_OBJS= \ .\$(OBJDIR)\nsMenuFrame.obj \ .\$(OBJDIR)\nsMenuBarFrame.obj \ .\$(OBJDIR)\nsMenuBarListener.obj \ + .\$(OBJDIR)\nsMenuPopupEntryListener.obj \ .\$(OBJDIR)\nsPopupSetFrame.obj \ $(NULL) diff --git a/mozilla/layout/xul/base/src/nsMenuFrame.cpp b/mozilla/layout/xul/base/src/nsMenuFrame.cpp index adcf9b656ec..7e4f6da722c 100644 --- a/mozilla/layout/xul/base/src/nsMenuFrame.cpp +++ b/mozilla/layout/xul/base/src/nsMenuFrame.cpp @@ -181,18 +181,6 @@ NS_IMETHODIMP nsMenuFrame::GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const { - // Maintain a separate child list for the menu contents. - // This is necessary because we don't want the menu contents to be included in the layout - // of the menu's single item because it would take up space, when it is supposed to - // be floating above the display. - /*NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer"); - - *aListName = nsnull; - if (NS_MENU_POPUP_LIST_INDEX == aIndex) { - *aListName = nsLayoutAtoms::popupList; - NS_ADDREF(*aListName); - return NS_OK; - }*/ return nsBoxFrame::GetAdditionalChildListName(aIndex, aListName); } @@ -331,9 +319,8 @@ PRBool nsMenuFrame::IsGenerated() // takes it from display: none to display: block and gives us // a menu forevermore. if (child) { - nsCOMPtr generated = dont_AddRef(NS_NewAtom("menugenerated")); nsString genVal; - child->GetAttribute(kNameSpaceID_None, generated, genVal); + child->GetAttribute(kNameSpaceID_None, nsXULAtoms::menugenerated, genVal); if (genVal == "") return PR_FALSE; } @@ -350,11 +337,10 @@ void nsMenuFrame::MarkAsGenerated() // takes it from display: none to display: block and gives us // a menu forevermore. if (child) { - nsCOMPtr generated = dont_AddRef(NS_NewAtom("menugenerated")); nsAutoString genVal; - child->GetAttribute(kNameSpaceID_None, generated, genVal); + child->GetAttribute(kNameSpaceID_None, nsXULAtoms::menugenerated, genVal); if (genVal == "") - child->SetAttribute(kNameSpaceID_None, generated, "true", PR_TRUE); + child->SetAttribute(kNameSpaceID_None, nsXULAtoms::menugenerated, "true", PR_TRUE); } } @@ -435,7 +421,7 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag) if (mMenuParent) mMenuParent->IsMenuBar(onMenuBar); - menuPopup->SyncViewWithFrame(onMenuBar); + menuPopup->SyncViewWithFrame(*mPresContext, onMenuBar, this, -1, -1); } mMenuOpen = PR_TRUE; @@ -541,7 +527,7 @@ nsMenuFrame::DidReflow(nsIPresContext& aPresContext, nsIFrame* frame = mPopupFrames.FirstChild(); nsMenuPopupFrame* menuPopup = (nsMenuPopupFrame*)frame; if (menuPopup && mMenuOpen) - menuPopup->SyncViewWithFrame(onMenuBar); + menuPopup->SyncViewWithFrame(aPresContext, onMenuBar, this, -1, -1); return nsBoxFrame::DidReflow(aPresContext, aStatus); } diff --git a/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp b/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp index ee7db08116c..c7ea7d4830d 100644 --- a/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -30,6 +30,7 @@ #include "nsIViewManager.h" #include "nsWidgetsCID.h" #include "nsMenuFrame.h" +#include "nsMenuPopupEntryListener.h" const PRInt32 kMaxZ = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32 @@ -87,7 +88,7 @@ NS_IMETHODIMP nsMenuPopupFrame::QueryInterface(REFNSIID aIID, void** aInstancePt // nsMenuPopupFrame cntr // nsMenuPopupFrame::nsMenuPopupFrame() -:mCurrentMenu(nsnull) +:mCurrentMenu(nsnull), mMenuPopupEntryListener(nsnull) { } // cntr @@ -149,10 +150,16 @@ nsMenuPopupFrame::Init(nsIPresContext& aPresContext, &widgetData, nsnull); - // XXX: Don't need? - // ourView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN); + // Register a listener so that we know when the mouse enters + // the menu (have to use moves, since enter is completely flaky). + + // Create the menu bar listener. + mMenuPopupEntryListener = new nsMenuPopupEntryListener(this); - return rv; + nsCOMPtr target = do_QueryInterface(mContent); + nsIDOMEventListener* domEventListener = (nsIDOMMouseMotionListener*)mMenuPopupEntryListener; + target->AddEventListener("mousemove", domEventListener, PR_FALSE); + return rv; } void @@ -174,20 +181,33 @@ nsMenuPopupFrame::GetViewOffset(nsIViewManager* aManager, nsIView* aView, } } +void +nsMenuPopupFrame::GetNearestEnclosingView(nsIFrame* aStartFrame, nsIView** aResult) +{ + *aResult = nsnull; + aStartFrame->GetView(aResult); + if (!*aResult) { + nsIFrame* parent; + aStartFrame->GetParentWithView(&parent); + if (parent) + parent->GetView(aResult); + } +} + nsresult -nsMenuPopupFrame::SyncViewWithFrame(PRBool aOnMenuBar) +nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext& aPresContext, + PRBool aOnMenuBar, + nsIFrame* aFrame, + PRInt32 aXPos, PRInt32 aYPos) { nsPoint parentPos; nsCOMPtr viewManager; - //Get parent frame - nsIFrame* parent; - GetParentWithView(&parent); - NS_ASSERTION(parent, "GetParentWithView failed"); - - // Get parent view + //Get the nearest enclosing parent view to aFrame. nsIView* parentView = nsnull; - parent->GetView(&parentView); + GetNearestEnclosingView(aFrame, &parentView); + if (!parentView) + return NS_OK; parentView->GetViewManager(*getter_AddRefs(viewManager)); GetViewOffset(viewManager, parentView, parentPos); @@ -196,18 +216,22 @@ nsMenuPopupFrame::SyncViewWithFrame(PRBool aOnMenuBar) nsIView* containingView = nsnull; nsPoint offset; - GetOffsetFromView(offset, &containingView); - nsSize size; - GetSize(size); - - nsIFrame* parentFrame; - GetParent(&parentFrame); + aFrame->GetOffsetFromView(offset, &containingView); nsRect parentRect; - parentFrame->GetRect(parentRect); + aFrame->GetRect(parentRect); viewManager->ResizeView(view, mRect.width, mRect.height); - if (aOnMenuBar) + if (aXPos != -1 || aYPos != -1) { + // Convert the screen coords to twips + float p2t; + aPresContext.GetScaledPixelsToTwips(&p2t); + PRInt32 xpos = NSIntPixelsToTwips(aXPos, p2t); + PRInt32 ypos = NSIntPixelsToTwips(aYPos, p2t); + viewManager->MoveViewTo(view, xpos, ypos); + } + + else if (aOnMenuBar) viewManager->MoveViewTo(view, parentPos.x + offset.x, parentPos.y + parentRect.height + offset.y ); else viewManager->MoveViewTo(view, parentPos.x + parentRect.width + offset.x, parentPos.y + offset.y ); @@ -219,7 +243,6 @@ nsMenuPopupFrame::DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus) { nsresult rv = nsBoxFrame::DidReflow(aPresContext, aStatus); - //SyncViewWithFrame(); return rv; } @@ -345,15 +368,20 @@ nsMenuPopupFrame::CaptureMouseEvents(PRBool aGrabMouseEvents) nsCOMPtr viewMan; PRBool result; + nsCOMPtr widget; + if (view) { view->GetViewManager(*getter_AddRefs(viewMan)); if (viewMan) { + view->GetWidget(*getter_AddRefs(widget)); if (aGrabMouseEvents) { viewMan->GrabMouseEvents(view,result); mIsCapturingMouseEvents = PR_TRUE; + widget->CaptureMouse(PR_TRUE); } else { viewMan->GrabMouseEvents(nsnull,result); mIsCapturingMouseEvents = PR_FALSE; + widget->CaptureMouse(PR_FALSE); } } } @@ -567,3 +595,25 @@ nsMenuPopupFrame::IsDisabled(nsIContent* aContent) return PR_TRUE; return PR_FALSE; } + +NS_IMETHODIMP +nsMenuPopupFrame::HandleEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + aEventStatus = nsEventStatus_eConsumeDoDefault; + if (aEvent->message == NS_MOUSE_MOVE) { + printf("Mouse enter!\n"); + //HandleMouseEnterEvent(aPresContext, aEvent, aEventStatus); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsMenuPopupFrame::Destroy(nsIPresContext& aPresContext) +{ + nsCOMPtr target = do_QueryInterface(mContent); + target->RemoveEventListener("mousemove", mMenuPopupEntryListener, PR_TRUE); + return NS_OK; +} diff --git a/mozilla/layout/xul/base/src/nsMenuPopupFrame.h b/mozilla/layout/xul/base/src/nsMenuPopupFrame.h index ea340a347a6..480884eeab2 100644 --- a/mozilla/layout/xul/base/src/nsMenuPopupFrame.h +++ b/mozilla/layout/xul/base/src/nsMenuPopupFrame.h @@ -34,6 +34,7 @@ nsresult NS_NewMenuPopupFrame(nsIFrame** aResult) ; class nsIViewManager; class nsIView; +class nsMenuPopupEntryListener; class nsMenuPopupFrame : public nsBoxFrame, public nsIMenuParent { @@ -66,8 +67,17 @@ public: NS_IMETHOD DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus); + NS_IMETHOD HandleEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + + NS_IMETHOD Destroy(nsIPresContext& aPresContext); + void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint); - nsresult SyncViewWithFrame(PRBool aOnMenuBar); + void GetNearestEnclosingView(nsIFrame* aStartFrame, nsIView** aResult); + + nsresult SyncViewWithFrame(nsIPresContext& aPresContext, PRBool aOnMenuBar, + nsIFrame* aFrame, PRInt32 aXPos, PRInt32 aYPos); NS_IMETHOD CaptureMouseEvents(PRBool aGrabMouseEvents); @@ -85,6 +95,7 @@ public: protected: nsIFrame* mCurrentMenu; // The current menu that is active. PRBool mIsCapturingMouseEvents; // Whether or not we're grabbing the mouse events. + nsMenuPopupEntryListener* mMenuPopupEntryListener; }; // class nsMenuPopupFrame #endif diff --git a/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp b/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp index 6840e7eec09..ce558950456 100644 --- a/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp +++ b/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp @@ -95,11 +95,17 @@ NS_IMETHODIMP nsPopupSetFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr // nsPopupSetFrame cntr // nsPopupSetFrame::nsPopupSetFrame() -:mActiveChild(nsnull), mPresContext(nsnull) +:mPresContext(nsnull), mElementFrame(nsnull) { } // cntr +nsIFrame* +nsPopupSetFrame::GetActiveChild() +{ + return mPopupFrames.FirstChild(); +} + NS_IMETHODIMP nsPopupSetFrame::Init(nsIPresContext& aPresContext, nsIContent* aContent, @@ -146,7 +152,7 @@ nsPopupSetFrame::SetInitialChildList(nsIPresContext& aPresContext, frame->GetContent(getter_AddRefs(content)); nsCOMPtr tag; content->GetTag(*getter_AddRefs(tag)); - if (tag.get() == nsXULAtoms::menupopup) { + if (tag.get() == nsXULAtoms::popup) { // Remove this frame from the list and place it in the other list. frames.RemoveFrame(frame); mPopupFrames.AppendFrame(this, frame); @@ -195,7 +201,7 @@ nsPopupSetFrame::Reflow(nsIPresContext& aPresContext, nsReflowStatus& aStatus) { nsresult rv = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - nsIFrame* frame = mActiveChild; + nsIFrame* frame = GetActiveChild(); if (!frame || (rv != NS_OK)) return rv; @@ -233,15 +239,10 @@ nsPopupSetFrame::DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus) { // Sync up the view. - /*PRBool onMenuBar = PR_FALSE; - if (mMenuParent) - mMenuParent->IsMenuBar(onMenuBar); - - nsIFrame* frame = mPopupFrames.FirstChild(); - nsMenuPopupFrame* menuPopup = (nsMenuPopupFrame*)frame; - if (menuPopup && mMenuOpen) - menuPopup->SyncViewWithFrame(onMenuBar); - */ + nsIFrame* activeChild = GetActiveChild(); + if (activeChild) { + ((nsMenuPopupFrame*)activeChild)->SyncViewWithFrame(aPresContext, PR_TRUE, mElementFrame, mXPos, mYPos); + } return nsBoxFrame::DidReflow(aPresContext, aStatus); } @@ -266,7 +267,7 @@ nsPopupSetFrame::Dirty(const nsHTMLReflowState& aReflowState, nsIFrame*& increme if (rv != NS_OK || incrementalChild) return rv; - nsIFrame* popup = mActiveChild; + nsIFrame* popup = GetActiveChild(); if (popup && (frame == popup)) { // An incremental reflow command is targeting something inside our // hidden popup view. We can't actually return the child, since it @@ -324,7 +325,7 @@ nsPopupSetFrame::InsertFrames(nsIPresContext& aPresContext, nsCOMPtr tag; nsresult rv; frameChild->GetTag(*getter_AddRefs(tag)); - if (tag && tag.get() == nsXULAtoms::menupopup) { + if (tag && tag.get() == nsXULAtoms::popup) { mPopupFrames.InsertFrames(nsnull, nsnull, aFrameList); rv = GenerateDirtyReflowCommand(aPresContext, aPresShell); } else { @@ -354,7 +355,7 @@ nsPopupSetFrame::AppendFrames(nsIPresContext& aPresContext, nsresult rv; frameChild->GetTag(*getter_AddRefs(tag)); - if (tag && tag.get() == nsXULAtoms::menupopup) { + if (tag && tag.get() == nsXULAtoms::popup) { mPopupFrames.AppendFrames(nsnull, aFrameList); rv = GenerateDirtyReflowCommand(aPresContext, aPresShell); } else { @@ -370,18 +371,26 @@ nsPopupSetFrame::CreatePopup(nsIFrame* aElementFrame, nsIContent* aPopupContent, const nsString& aPopupType, const nsString& anAnchorAlignment, const nsString& aPopupAlignment) { - // Generate the popup. - MarkAsGenerated(aPopupContent); - - // Now we'll have it in our child frame list. Make it our active child. - SetActiveChild(aPopupContent); + // Cache the element frame. + mElementFrame = aElementFrame; // Show the popup at the specified position. mXPos = aXPos; mYPos = aYPos; - // Mark the view as active. - ActivateMenuPopup(PR_TRUE); + printf("X Pos: %d\n", mXPos); + printf("Y Pos: %d\n", mYPos); + + if (!OnCreate(aPopupContent)) + return NS_OK; + + // Generate the popup. + MarkAsGenerated(aPopupContent); + + // Now we'll have it in our child frame list. + + // Now open the popup. + OpenPopup(PR_TRUE); return NS_OK; } @@ -414,32 +423,99 @@ nsPopupSetFrame::MarkAsGenerated(nsIContent* aPopupContent) aPopupContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::menugenerated, value); if (value != "true") { - // Ungenerate this element. + // Generate this element. aPopupContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::menugenerated, "true", PR_TRUE); } } void -nsPopupSetFrame::SetActiveChild(nsIContent* aPopupContent) +nsPopupSetFrame::OpenPopup(PRBool aActivateFlag) { - mActiveContent = aPopupContent; // Weak ref - nsIFrame* frame = mPopupFrames.FirstChild(); - while (frame) { - nsCOMPtr childContent; - frame->GetContent(getter_AddRefs(childContent)); - if (childContent.get() == mActiveContent) { - mActiveChild = frame; - break; - } + if (aActivateFlag) { + ActivatePopup(PR_TRUE); + + nsIFrame* activeChild = GetActiveChild(); + } + else { + // Close the menu. + nsIFrame* frame = GetActiveChild(); + nsMenuPopupFrame* menuPopup = (nsMenuPopupFrame*)frame; + + // Make sure we clear out our own items. + if (menuPopup) + menuPopup->SetCurrentMenuItem(nsnull); - frame->GetNextSibling(&frame); + ActivatePopup(PR_FALSE); + + // Set the focus back to our view's widget. + nsIView* view; + mElementFrame->GetView(&view); + if (!view) { + nsPoint offset; + mElementFrame->GetOffsetFromView(offset, &view); + } + nsCOMPtr widget; + view->GetWidget(*getter_AddRefs(widget)); + if (widget) + widget->SetFocus(); } } void -nsPopupSetFrame::ActivateMenuPopup(PRBool aActivateFlag) +nsPopupSetFrame::ActivatePopup(PRBool aActivateFlag) { - - + nsCOMPtr content; + GetActiveChildElement(getter_AddRefs(content)); + if (content) { + if (aActivateFlag) + content->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE); + else content->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE); + } } + +PRBool +nsPopupSetFrame::OnCreate(nsIContent* aPopupContent) +{ + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_MENU_CREATE; + + if (aPopupContent) { + nsresult rv = aPopupContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault ) + return PR_FALSE; + } + + return PR_TRUE; +} + +PRBool +nsPopupSetFrame::OnDestroy() +{ + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_MENU_DESTROY; + + nsCOMPtr content; + GetActiveChildElement(getter_AddRefs(content)); + + if (content) { + nsresult rv = content->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault ) + return PR_FALSE; + } + return PR_TRUE; +} + +void +nsPopupSetFrame::GetActiveChildElement(nsIContent** aResult) +{ + *aResult = nsnull; + nsIFrame* child = GetActiveChild(); + if (child) { + child->GetContent(aResult); + } +} \ No newline at end of file diff --git a/mozilla/layout/xul/base/src/nsPopupSetFrame.h b/mozilla/layout/xul/base/src/nsPopupSetFrame.h index 06c7a677404..c64148a09c4 100644 --- a/mozilla/layout/xul/base/src/nsPopupSetFrame.h +++ b/mozilla/layout/xul/base/src/nsPopupSetFrame.h @@ -94,19 +94,24 @@ public: const nsString& aPopupType, const nsString& anAnchorAlignment, const nsString& aPopupAlignment); + PRBool OnCreate(nsIContent* aPopupContent); + PRBool OnDestroy(); - void ActivateMenuPopup(PRBool aActivateFlag); + void ActivatePopup(PRBool aActivateFlag); + void OpenPopup(PRBool aOpenFlag); + + nsIFrame* GetActiveChild(); + void GetActiveChildElement(nsIContent** aResult); protected: void MarkAsGenerated(nsIContent* aPopupContent); - void SetActiveChild(nsIContent* aPopupContent); - + protected: nsFrameList mPopupFrames; - nsIFrame* mActiveChild; - nsIContent* mActiveContent; // [WEAK] nsIPresContext* mPresContext; // Our pres context. + nsIFrame* mElementFrame; // The frame that is having something popped up over it. + PRInt32 mXPos; // Active child's x position PRInt32 mYPos; // Active child's y position diff --git a/mozilla/layout/xul/content/src/nsXULAtomList.h b/mozilla/layout/xul/content/src/nsXULAtomList.h index 38ed37067fc..a23ab76ef51 100644 --- a/mozilla/layout/xul/content/src/nsXULAtomList.h +++ b/mozilla/layout/xul/content/src/nsXULAtomList.h @@ -73,7 +73,8 @@ XUL_ATOM(menupopup, "menupopup") // The XP menu's children. XUL_ATOM(menuactive, "menuactive") // Whether or not a menu is active (without necessarily being open) XUL_ATOM(accesskey, "accesskey") // The shortcut key for a menu or menu item XUL_ATOM(acceltext, "acceltext") // Text to use for the accelerator -XUL_ATOM(menupopupset, "menupopupset") // Contains popup menus, context menus, and tooltips +XUL_ATOM(popupset, "popupset") // Contains popup menus, context menus, and tooltips +XUL_ATOM(popup, "popup") // The popup for a context menu, popup menu, or tooltip XUL_ATOM(menugenerated, "menugenerated") // Internal XUL_ATOM(key, "key") // A key element