mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1701770 - Defer Windows DPI Awareness from load time to run time r=bobowen,aklotz
Currently, we set DPI awareness in the manifest files for firefox.exe. Unfortunately, that causes DPI-related Win32k calls when user32.dll is loaded. This changes things to wait until we are sure we're not running in a Win32k Lockdown Content Process before we attempt to initialize DPI scaling. Differential Revision: https://phabricator.services.mozilla.com/D116433
This commit is contained in:
parent
06ed013306
commit
38d538c966
@ -36,12 +36,6 @@
|
||||
</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}"/>
|
||||
|
@ -28,6 +28,7 @@
|
||||
# include "freestanding/SharedSection.h"
|
||||
# include "LauncherProcessWin.h"
|
||||
# include "mozilla/WindowsDllBlocklist.h"
|
||||
# include "mozilla/WindowsDpiInitialization.h"
|
||||
|
||||
# define XRE_WANT_ENVIRON
|
||||
# define strcasecmp _stricmp
|
||||
@ -296,6 +297,19 @@ int main(int argc, char* argv[], char* envp[]) {
|
||||
DllBlocklist_Initialize(gBlocklistInitFlags |
|
||||
eDllBlocklistInitFlagIsChildProcess);
|
||||
# endif
|
||||
# if defined(XP_WIN)
|
||||
// Ideally, we would be able to set our DPI awareness in
|
||||
// firefox.exe.manifest Unfortunately, that would cause Win32k calls when
|
||||
// user32.dll gets loaded, which would be incompatible with Win32k Lockdown
|
||||
//
|
||||
// MSDN says that it's allowed-but-not-recommended to initialize DPI
|
||||
// programatically, as long as it's done before any HWNDs are created.
|
||||
// Thus, we do it almost as soon as we possibly can
|
||||
{
|
||||
auto result = mozilla::WindowsDpiInitialization();
|
||||
(void)result; // Ignore errors since some tools block DPI calls
|
||||
}
|
||||
# endif
|
||||
# if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
// We need to initialize the sandbox TargetServices before InitXPCOMGlue
|
||||
// because we might need the sandbox broker to give access to some files.
|
||||
@ -328,6 +342,19 @@ int main(int argc, char* argv[], char* envp[]) {
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
// Ideally, we would be able to set our DPI awareness in firefox.exe.manifest
|
||||
// Unfortunately, that would cause Win32k calls when user32.dll gets loaded,
|
||||
// which would be incompatible with Win32k Lockdown
|
||||
//
|
||||
// MSDN says that it's allowed-but-not-recommended to initialize DPI
|
||||
// programatically, as long as it's done before any HWNDs are created.
|
||||
// Thus, we do it almost as soon as we possibly can
|
||||
{
|
||||
auto result = mozilla::WindowsDpiInitialization();
|
||||
(void)result; // Ignore errors since some tools block DPI calls
|
||||
}
|
||||
|
||||
// Once the browser process hits the main function, we no longer need
|
||||
// a writable section handle because all dependent modules have been
|
||||
// loaded.
|
||||
|
73
mozglue/misc/WindowsDpiInitialization.cpp
Normal file
73
mozglue/misc/WindowsDpiInitialization.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/WindowsDpiInitialization.h"
|
||||
|
||||
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
|
||||
#include "mozilla/WindowsProcessMitigations.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
||||
#include <shellscalingapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
typedef HRESULT(WINAPI* SetProcessDpiAwarenessType)(PROCESS_DPI_AWARENESS);
|
||||
typedef BOOL(WINAPI* SetProcessDpiAwarenessContextType)(DPI_AWARENESS_CONTEXT);
|
||||
|
||||
WindowsDpiInitializationResult WindowsDpiInitialization() {
|
||||
// DPI Awareness can't be used in a Win32k Lockdown process, so there's
|
||||
// nothing to do
|
||||
if (IsWin32kLockedDown()) {
|
||||
return WindowsDpiInitializationResult::Success;
|
||||
}
|
||||
|
||||
// From MSDN:
|
||||
// SetProcessDpiAwarenessContext() was added in the Win10 Anniversary Update
|
||||
// SetProcessDpiAwareness() was added in Windows 8.1
|
||||
// SetProcessDpiAware() was added in Windows Vista
|
||||
//
|
||||
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 wasn't added later until
|
||||
// the Creators Update, so if it fails we just fall back to
|
||||
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
|
||||
if (IsWin10AnniversaryUpdateOrLater()) {
|
||||
DynamicallyLinkedFunctionPtr<SetProcessDpiAwarenessContextType>
|
||||
setProcessDpiAwarenessContext(L"user32.dll",
|
||||
"SetProcessDpiAwarenessContext");
|
||||
if (!setProcessDpiAwarenessContext) {
|
||||
return WindowsDpiInitializationResult::
|
||||
FindSetProcessDpiAwarenessContextFailed;
|
||||
}
|
||||
|
||||
if (!setProcessDpiAwarenessContext(
|
||||
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) &&
|
||||
!setProcessDpiAwarenessContext(
|
||||
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) {
|
||||
return WindowsDpiInitializationResult::
|
||||
SetProcessDpiAwarenessContextFailed;
|
||||
}
|
||||
|
||||
return WindowsDpiInitializationResult::Success;
|
||||
} else if (IsWin8Point1OrLater()) {
|
||||
DynamicallyLinkedFunctionPtr<SetProcessDpiAwarenessType>
|
||||
setProcessDpiAwareness(L"Shcore.dll", "SetProcessDpiAwareness");
|
||||
if (!setProcessDpiAwareness) {
|
||||
return WindowsDpiInitializationResult::FindSetProcessDpiAwarenessFailed;
|
||||
}
|
||||
|
||||
if (FAILED(setProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE))) {
|
||||
return WindowsDpiInitializationResult::SetProcessDpiAwarenessFailed;
|
||||
}
|
||||
|
||||
return WindowsDpiInitializationResult::Success;
|
||||
} else {
|
||||
if (!SetProcessDPIAware()) {
|
||||
return WindowsDpiInitializationResult::SetProcessDPIAwareFailed;
|
||||
}
|
||||
|
||||
return WindowsDpiInitializationResult::Success;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
54
mozglue/misc/WindowsDpiInitialization.h
Normal file
54
mozglue/misc/WindowsDpiInitialization.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_MOZGLUE_MISC_WINDOWSDPIINITIALIZATION_H_
|
||||
#define MOZILLA_MOZGLUE_MISC_WINDOWSDPIINITIALIZATION_H_
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// The result codes that may be returned from WindowsDpiInitialization()
|
||||
enum class WindowsDpiInitializationResult : uint32_t {
|
||||
Success,
|
||||
FindSetProcessDpiAwarenessContextFailed,
|
||||
SetProcessDpiAwarenessContextFailed,
|
||||
FindSetProcessDpiAwarenessFailed,
|
||||
SetProcessDpiAwarenessFailed,
|
||||
SetProcessDPIAwareFailed,
|
||||
};
|
||||
|
||||
// Get a string representation of any WindowsDpiInitializationResult value
|
||||
inline const char* WindowsDpiInitializationResultString(
|
||||
WindowsDpiInitializationResult result) {
|
||||
switch (result) {
|
||||
case WindowsDpiInitializationResult::Success:
|
||||
return "Success";
|
||||
case WindowsDpiInitializationResult::
|
||||
FindSetProcessDpiAwarenessContextFailed:
|
||||
return "Failed to find SetProcessDpiAwarenessContext";
|
||||
case WindowsDpiInitializationResult::SetProcessDpiAwarenessContextFailed:
|
||||
return "SetProcessDpiAwarenessContext failed";
|
||||
case WindowsDpiInitializationResult::FindSetProcessDpiAwarenessFailed:
|
||||
return "Failed to find SetProcessDpiAwareness";
|
||||
case WindowsDpiInitializationResult::SetProcessDpiAwarenessFailed:
|
||||
return "SetProcessDpiAwareness failed";
|
||||
case WindowsDpiInitializationResult::SetProcessDPIAwareFailed:
|
||||
return "SetProcessDPIAware failed";
|
||||
default:
|
||||
return "Unknown result";
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize DPI awareness to the best available for the current OS
|
||||
// According to MSDN, this will be:
|
||||
// Per-Monitor V2 for Windows 10 Creators Update (1703) and later
|
||||
// Per-Monitor V1 for Windows 8.1 and later
|
||||
// System DPI for Vista and later (we don't support anything older)
|
||||
// https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
|
||||
MFBT_API WindowsDpiInitializationResult WindowsDpiInitialization();
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_MOZGLUE_MISC_WINDOWSDPIINITIALIZATION_H_
|
@ -59,6 +59,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
||||
"DynamicallyLinkedFunctionPtr.h",
|
||||
"ImportDir.h",
|
||||
"NativeNt.h",
|
||||
"WindowsDpiInitialization.h",
|
||||
"WindowsEnumProcessModules.h",
|
||||
"WindowsMapRemoteView.h",
|
||||
"WindowsProcessMitigations.h",
|
||||
@ -69,6 +70,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
||||
SOURCES += [
|
||||
"PreXULSkeletonUI.cpp",
|
||||
"TimeStamp_windows.cpp",
|
||||
"WindowsDpiInitialization.cpp",
|
||||
"WindowsMapRemoteView.cpp",
|
||||
"WindowsProcessMitigations.cpp",
|
||||
"WindowsUnicode.cpp",
|
||||
|
Loading…
Reference in New Issue
Block a user