Bug 1354020 - Use per-monitor v2 on Creators Update. r?jfkthame draft
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 07 Apr 2017 07:14:14 +0900
changeset 557477 d112b2df289901862028b10cd8c209d394817c66
parent 556960 950612071c4e5cbd61af6c0f66ed0bc40c35e39c
child 623077 a89c9d3f7a9c0e0967715fbe83d21d7066389b37
push id52742
push userVYV03354@nifty.ne.jp
push dateThu, 06 Apr 2017 22:14:55 +0000
reviewersjfkthame
bugs1354020
milestone55.0a1
Bug 1354020 - Use per-monitor v2 on Creators Update. r?jfkthame MozReview-Commit-ID: FiO3DupULFu
browser/app/firefox.exe.32.manifest
browser/app/firefox.exe.64.manifest
ipc/app/plugin-container.exe.32.manifest
ipc/app/plugin-container.exe.64.manifest
widget/windows/WinUtils.cpp
widget/windows/WinUtils.h
widget/windows/nsWindow.cpp
--- a/browser/app/firefox.exe.32.manifest
+++ b/browser/app/firefox.exe.32.manifest
@@ -30,16 +30,17 @@
     <ms_asmv3:requestedPrivileges>
       <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
     </ms_asmv3:requestedPrivileges>
   </ms_asmv3:security>
 </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/browser/app/firefox.exe.64.manifest
+++ b/browser/app/firefox.exe.64.manifest
@@ -24,16 +24,17 @@
     <ms_asmv3:requestedPrivileges>
       <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
     </ms_asmv3:requestedPrivileges>
   </ms_asmv3:security>
 </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/ipc/app/plugin-container.exe.32.manifest
+++ b/ipc/app/plugin-container.exe.32.manifest
@@ -30,16 +30,17 @@
       <ms_asmv3:requestedPrivileges>
         <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
       </ms_asmv3:requestedPrivileges>
     </ms_asmv3:security>
   </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/ipc/app/plugin-container.exe.64.manifest
