Bug 1776498 - Use popup class with all popups. r=Jamie,handyman
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 20 Jul 2022 09:45:04 +0000
changeset 624479 18a7f69d5ce40c433f207c6c31124369b569f891
parent 624478 3e28a015ff201a6ca1fdd213bbc0f16d44b5e4c9
child 624480 c70715f298224de916f920be9df3e67475a985ef
push id40007
push usersmolnar@mozilla.com
push dateWed, 20 Jul 2022 21:52:02 +0000
treeherdermozilla-central@16a4302fb1a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamie, handyman
bugs1776498
milestone104.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1776498 - Use popup class with all popups. r=Jamie,handyman Manage their shadow style per-window instead. It is a bit unfortunate, but alas, seems to work, and we had existing code for various workarounds, so it's not too gross. The menulist special-case isn't needed anymore, menulists always have eTransparencyTransparent nowadays on Windows. Differential Revision: https://phabricator.services.mozilla.com/D151994
layout/xul/nsMenuPopupFrame.cpp
widget/nsWidgetInitData.h
widget/windows/WinMessages.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowDefs.h
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -359,29 +359,21 @@ nsresult nsMenuPopupFrame::CreateWidgetF
             widgetData.mBorderStyle | eBorderStyle_close);
       }
     }
   }
 
   bool remote = HasRemoteContent();
 
   nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(this, this);
-  nsIContent* parentContent = GetContent()->GetParent();
-  nsAtom* tag = nullptr;
-  if (parentContent && parentContent->IsXULElement())
-    tag = parentContent->NodeInfo()->NameAtom();
   widgetData.mHasRemoteContent = remote;
   widgetData.mSupportTranslucency = mode == eTransparencyTransparent;
   widgetData.mPopupLevel = PopupLevel(widgetData.mNoAutoHide);
 
