зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1744687 - Part 1. Lock orientation backend for Windows Tablet. r=gsvelto
Since Windows tablet mode has a orientation lock API, this patch implements orientation lock backend for Windows tablet mode. `GetAutoRotationState` API recognizes whether orientation API is supported on the device. So this fix uses this API to check orientation API capability. Differential Revision: https://phabricator.services.mozilla.com/D162451
This commit is contained in:
Родитель
c14185f7cc
Коммит
3dbf8deeb8
|
@ -63,8 +63,8 @@ elif CONFIG["OS_TARGET"] == "Linux":
|
||||||
elif CONFIG["OS_TARGET"] == "WINNT":
|
elif CONFIG["OS_TARGET"] == "WINNT":
|
||||||
REQUIRES_UNIFIED_BUILD = True
|
REQUIRES_UNIFIED_BUILD = True
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
"fallback/FallbackScreenConfiguration.cpp",
|
|
||||||
"fallback/FallbackVibration.cpp",
|
"fallback/FallbackVibration.cpp",
|
||||||
|
"windows/WindowsScreenConfiguration.cpp",
|
||||||
"windows/WindowsSensor.cpp",
|
"windows/WindowsSensor.cpp",
|
||||||
]
|
]
|
||||||
# WindowsBattery.cpp cannot be built in unified mode because it relies on HalImpl.h.
|
# WindowsBattery.cpp cannot be built in unified mode because it relies on HalImpl.h.
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* 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 "Hal.h"
|
||||||
|
#include "mozilla/WindowsVersion.h"
|
||||||
|
#include "mozilla/widget/ScreenManager.h"
|
||||||
|
#include "nsIWindowsUIUtils.h"
|
||||||
|
#include "WinUtils.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace hal_impl {
|
||||||
|
|
||||||
|
static decltype(SetDisplayAutoRotationPreferences)*
|
||||||
|
sSetDisplayAutoRotationPreferences = nullptr;
|
||||||
|
|
||||||
|
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
||||||
|
const hal::ScreenOrientation& aOrientation) {
|
||||||
|
// SetDisplayAutoRotationPreferences requires Win8, tablet mode and device
|
||||||
|
// support.
|
||||||
|
if (!IsWin8OrLater()) {
|
||||||
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
|
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
|
||||||
|
}
|
||||||
|
AR_STATE state;
|
||||||
|
if (!widget::WinUtils::GetAutoRotationState(&state)) {
|
||||||
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
|
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state & (AR_DISABLED | AR_REMOTESESSION | AR_MULTIMON | AR_NOSENSOR |
|
||||||
|
AR_NOT_SUPPORTED | AR_LAPTOP | AR_DOCKED)) {
|
||||||
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
|
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sSetDisplayAutoRotationPreferences) {
|
||||||
|
HMODULE user32dll = GetModuleHandleW(L"user32.dll");
|
||||||
|
if (user32dll) {
|
||||||
|
sSetDisplayAutoRotationPreferences =
|
||||||
|
(decltype(SetDisplayAutoRotationPreferences)*)GetProcAddress(
|
||||||
|
user32dll, "SetDisplayAutoRotationPreferences");
|
||||||
|
}
|
||||||
|
if (!sSetDisplayAutoRotationPreferences) {
|
||||||
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
|
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ORIENTATION_PREFERENCE orientation = ORIENTATION_PREFERENCE_NONE;
|
||||||
|
|
||||||
|
if (aOrientation == hal::ScreenOrientation::Default) {
|
||||||
|
// Actually, current screen is single and tablet mode according to
|
||||||
|
// GetAutoRotationState. So get primary screen data for natural orientation.
|
||||||
|
RefPtr<widget::Screen> screen =
|
||||||
|
widget::ScreenManager::GetSingleton().GetPrimaryScreen();
|
||||||
|
hal::ScreenOrientation defaultOrientation =
|
||||||
|
screen->GetDefaultOrientationType();
|
||||||
|
if (defaultOrientation == hal::ScreenOrientation::LandscapePrimary) {
|
||||||
|
orientation = ORIENTATION_PREFERENCE_LANDSCAPE;
|
||||||
|
} else {
|
||||||
|
orientation = ORIENTATION_PREFERENCE_PORTRAIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (aOrientation & hal::ScreenOrientation::LandscapePrimary) {
|
||||||
|
orientation |= ORIENTATION_PREFERENCE_LANDSCAPE;
|
||||||
|
}
|
||||||
|
if (aOrientation & hal::ScreenOrientation::LandscapeSecondary) {
|
||||||
|
orientation |= ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
|
||||||
|
}
|
||||||
|
if (aOrientation & hal::ScreenOrientation::PortraitPrimary) {
|
||||||
|
orientation |= ORIENTATION_PREFERENCE_PORTRAIT;
|
||||||
|
}
|
||||||
|
if (aOrientation & hal::ScreenOrientation::PortraitSecondary) {
|
||||||
|
orientation |= ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sSetDisplayAutoRotationPreferences(orientation)) {
|
||||||
|
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnlockScreenOrientation() {
|
||||||
|
if (!sSetDisplayAutoRotationPreferences) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// This does nothing if the device doesn't support orientation lock
|
||||||
|
sSetDisplayAutoRotationPreferences(ORIENTATION_PREFERENCE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace hal_impl
|
||||||
|
} // namespace mozilla
|
|
@ -165,4 +165,18 @@ Screen::GetIsPseudoDisplay(bool* aIsPseudoDisplay) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hal::ScreenOrientation Screen::GetDefaultOrientationType() const {
|
||||||
|
if (mRect.Width() >= mRect.Height()) {
|
||||||
|
if (mOrientationAngle == 0 || mOrientationAngle == 180) {
|
||||||
|
return hal::ScreenOrientation::LandscapePrimary;
|
||||||
|
}
|
||||||
|
return hal::ScreenOrientation::PortraitPrimary;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mOrientationAngle == 0 || mOrientationAngle == 180) {
|
||||||
|
return hal::ScreenOrientation::PortraitPrimary;
|
||||||
|
}
|
||||||
|
return hal::ScreenOrientation::LandscapePrimary;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla::widget
|
} // namespace mozilla::widget
|
||||||
|
|
|
@ -43,6 +43,12 @@ class Screen final : public nsIScreen {
|
||||||
return mScreenOrientation;
|
return mScreenOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return default orientation type that angle is 0.
|
||||||
|
* This returns LandscapePrimary or PortraitPrimary.
|
||||||
|
*/
|
||||||
|
hal::ScreenOrientation GetDefaultOrientationType() const;
|
||||||
|
|
||||||
float GetDPI() const { return mDPI; }
|
float GetDPI() const { return mDPI; }
|
||||||
|
|
||||||
const LayoutDeviceIntRect& GetRect() const { return mRect; }
|
const LayoutDeviceIntRect& GetRect() const { return mRect; }
|
||||||
|
|
|
@ -1525,7 +1525,8 @@ WinUtils::GetPowerPlatformRole() {
|
||||||
return power_determine_platform_role(POWER_PLATFORM_ROLE_V2);
|
return power_determine_platform_role(POWER_PLATFORM_ROLE_V2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CallGetAutoRotationState(AR_STATE* aRotationState) {
|
// static
|
||||||
|
bool WinUtils::GetAutoRotationState(AR_STATE* aRotationState) {
|
||||||
typedef BOOL(WINAPI * GetAutoRotationStateFunc)(PAR_STATE pState);
|
typedef BOOL(WINAPI * GetAutoRotationStateFunc)(PAR_STATE pState);
|
||||||
static GetAutoRotationStateFunc get_auto_rotation_state_func =
|
static GetAutoRotationStateFunc get_auto_rotation_state_func =
|
||||||
reinterpret_cast<GetAutoRotationStateFunc>(::GetProcAddress(
|
reinterpret_cast<GetAutoRotationStateFunc>(::GetProcAddress(
|
||||||
|
@ -1564,7 +1565,7 @@ static bool IsTabletDevice() {
|
||||||
// a convertible or a detachable. See:
|
// a convertible or a detachable. See:
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn629263(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn629263(v=vs.85).aspx
|
||||||
AR_STATE rotation_state;
|
AR_STATE rotation_state;
|
||||||
if (CallGetAutoRotationState(&rotation_state) &&
|
if (WinUtils::GetAutoRotationState(&rotation_state) &&
|
||||||
(rotation_state & (AR_NOT_SUPPORTED | AR_LAPTOP | AR_NOSENSOR))) {
|
(rotation_state & (AR_NOT_SUPPORTED | AR_LAPTOP | AR_NOSENSOR))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,6 +608,8 @@ class WinUtils {
|
||||||
static nsresult RestoreHiDPIMode();
|
static nsresult RestoreHiDPIMode();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool GetAutoRotationState(AR_STATE* aRotationState);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static WhitelistVec BuildWhitelist();
|
static WhitelistVec BuildWhitelist();
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче