Bug 608515 Painting methods should use consistent composition state between WM_DWMCOMPOSITIONCHANGED messages r=jimm, a=final+
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 18 Nov 2010 11:31:22 +0900
changeset 57844 c7128de9595a8bdc160f033682213d9178d6fe7b
parent 57843 2c5363747246cd55a2a572cc607790674d22f7e9
child 57845 c3c229aaf5310cfaf67188d1ae5f3e214d8cef99
push idunknown
push userunknown
push dateunknown
reviewersjimm, final
bugs608515
milestone2.0b8pre
Bug 608515 Painting methods should use consistent composition state between WM_DWMCOMPOSITIONCHANGED messages r=jimm, a=final+
widget/src/windows/nsUXThemeData.cpp
widget/src/windows/nsUXThemeData.h
widget/src/windows/nsWindow.cpp
--- a/widget/src/windows/nsUXThemeData.cpp
+++ b/widget/src/windows/nsUXThemeData.cpp
@@ -141,17 +141,17 @@ nsUXThemeData::Initialize()
     dwmExtendFrameIntoClientAreaPtr = (DwmExtendFrameIntoClientAreaProc)::GetProcAddress(sDwmDLL, "DwmExtendFrameIntoClientArea");
     dwmIsCompositionEnabledPtr = (DwmIsCompositionEnabledProc)::GetProcAddress(sDwmDLL, "DwmIsCompositionEnabled");
     dwmSetIconicThumbnailPtr = (DwmSetIconicThumbnailProc)::GetProcAddress(sDwmDLL, "DwmSetIconicThumbnail");
     dwmSetIconicLivePreviewBitmapPtr = (DwmSetIconicLivePreviewBitmapProc)::GetProcAddress(sDwmDLL, "DwmSetIconicLivePreviewBitmap");
     dwmGetWindowAttributePtr = (DwmGetWindowAttributeProc)::GetProcAddress(sDwmDLL, "DwmGetWindowAttribute");
     dwmSetWindowAttributePtr = (DwmSetWindowAttributeProc)::GetProcAddress(sDwmDLL, "DwmSetWindowAttribute");
     dwmInvalidateIconicBitmapsPtr = (DwmInvalidateIconicBitmapsProc)::GetProcAddress(sDwmDLL, "DwmInvalidateIconicBitmaps");
     dwmDwmDefWindowProcPtr = (DwmDefWindowProcProc)::GetProcAddress(sDwmDLL, "DwmDefWindowProc");
-    CheckForCompositor();
+    CheckForCompositor(PR_TRUE);
   }
 #endif
 
   Invalidate();
 }
 
 void
 nsUXThemeData::Invalidate() {
--- a/widget/src/windows/nsUXThemeData.h
+++ b/widget/src/windows/nsUXThemeData.h
@@ -227,18 +227,25 @@ public:
   static DwmSetIconicThumbnailProc dwmSetIconicThumbnailPtr;
   static DwmSetIconicLivePreviewBitmapProc dwmSetIconicLivePreviewBitmapPtr;
   static DwmGetWindowAttributeProc dwmGetWindowAttributePtr;
   static DwmSetWindowAttributeProc dwmSetWindowAttributePtr;
   static DwmInvalidateIconicBitmapsProc dwmInvalidateIconicBitmapsPtr;
   static DwmDefWindowProcProc dwmDwmDefWindowProcPtr;
 #endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
 
-  static PRBool CheckForCompositor() {
-    BOOL compositionIsEnabled = FALSE;
+  // This method returns the cached compositor state. Most
+  // callers should call without the argument. The cache
+  // should be modified only when the application receives
+  // WM_DWMCOMPOSITIONCHANGED. This rule prevents inconsistent
+  // results for two or more calls which check the state during
+  // composition transition.
+  static PRBool CheckForCompositor(PRBool aUpdateCache = PR_FALSE) {
+    static BOOL sCachedValue = FALSE;
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-    if(dwmIsCompositionEnabledPtr)
-      dwmIsCompositionEnabledPtr(&compositionIsEnabled);
+    if(aUpdateCache && dwmIsCompositionEnabledPtr) {
+      dwmIsCompositionEnabledPtr(&sCachedValue);
+    }
 #endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
-    return (compositionIsEnabled != FALSE);
+    return (sCachedValue != FALSE);
   }
 };
 #endif // __UXThemeData_h__
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -5294,16 +5294,20 @@ PRBool nsWindow::ProcessMessage(UINT msg
       if (OnMouseWheel(msg, wParam, lParam, getWheelInfo, result, aRetValue))
         return result;
     }
     break;
 
 #ifndef WINCE
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
   case WM_DWMCOMPOSITIONCHANGED:
+    // First, update the compositor state to latest one. All other methods
+    // should use same state as here for consistency painting.
+    nsUXThemeData::CheckForCompositor(PR_TRUE);
+
     UpdateNonClientMargins();
     RemovePropW(mWnd, kManageWindowInfoProperty);
     BroadcastMsg(mWnd, WM_DWMCOMPOSITIONCHANGED);
     DispatchStandardEvent(NS_THEMECHANGED);
     UpdateGlass();
     Invalidate(PR_FALSE);
     break;
 #endif