-  // The special cases are menulists.
-  widgetData.mDropShadow =
-      !(mode == eTransparencyTransparent || tag == nsGkAtoms::menulist);
-
-  // panels which have a parent level need a parent widget. This allows them to
+  // Panels which have a parent level need a parent widget. This allows them to
   // always appear in front of the parent window but behind other windows that
   // should be in front of it.
   nsCOMPtr<nsIWidget> parentWidget;
   if (widgetData.mPopupLevel != ePopupLevelTop) {
     nsCOMPtr<nsIDocShellTreeItem> dsti = PresContext()->GetDocShell();
     if (!dsti) return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
--- a/widget/nsWidgetInitData.h
+++ b/widget/nsWidgetInitData.h
@@ -92,17 +92,16 @@ struct nsWidgetInitData {
 
   nsWindowType mWindowType = eWindowType_child;
   nsBorderStyle mBorderStyle = eBorderStyle_default;
   nsPopupType mPopupHint = ePopupTypePanel;
   nsPopupLevel mPopupLevel = ePopupLevelTop;
   // when painting exclude area occupied by child windows and sibling windows
   bool mClipChildren = false;
   bool mClipSiblings = false;
-  bool mDropShadow = false;
   bool mRTL = false;
   bool mNoAutoHide = false;   // true for noautohide panels
   bool mIsDragPopup = false;  // true for drag feedback panels
   // true if window creation animation is suppressed, e.g. for session restore
   bool mIsAnimationSuppressed = false;
   // true if the window should support an alpha channel, if available.
   bool mSupportTranslucency = false;
   bool mHasRemoteContent = false;
--- a/widget/windows/WinMessages.h
+++ b/widget/windows/WinMessages.h
@@ -37,19 +37,16 @@
 // Internal message used for rolling up popups for dmanip events
 #define MOZ_WM_DMANIP (WM_APP + 0x0317)
 
 // XXX Should rename them to MOZ_WM_* and use safer values!
 // Messages for fullscreen transition window
 #define WM_FULLSCREEN_TRANSITION_BEFORE (WM_USER + 0)
 #define WM_FULLSCREEN_TRANSITION_AFTER (WM_USER + 1)
 
-// Drop shadow window style
-#define CS_XP_DROPSHADOW 0x00020000
-
 #ifndef APPCOMMAND_BROWSER_BACKWARD
 #  define APPCOMMAND_BROWSER_BACKWARD 1
 #  define APPCOMMAND_BROWSER_FORWARD 2
 #  define APPCOMMAND_BROWSER_REFRESH 3
 #  define APPCOMMAND_BROWSER_STOP 4
 #  define APPCOMMAND_BROWSER_SEARCH 5
 #  define APPCOMMAND_BROWSER_FAVORITES 6
 #  define APPCOMMAND_BROWSER_HOME 7
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -255,17 +255,16 @@ using namespace mozilla::plugins;
 
 /**************************************************************
  *
  * SECTION: nsWindow statics
  *
  **************************************************************/
 static const wchar_t kUser32LibName[] = L"user32.dll";
 
-bool nsWindow::sDropShadowEnabled = true;
 uint32_t nsWindow::sInstanceCount = 0;
 bool nsWindow::sSwitchKeyboardLayout = false;
 BOOL nsWindow::sIsOleInitialized = FALSE;
 nsIWidget::Cursor nsWindow::sCurrentCursor = {};
 nsWindow* nsWindow::sCurrentWindow = nullptr;
 bool nsWindow::sJustGotDeactivate = false;
 bool nsWindow::sJustGotActivate = false;
 bool nsWindow::sIsInMouseCapture = false;
@@ -1015,23 +1014,17 @@ nsresult nsWindow::Create(nsIWidget* aPa
     } else {
       style &= ~WS_CLIPCHILDREN;
     }
     if (aInitData->mClipSiblings) {
       style |= WS_CLIPSIBLINGS;
     }
   }
 
-  const wchar_t* className;
-  if (aInitData->mDropShadow) {
-    className = GetWindowPopupClass();
-  } else {
-    className = GetWindowClass();
-  }
-
+  const wchar_t* className = GetWindowClass();
   if (aInitData->mWindowType == eWindowType_toplevel && !aParent &&
       !sFirstTopLevelWindowCreated) {
     sFirstTopLevelWindowCreated = true;
     mWnd = ConsumePreXULSkeletonUIHandle();
     auto skeletonUIError = GetPreXULSkeletonUIErrorReason();
     if (skeletonUIError) {
       nsAutoString errorString(
           GetPreXULSkeletonUIErrorString(skeletonUIError.value()));
@@ -1355,28 +1348,25 @@ static LPWSTR const gStockApplicationIco
 
 // Return the proper window class for everything except popups.
 const wchar_t* nsWindow::GetWindowClass() const {
   switch (mWindowType) {
     case eWindowType_invisible:
       return RegisterWindowClass(kClassNameHidden, 0, gStockApplicationIcon);
     case eWindowType_dialog:
       return RegisterWindowClass(kClassNameDialog, 0, 0);
+    case eWindowType_popup:
+      return RegisterWindowClass(kClassNameDropShadow, CS_DROPSHADOW,
+                                 gStockApplicationIcon);
     default:
       return RegisterWindowClass(GetMainWindowClass(), 0,
                                  gStockApplicationIcon);
   }
 }
 
-// Return the proper popup window class
-const wchar_t* nsWindow::GetWindowPopupClass() const {
-  return RegisterWindowClass(kClassNameDropShadow, CS_XP_DROPSHADOW,
-                             gStockApplicationIcon);
-}
-
 /**************************************************************
  *
  * SECTION: Window styles utilities
  *
  * Return the proper windows styles and extended styles.
  *
  **************************************************************/
 
@@ -1680,33 +1670,37 @@ void nsWindow::Show(bool bState) {
     // already fired focus on a descendant.
     if (::GetFocus() == mWnd && !GetAccService()) {
       ::NotifyWinEvent(EVENT_OBJECT_FOCUS, mWnd, OBJID_CLIENT, CHILDID_SELF);
     }
 #endif  // defined(ACCESSIBILITY)
   }
 
   if (mWindowType == eWindowType_popup) {
-    // See bug 603793. When we try to draw D3D9/10 windows with a drop shadow
-    // without the DWM on a secondary monitor, windows fails to composite
-    // our windows correctly. We therefor switch off the drop shadow for
-    // pop-up windows when the DWM is disabled and two monitors are
-    // connected.
-    if (HasBogusPopupsDropShadowOnMultiMonitor() &&
-        WinUtils::GetMonitorCount() > 1 &&
-        !gfxWindowsPlatform::GetPlatform()->DwmCompositionEnabled()) {
-      if (sDropShadowEnabled) {
-        ::SetClassLongA(mWnd, GCL_STYLE, 0);
-        sDropShadowEnabled = false;
-      }
-    } else {
-      if (!sDropShadowEnabled) {
-        ::SetClassLongA(mWnd, GCL_STYLE, CS_DROPSHADOW);
-        sDropShadowEnabled = true;
-      }
+    const bool shouldUseDropShadow = [&] {
+      if (mTransparencyMode == eTransparencyTransparent) {
+        return false;
+      }
+      if (HasBogusPopupsDropShadowOnMultiMonitor() &&
+          WinUtils::GetMonitorCount() > 1 &&
+          !gfxWindowsPlatform::GetPlatform()->DwmCompositionEnabled()) {
+        // See bug 603793. When we try to draw D3D9/10 windows with a drop
+        // shadow without the DWM on a secondary monitor, windows fails to
+        // composite our windows correctly. We therefor switch off the drop
+        // shadow for pop-up windows when the DWM is disabled and two monitors
+        // are connected.
+        return false;
+      }
+      return true;
+    }();
+
+    static bool sShadowEnabled = true;
+    if (sShadowEnabled != shouldUseDropShadow) {
+      ::SetClassLongA(mWnd, GCL_STYLE, shouldUseDropShadow ? CS_DROPSHADOW : 0);
+      sShadowEnabled = shouldUseDropShadow;
     }
 
     // WS_EX_COMPOSITED conflicts with the WS_EX_LAYERED style and causes
     // some popup menus to become invisible.
     LONG_PTR exStyle = ::GetWindowLongPtrW(mWnd, GWL_EXSTYLE);
     if (exStyle & WS_EX_LAYERED) {
       ::SetWindowLongPtrW(mWnd, GWL_EXSTYLE, exStyle & ~WS_EX_COMPOSITED);
     }
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -691,17 +691,16 @@ class nsWindow final : public nsBaseWidg
   void OnFullscreenWillChange(bool aFullScreen);
   void OnFullscreenChanged(bool aFullScreen);
 
   static void OnCloakEvent(HWND aWnd, bool aCloaked);
   void OnCloakChanged(bool aCloaked);
 
   static bool sTouchInjectInitialized;
   static InjectTouchInputPtr sInjectTouchFuncPtr;
-  static bool sDropShadowEnabled;
   static uint32_t sInstanceCount;
   static TriStateBool sCanQuit;
   static nsWindow* sCurrentWindow;
   static BOOL sIsOleInitialized;
   static Cursor sCurrentCursor;
   static bool sSwitchKeyboardLayout;
   static bool sJustGotDeactivate;
   static bool sJustGotActivate;
--- a/widget/windows/nsWindowDefs.h
+++ b/widget/windows/nsWindowDefs.h
@@ -58,18 +58,19 @@ typedef enum { TRI_UNKNOWN = -1, TRI_FAL
 /*
  * Native windows class names
  *
  * ::: IMPORTANT :::
  *
  * External apps and drivers depend on window class names.
  * For example, changing the window classes could break
  * touchpad scrolling or screen readers.
+ *
+ * See bug 1776498.
  */
-const uint32_t kMaxClassNameLength = 40;
 const wchar_t kClassNameHidden[] = L"MozillaHiddenWindowClass";
 const wchar_t kClassNameGeneral[] = L"MozillaWindowClass";
 const wchar_t kClassNameDialog[] = L"MozillaDialogClass";
 const wchar_t kClassNameDropShadow[] = L"MozillaDropShadowWindowClass";
 const wchar_t kClassNameTemp[] = L"MozillaTempWindowClass";
 const wchar_t kClassNameTransition[] = L"MozillaTransitionWindowClass";
 
 /**************************************************************