Bug 412954 - "menus should have Menu, PopupMenu or DropdownMenu window type" [p=ventnor.bugzilla@yahoo.com.au (Michael Ventnor) r+sr=roc a1.9=beltzner]
authorreed@reedloden.com
Sat, 08 Mar 2008 03:32:25 -0800
changeset 12796 b8dc1ab73cf84310f655bd7279b5b18524b83d46
parent 12795 b703593a7e9c52c981d3422848b34ca990157179
child 12797 fd782c173df2ffded476012175d848fc37149ed5
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs412954
milestone1.9b5pre
Bug 412954 - "menus should have Menu, PopupMenu or DropdownMenu window type" [p=ventnor.bugzilla@yahoo.com.au (Michael Ventnor) r+sr=roc a1.9=beltzner]
layout/xul/base/public/nsXULPopupManager.h
layout/xul/base/src/nsMenuPopupFrame.cpp
widget/public/nsIWidget.h
widget/src/gtk2/nsWindow.cpp
--- a/layout/xul/base/public/nsXULPopupManager.h
+++ b/layout/xul/base/public/nsXULPopupManager.h
@@ -72,23 +72,16 @@
 class nsIPresShell;
 class nsMenuFrame;
 class nsMenuPopupFrame;
 class nsMenuBarFrame;
 class nsIMenuParent;
 class nsIDOMKeyEvent;
 class nsIDocShellTreeItem;
 
-enum nsPopupType {
-  ePopupTypePanel,
-  ePopupTypeMenu,
-  ePopupTypeTooltip,
-  ePopupTypeAny = 0xF000 // used only to pass to GetTopPopup
-};
-
 // when a menu command is executed, the closemenu attribute may be used
 // to define how the menu should be closed up
 enum CloseMenuMode {
   CloseMenuMode_Auto, // close up the chain of menus, default value
   CloseMenuMode_None, // don't close up any menus
   CloseMenuMode_Single // close up only the menu the command is inside
 };
 
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -202,16 +202,17 @@ nsMenuPopupFrame::EnsureWidget()
 nsresult
 nsMenuPopupFrame::CreateWidgetForView(nsIView* aView)
 {
   // Create a widget for ourselves.
   nsWidgetInitData widgetData;
   widgetData.mWindowType = eWindowType_popup;
   widgetData.mBorderStyle = eBorderStyle_default;
   widgetData.clipSiblings = PR_TRUE;
+  widgetData.mPopupHint = mPopupType;
 
   PRBool viewHasTransparentContent = !mInContentShell &&
                                      nsLayoutUtils::FrameHasTransparency(this);
   nsIContent* parentContent = GetContent()->GetParent();
   nsIAtom *tag = nsnull;
   if (parentContent)
     tag = parentContent->Tag();
   widgetData.mDropShadow = !(viewHasTransparentContent || tag == nsGkAtoms::menulist);
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -123,16 +123,23 @@ enum nsWindowType {     // Don't alter p
   // plugin window
   eWindowType_plugin,
   // java plugin window
   eWindowType_java,
   // MacOSX sheet (special dialog class)
   eWindowType_sheet
 };
 
+enum nsPopupType {
+  ePopupTypePanel,
+  ePopupTypeMenu,
+  ePopupTypeTooltip,
+  ePopupTypeAny = 0xF000 // used only to pass to nsXULPopupManager::GetTopPopup
+};
+
 enum nsBorderStyle
 {
   // no border, titlebar, etc.. opposite of all
   eBorderStyle_none     = 0,
 
   // all window decorations
   eBorderStyle_all      = 1 << 0,
 
@@ -233,27 +240,29 @@ struct nsWidgetInitData {
   nsWidgetInitData()
     : clipChildren(PR_FALSE), 
       clipSiblings(PR_FALSE), 
       mDropShadow(PR_FALSE),
       mListenForResizes(PR_FALSE),
       mWindowType(eWindowType_child),
       mBorderStyle(eBorderStyle_default),
       mContentType(eContentTypeInherit),
-      mUnicode(PR_TRUE)
+      mUnicode(PR_TRUE),
+      mPopupHint(ePopupTypePanel)
   {
   }
 
   // when painting exclude area occupied by child windows and sibling windows
   PRPackedBool  clipChildren, clipSiblings, mDropShadow;
   PRPackedBool  mListenForResizes;
   nsWindowType mWindowType;
   nsBorderStyle mBorderStyle;
   nsContentType mContentType;  // Exposed so screen readers know what's UI
   PRPackedBool mUnicode;
+  nsPopupType mPopupHint;
 };
 
 /**
  * The base class for all the widgets. It provides the interface for
  * all basic and necessary functionality.
  */
 class nsIWidget : public nsISupports {
 
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -3101,26 +3101,32 @@ nsWindow::NativeCreate(nsIWidget        
                     mWindowGroup = parentnsWindow->mWindowGroup;
                     g_object_ref(G_OBJECT(mWindowGroup));
                     LOG(("adding window %p to group %p\n",
                          (void *)mShell, (void *)mWindowGroup));
                 }
             }
         }
         else if (mWindowType == eWindowType_popup) {
-            // treat popups with a parent as top level windows
-            if (mParent) {
-                mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-                gtk_window_set_wmclass(GTK_WINDOW(mShell), "Toplevel", cBrand.get());
-                gtk_window_set_decorated(GTK_WINDOW(mShell), FALSE);
+            mShell = gtk_window_new(GTK_WINDOW_POPUP);
+            gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", cBrand.get());
+
+            GdkWindowTypeHint gtkTypeHint;
+            switch (aInitData->mPopupHint) {
+                case ePopupTypeMenu:
+                    gtkTypeHint = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
+                    break;
+                case ePopupTypeTooltip:
+                    gtkTypeHint = GDK_WINDOW_TYPE_HINT_TOOLTIP;
+                    break;
+                default:
+                    gtkTypeHint = GDK_WINDOW_TYPE_HINT_UTILITY;
+                    break;
             }
-            else {
-                mShell = gtk_window_new(GTK_WINDOW_POPUP);
-                gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup", cBrand.get());
-            }
+            gtk_window_set_type_hint(GTK_WINDOW(mShell), gtkTypeHint);
 
             if (topLevelParent) {
                 gtk_window_set_transient_for(GTK_WINDOW(mShell),
                                             topLevelParent);
                 mTransientParent = topLevelParent;
 
                 if (topLevelParent->group) {
                     gtk_window_group_add_window(topLevelParent->group,