+++ b/ipc/app/plugin-container.exe.64.manifest
@@ -24,16 +24,17 @@
       <ms_asmv3:requestedPrivileges>
         <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
       </ms_asmv3:requestedPrivileges>
     </ms_asmv3:security>
   </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -439,36 +439,45 @@ static NtTestAlertPtr sNtTestAlert = nul
 
 /* static */
 void
 WinUtils::Initialize()
 {
   if (IsWin10OrLater()) {
     HMODULE user32Dll = ::GetModuleHandleW(L"user32");
     if (user32Dll) {
-      sEnableNonClientDpiScaling = (EnableNonClientDpiScalingProc)
-        ::GetProcAddress(user32Dll, "EnableNonClientDpiScaling");
-      sSetThreadDpiAwarenessContext = (SetThreadDpiAwarenessContextProc)
-        ::GetProcAddress(user32Dll, "SetThreadDpiAwarenessContext");
+      auto getThreadDpiAwarenessContext = (decltype(GetThreadDpiAwarenessContext)*)
+        ::GetProcAddress(user32Dll, "GetThreadDpiAwarenessContext");
+      auto areDpiAwarenessContextsEqual = (decltype(AreDpiAwarenessContextsEqual)*)
+        ::GetProcAddress(user32Dll, "AreDpiAwarenessContextsEqual");
+      if (getThreadDpiAwarenessContext && areDpiAwarenessContextsEqual &&
+          areDpiAwarenessContextsEqual(getThreadDpiAwarenessContext(),
+                                       DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) {
+        // Only per-monitor v1 requires these workarounds.
+        sEnableNonClientDpiScaling = (EnableNonClientDpiScalingProc)
+          ::GetProcAddress(user32Dll, "EnableNonClientDpiScaling");
+        sSetThreadDpiAwarenessContext = (SetThreadDpiAwarenessContextProc)
+          ::GetProcAddress(user32Dll, "SetThreadDpiAwarenessContext");
+      }
     }
   }
 
 #ifdef ACCESSIBILITY
   sNtTestAlert = reinterpret_cast<NtTestAlertPtr>(
       ::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), "NtTestAlert"));
   MOZ_ASSERT(sNtTestAlert);
 #endif
 }
 
 // static
 LRESULT WINAPI
 WinUtils::NonClientDpiScalingDefWindowProcW(HWND hWnd, UINT msg,
                                             WPARAM wParam, LPARAM lParam)
 {
-  if (msg == WM_NCCREATE && sEnableNonClientDpiScaling) {
+  if (msg == WM_NCCREATE) {
     sEnableNonClientDpiScaling(hWnd);
   }
   return ::DefWindowProcW(hWnd, msg, wParam, lParam);
 }
 
 // static
 void
 WinUtils::LogW(const wchar_t *fmt, ...)
--- a/widget/windows/WinUtils.h
+++ b/widget/windows/WinUtils.h
@@ -91,16 +91,21 @@ typedef enum DPI_AWARENESS {
 
 #define DPI_AWARENESS_CONTEXT_UNAWARE           ((DPI_AWARENESS_CONTEXT)-1)
 #define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE      ((DPI_AWARENESS_CONTEXT)-2)
 #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
 
 #define DPI_AWARENESS_CONTEXT_DECLARED
 #endif // (DPI_AWARENESS_CONTEXT_DECLARED)
 
+#if WINVER < 0x0605
+WINUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext();
+WINUSERAPI BOOL WINAPI
+AreDpiAwarenessContextsEqual(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT);
+#endif /* WINVER < 0x0605 */
 typedef DPI_AWARENESS_CONTEXT(WINAPI * SetThreadDpiAwarenessContextProc)(DPI_AWARENESS_CONTEXT);
 typedef BOOL(WINAPI * EnableNonClientDpiScalingProc)(HWND);
 
 namespace mozilla {
 namespace widget {
 
 // Windows message debugging data
 typedef struct {
@@ -147,16 +152,22 @@ public:
 
 class WinUtils
 {
   // Function pointers for APIs that may not be available depending on
   // the Win10 update version -- will be set up in Initialize().
   static SetThreadDpiAwarenessContextProc sSetThreadDpiAwarenessContext;
   static EnableNonClientDpiScalingProc sEnableNonClientDpiScaling;
 
+  // Wrapper for DefWindowProc that will enable non-client dpi scaling on the
+  // window during creation.
+  static LRESULT WINAPI
+  NonClientDpiScalingDefWindowProcW(HWND hWnd, UINT msg,
+                                    WPARAM wParam, LPARAM lParam);
+
 public:
   class AutoSystemDpiAware
   {
   public:
     AutoSystemDpiAware()
     {
       if (sSetThreadDpiAwarenessContext) {
         mPrevContext = sSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
@@ -169,21 +180,21 @@ public:
         sSetThreadDpiAwarenessContext(mPrevContext);
       }
     }
 
   private:
     DPI_AWARENESS_CONTEXT mPrevContext;
   };
 
-  // Wrapper for DefWindowProc that will enable non-client dpi scaling on the
-  // window during creation.
-  static LRESULT WINAPI
-  NonClientDpiScalingDefWindowProcW(HWND hWnd, UINT msg,
-                                    WPARAM wParam, LPARAM lParam);
+  static decltype(::DefWindowProcW)* GetDefWindowProc()
+  {
+    return sEnableNonClientDpiScaling ? NonClientDpiScalingDefWindowProcW :
+                                        ::DefWindowProcW;
+  }
 
   /**
    * Get the system's default logical-to-physical DPI scaling factor,
    * which is based on the primary display. Note however that unlike
    * LogToPhysFactor(GetPrimaryMonitor()), this will not change during
    * a session even if the displays are reconfigured. This scale factor
    * is used by Windows theme metrics etc, which do not fully support
    * dynamic resolution changes but are only updated on logout.
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -1010,17 +1010,17 @@ nsWindow::RegisterWindowClass(const wcha
 {
   WNDCLASSW wc;
   if (::GetClassInfoW(nsToolkit::mDllInstance, aClassName, &wc)) {
     // already registered
     return aClassName;
   }
 
   wc.style         = CS_DBLCLKS | aExtraStyle;
-  wc.lpfnWndProc   = WinUtils::NonClientDpiScalingDefWindowProcW;
+  wc.lpfnWndProc   = WinUtils::GetDefWindowProc();
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hInstance     = nsToolkit::mDllInstance;
   wc.hIcon         = aIconID ? ::LoadIconW(::GetModuleHandleW(nullptr), aIconID) : nullptr;
   wc.hCursor       = nullptr;
   wc.hbrBackground = mBrush;
   wc.lpszMenuName  = nullptr;
   wc.lpszClassName = aClassName;