зеркало из 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":
|
||||
REQUIRES_UNIFIED_BUILD = True
|
||||
UNIFIED_SOURCES += [
|
||||
"fallback/FallbackScreenConfiguration.cpp",
|
||||
"fallback/FallbackVibration.cpp",
|
||||
"windows/WindowsScreenConfiguration.cpp",
|
||||
"windows/WindowsSensor.cpp",
|
||||
]
|
||||
# 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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -43,6 +43,12 @@ class Screen final : public nsIScreen {
|
|||
return mScreenOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return default orientation type that angle is 0.
|
||||
* This returns LandscapePrimary or PortraitPrimary.
|
||||
*/
|
||||
hal::ScreenOrientation GetDefaultOrientationType() const;
|
||||
|
||||
float GetDPI() const { return mDPI; }
|
||||
|
||||
const LayoutDeviceIntRect& GetRect() const { return mRect; }
|
||||
|
|
|
@ -1525,7 +1525,8 @@ WinUtils::GetPowerPlatformRole() {
|
|||
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);
|
||||
static GetAutoRotationStateFunc get_auto_rotation_state_func =
|
||||
reinterpret_cast<GetAutoRotationStateFunc>(::GetProcAddress(
|
||||
|
@ -1564,7 +1565,7 @@ static bool IsTabletDevice() {
|
|||
// a convertible or a detachable. See:
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn629263(v=vs.85).aspx
|
||||
AR_STATE rotation_state;
|
||||
if (CallGetAutoRotationState(&rotation_state) &&
|
||||
if (WinUtils::GetAutoRotationState(&rotation_state) &&
|
||||
(rotation_state & (AR_NOT_SUPPORTED | AR_LAPTOP | AR_NOSENSOR))) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -608,6 +608,8 @@ class WinUtils {
|
|||
static nsresult RestoreHiDPIMode();
|
||||
#endif
|
||||
|
||||
static bool GetAutoRotationState(AR_STATE* aRotationState);
|
||||
|
||||
private:
|
||||
static WhitelistVec BuildWhitelist();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче