Backed out 2 changesets (bug 1819421) for causing linting failures at browser.js. CLOSED TREE
Backed out changeset b4f770bfe94c (bug 1819421) Backed out changeset b11774655311 (bug 1819421)
This commit is contained in:
@@ -4656,7 +4656,7 @@ function updateToggleControlLabel(control) {
|
|||||||
var TabletModeUpdater = {
|
var TabletModeUpdater = {
|
||||||
init() {
|
init() {
|
||||||
if (AppConstants.platform == "win") {
|
if (AppConstants.platform == "win") {
|
||||||
this.update(WindowsUIUtils.inWin10TabletMode);
|
this.update(WindowsUIUtils.inTabletMode);
|
||||||
Services.obs.addObserver(this, "tablet-mode-change");
|
Services.obs.addObserver(this, "tablet-mode-change");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4668,16 +4668,19 @@ var TabletModeUpdater = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
observe(subject, topic, data) {
|
observe(subject, topic, data) {
|
||||||
this.update(data == "win10-tablet-mode");
|
this.update(data == "tablet-mode");
|
||||||
},
|
},
|
||||||
|
|
||||||
update(isInTabletMode) {
|
update(isInTabletMode) {
|
||||||
// [tabletmode] is currently only set in Win10
|
let wasInTabletMode = document.documentElement.hasAttribute("tabletmode");
|
||||||
if (isInTabletMode) {
|
if (isInTabletMode) {
|
||||||
document.documentElement.setAttribute("tabletmode", "true");
|
document.documentElement.setAttribute("tabletmode", "true");
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.removeAttribute("tabletmode");
|
document.documentElement.removeAttribute("tabletmode");
|
||||||
}
|
}
|
||||||
|
if (wasInTabletMode != isInTabletMode) {
|
||||||
|
gUIDensity.update();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4692,30 +4695,23 @@ var gUIDensity = {
|
|||||||
MODE_TOUCH: 2,
|
MODE_TOUCH: 2,
|
||||||
uiDensityPref: "browser.uidensity",
|
uiDensityPref: "browser.uidensity",
|
||||||
autoTouchModePref: "browser.touchmode.auto",
|
autoTouchModePref: "browser.touchmode.auto",
|
||||||
knownPrefs: new Set(["browser.uidensity", "browser.touchmode.auto"]),
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.update();
|
this.update();
|
||||||
Services.obs.addObserver(this, "tablet-mode-change");
|
|
||||||
Services.prefs.addObserver(this.uiDensityPref, this);
|
Services.prefs.addObserver(this.uiDensityPref, this);
|
||||||
Services.prefs.addObserver(this.autoTouchModePref, this);
|
Services.prefs.addObserver(this.autoTouchModePref, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
uninit() {
|
uninit() {
|
||||||
Services.obs.removeObserver(this, "tablet-mode-change");
|
|
||||||
Services.prefs.removeObserver(this.uiDensityPref, this);
|
Services.prefs.removeObserver(this.uiDensityPref, this);
|
||||||
Services.prefs.removeObserver(this.autoTouchModePref, this);
|
Services.prefs.removeObserver(this.autoTouchModePref, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
observe(aSubject, aTopic, aPrefName) {
|
observe(aSubject, aTopic, aPrefName) {
|
||||||
const ok = (() => {
|
if (
|
||||||
if (aTopic == "tablet-mode-change") return true;
|
aTopic != "nsPref:changed" ||
|
||||||
if (aTopic == "nsPref:changed" && this.knownPrefs.has(aPrefName)) {
|
(aPrefName != this.uiDensityPref && aPrefName != this.autoTouchModePref)
|
||||||
return true;
|
) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
})();
|
|
||||||
if (!ok) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4723,13 +4719,10 @@ var gUIDensity = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getCurrentDensity() {
|
getCurrentDensity() {
|
||||||
// Automatically override the uidensity to touch in Windows tablet mode
|
// Automatically override the uidensity to touch in Windows tablet mode.
|
||||||
// (either Win10 or Win11).
|
|
||||||
const inTablet =
|
|
||||||
WindowsUIUtils.inWin10TabletMode || WindowsUIUtils.inWin11TabletMode;
|
|
||||||
if (
|
if (
|
||||||
AppConstants.platform == "win" &&
|
AppConstants.platform == "win" &&
|
||||||
inTablet &&
|
WindowsUIUtils.inTabletMode &&
|
||||||
Services.prefs.getBoolPref(this.autoTouchModePref)
|
Services.prefs.getBoolPref(this.autoTouchModePref)
|
||||||
) {
|
) {
|
||||||
return { mode: this.MODE_TOUCH, overridden: true };
|
return { mode: this.MODE_TOUCH, overridden: true };
|
||||||
|
|||||||
@@ -1583,7 +1583,7 @@ nsDefaultCommandLineHandler.prototype = {
|
|||||||
if (
|
if (
|
||||||
AppConstants.platform == "win" &&
|
AppConstants.platform == "win" &&
|
||||||
cmdLine.state != Ci.nsICommandLine.STATE_INITIAL_LAUNCH &&
|
cmdLine.state != Ci.nsICommandLine.STATE_INITIAL_LAUNCH &&
|
||||||
lazy.WindowsUIUtils.inWin10TabletMode
|
lazy.WindowsUIUtils.inTabletMode
|
||||||
) {
|
) {
|
||||||
// In windows 10 tablet mode, do not create a new window, but reuse the existing one.
|
// In windows 10 tablet mode, do not create a new window, but reuse the existing one.
|
||||||
let win = lazy.BrowserWindowTracker.getTopWindow();
|
let win = lazy.BrowserWindowTracker.getTopWindow();
|
||||||
|
|||||||
@@ -17609,17 +17609,6 @@
|
|||||||
value: true
|
value: true
|
||||||
mirror: always
|
mirror: always
|
||||||
|
|
||||||
# Whether this device is capable of entering tablet mode. (Win11+ only.)
|
|
||||||
#
|
|
||||||
# Valid values:
|
|
||||||
# * -1: assume this device is tablet-mode-incapable
|
|
||||||
# * 0: rely on heuristics
|
|
||||||
# * 1: assume this device is tablet-mode-capable
|
|
||||||
- name: widget.windows.tablet_detection_override
|
|
||||||
type: RelaxedAtomicInt32
|
|
||||||
value: 0
|
|
||||||
mirror: always
|
|
||||||
|
|
||||||
# Whether to give explorer.exe a delated nudge to recalculate the fullscreenness
|
# Whether to give explorer.exe a delated nudge to recalculate the fullscreenness
|
||||||
# of a window after maximizing it.
|
# of a window after maximizing it.
|
||||||
- name: widget.windows.fullscreen_remind_taskbar
|
- name: widget.windows.fullscreen_remind_taskbar
|
||||||
|
|||||||
@@ -22,24 +22,10 @@ interface nsIWindowsUIUtils : nsISupports
|
|||||||
void setWindowIconNoData(in mozIDOMWindowProxy aWindow);
|
void setWindowIconNoData(in mozIDOMWindowProxy aWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the OS is currently in Win10's Tablet Mode. Always false on
|
* Whether the OS is currently in tablet mode. Always false on
|
||||||
* versions of Windows other than Win10.
|
* non-Windows and on versions of Windows before win10
|
||||||
*
|
|
||||||
* (Win10 tablet mode is sufficiently different from Win11 tablet mode that
|
|
||||||
* there is no single getter to retrieve whether we're in a generic "tablet
|
|
||||||
* mode".)
|
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean inWin10TabletMode;
|
readonly attribute boolean inTabletMode;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the OS is currently in Windows 11's tablet mode. Always false on
|
|
||||||
* versions of Windows prior to Win11.
|
|
||||||
*
|
|
||||||
* (Win11 tablet mode is sufficiently different from Win10 tablet mode that
|
|
||||||
* there is no single getter to retrieve whether we're in a generic "tablet
|
|
||||||
* mode".)
|
|
||||||
*/
|
|
||||||
readonly attribute boolean inWin11TabletMode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share URL
|
* Share URL
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
#include "mozilla/WindowsVersion.h"
|
|
||||||
#include "nsLookAndFeel.h"
|
#include "nsLookAndFeel.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
#include "nsWindowDbg.h"
|
#include "nsWindowDbg.h"
|
||||||
@@ -213,32 +212,13 @@ static void OnSettingsChange(WPARAM wParam, LPARAM lParam) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserInteractionMode, ConvertibleSlateMode, and SystemDockMode may cause
|
// UserInteractionMode, ConvertibleSlateMode, SystemDockMode may cause
|
||||||
// @media(pointer) queries to change, which layout needs to know about.
|
// @media(pointer) queries to change, which layout needs to know about
|
||||||
//
|
if (lParamString == u"UserInteractionMode"_ns ||
|
||||||
// The former two of those also imply that the current tablet-mode state needs
|
lParamString == u"ConvertibleSlateMode"_ns ||
|
||||||
// to be updated.
|
lParamString == u"SystemDockMode"_ns) {
|
||||||
|
|
||||||
if (lParamString == u"UserInteractionMode"_ns) {
|
|
||||||
// Documentation implies, and testing shows, that this is seen on Win10
|
|
||||||
// only.
|
|
||||||
Unused << NS_WARN_IF(mozilla::IsWin11OrLater());
|
|
||||||
WindowsUIUtils::UpdateInWin10TabletMode();
|
|
||||||
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
|
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
|
||||||
return;
|
WindowsUIUtils::UpdateInTabletMode();
|
||||||
}
|
|
||||||
|
|
||||||
if (lParamString == u"ConvertibleSlateMode"_ns) {
|
|
||||||
// Documentation implies, and testing shows, that this is not seen on Win10.
|
|
||||||
Unused << NS_WARN_IF(!mozilla::IsWin11OrLater());
|
|
||||||
WindowsUIUtils::UpdateInWin11TabletMode();
|
|
||||||
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lParamString == u"SystemDockMode"_ns) {
|
|
||||||
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -727,7 +727,7 @@ bool IMEHandler::IsOnScreenKeyboardSupported() {
|
|||||||
if (!IsWin11OrLater()) {
|
if (!IsWin11OrLater()) {
|
||||||
// On Windows 10 we require tablet mode, unless the user has set the
|
// On Windows 10 we require tablet mode, unless the user has set the
|
||||||
// relevant setting to enable the on-screen keyboard in desktop mode.
|
// relevant setting to enable the on-screen keyboard in desktop mode.
|
||||||
if (!IsInWin10TabletMode() && !AutoInvokeOnScreenKeyboardInDesktopMode()) {
|
if (!IsInTabletMode() && !AutoInvokeOnScreenKeyboardInDesktopMode()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -918,8 +918,8 @@ bool IMEHandler::IsKeyboardPresentOnSlate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool IMEHandler::IsInWin10TabletMode() {
|
bool IMEHandler::IsInTabletMode() {
|
||||||
bool isInTabletMode = WindowsUIUtils::GetInWin10TabletMode();
|
bool isInTabletMode = WindowsUIUtils::GetInTabletMode();
|
||||||
if (isInTabletMode) {
|
if (isInTabletMode) {
|
||||||
Preferences::SetString(kOskDebugReason, L"IITM: GetInTabletMode=true.");
|
Preferences::SetString(kOskDebugReason, L"IITM: GetInTabletMode=true.");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ class IMEHandler final {
|
|||||||
const std::wstring& aNeedle);
|
const std::wstring& aNeedle);
|
||||||
static bool NeedOnScreenKeyboard();
|
static bool NeedOnScreenKeyboard();
|
||||||
static bool IsKeyboardPresentOnSlate();
|
static bool IsKeyboardPresentOnSlate();
|
||||||
static bool IsInWin10TabletMode();
|
static bool IsInTabletMode();
|
||||||
static bool AutoInvokeOnScreenKeyboardInDesktopMode();
|
static bool AutoInvokeOnScreenKeyboardInDesktopMode();
|
||||||
static bool NeedsToAssociateIMC();
|
static bool NeedsToAssociateIMC();
|
||||||
static bool NeedsSearchInputScope();
|
static bool NeedsSearchInputScope();
|
||||||
|
|||||||
@@ -1583,8 +1583,9 @@ static bool IsTabletDevice() {
|
|||||||
// Guarantees that:
|
// Guarantees that:
|
||||||
// - The device has a touch screen.
|
// - The device has a touch screen.
|
||||||
// - It is used as a tablet which means that it has no keyboard connected.
|
// - It is used as a tablet which means that it has no keyboard connected.
|
||||||
|
// On Windows 10 it means that it is verifying with ConvertibleSlateMode.
|
||||||
|
|
||||||
if (WindowsUIUtils::GetInWin10TabletMode()) {
|
if (WindowsUIUtils::GetInTabletMode()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winreg.h>
|
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
#include <powerbase.h>
|
|
||||||
#include <cfgmgr32.h>
|
|
||||||
|
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
@@ -32,11 +29,6 @@
|
|||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsWindowGfx.h"
|
#include "nsWindowGfx.h"
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
#include "nsWindowsHelpers.h"
|
|
||||||
#include "WinRegistry.h"
|
|
||||||
#include "WinUtils.h"
|
|
||||||
|
|
||||||
mozilla::LazyLogModule gTabletModeLog("TabletMode");
|
|
||||||
|
|
||||||
/* mingw currently doesn't support windows.ui.viewmanagement.h, so we disable it
|
/* mingw currently doesn't support windows.ui.viewmanagement.h, so we disable it
|
||||||
* until it's fixed. */
|
* until it's fixed. */
|
||||||
@@ -196,10 +188,8 @@ IUISettings5 : public IInspectable {
|
|||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
// Since Win10 and Win11 tablet modes can't both be simultaneously active, we
|
|
||||||
// only need one backing variable for the both of them.
|
|
||||||
enum class TabletModeState : uint8_t { Unknown, Off, On };
|
enum class TabletModeState : uint8_t { Unknown, Off, On };
|
||||||
static TabletModeState sInTabletModeState = TabletModeState::Unknown;
|
static TabletModeState sInTabletModeState;
|
||||||
|
|
||||||
WindowsUIUtils::WindowsUIUtils() = default;
|
WindowsUIUtils::WindowsUIUtils() = default;
|
||||||
WindowsUIUtils::~WindowsUIUtils() = default;
|
WindowsUIUtils::~WindowsUIUtils() = default;
|
||||||
@@ -292,37 +282,17 @@ WindowsUIUtils::SetWindowIconNoData(mozIDOMWindowProxy* aWindow) {
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsUIUtils::GetInWin10TabletMode() {
|
bool WindowsUIUtils::GetInTabletMode() {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
||||||
if (IsWin11OrLater()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (sInTabletModeState == TabletModeState::Unknown) {
|
if (sInTabletModeState == TabletModeState::Unknown) {
|
||||||
UpdateInWin10TabletMode();
|
UpdateInTabletMode();
|
||||||
}
|
|
||||||
return sInTabletModeState == TabletModeState::On;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowsUIUtils::GetInWin11TabletMode() {
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
|
||||||
if (!IsWin11OrLater()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (sInTabletModeState == TabletModeState::Unknown) {
|
|
||||||
UpdateInWin11TabletMode();
|
|
||||||
}
|
}
|
||||||
return sInTabletModeState == TabletModeState::On;
|
return sInTabletModeState == TabletModeState::On;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WindowsUIUtils::GetInWin10TabletMode(bool* aResult) {
|
WindowsUIUtils::GetInTabletMode(bool* aResult) {
|
||||||
*aResult = GetInWin10TabletMode();
|
*aResult = GetInTabletMode();
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
WindowsUIUtils::GetInWin11TabletMode(bool* aResult) {
|
|
||||||
*aResult = GetInWin11TabletMode();
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,18 +543,7 @@ bool WindowsUIUtils::ComputeTransparencyEffects() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsUIUtils::UpdateInWin10TabletMode() {
|
void WindowsUIUtils::UpdateInTabletMode() {
|
||||||
if (IsWin11OrLater()) {
|
|
||||||
// (In theory we should never get here under Win11; but it's conceivable
|
|
||||||
// that there are third-party applications that try to "assist" legacy Win10
|
|
||||||
// apps by synthesizing Win10-style tablet-mode notifications.)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The getter below relies on querying a HWND which is affine to the main
|
|
||||||
// thread; its operation is not known to be thread-safe, let alone lock-free.
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIWindowMediator> winMediator(
|
nsCOMPtr<nsIWindowMediator> winMediator(
|
||||||
@@ -633,219 +592,17 @@ void WindowsUIUtils::UpdateInWin10TabletMode() {
|
|||||||
TabletModeState oldTabletModeState = sInTabletModeState;
|
TabletModeState oldTabletModeState = sInTabletModeState;
|
||||||
sInTabletModeState = mode == UserInteractionMode_Touch ? TabletModeState::On
|
sInTabletModeState = mode == UserInteractionMode_Touch ? TabletModeState::On
|
||||||
: TabletModeState::Off;
|
: TabletModeState::Off;
|
||||||
|
|
||||||
if (sInTabletModeState != oldTabletModeState) {
|
if (sInTabletModeState != oldTabletModeState) {
|
||||||
nsCOMPtr<nsIObserverService> observerService =
|
nsCOMPtr<nsIObserverService> observerService =
|
||||||
mozilla::services::GetObserverService();
|
mozilla::services::GetObserverService();
|
||||||
observerService->NotifyObservers(nullptr, "tablet-mode-change",
|
observerService->NotifyObservers(nullptr, "tablet-mode-change",
|
||||||
sInTabletModeState == TabletModeState::On
|
sInTabletModeState == TabletModeState::On
|
||||||
? u"win10-tablet-mode"
|
? u"tablet-mode"
|
||||||
: u"normal-mode");
|
: u"normal-mode");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache: whether this device is believed to be capable of entering tablet mode.
|
|
||||||
//
|
|
||||||
// Meaningful only if `IsWin11OrLater()`.
|
|
||||||
static Maybe<bool> sIsTabletCapable = Nothing();
|
|
||||||
|
|
||||||
// The UUID of a GPIO pin which indicates whether or not a convertible device is
|
|
||||||
// currently in tablet mode. (We copy `DEFINE_GUID`'s implementation here since
|
|
||||||
// we can't control `INITGUID`, which the canonical one is conditional on.)
|
|
||||||
//
|
|
||||||
// https://learn.microsoft.com/en-us/windows-hardware/drivers/gpiobtn/laptop-slate-mode-toggling-between-states
|
|
||||||
#define MOZ_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
|
||||||
EXTERN_C const GUID DECLSPEC_SELECTANY name = { \
|
|
||||||
l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}
|
|
||||||
/* 317fc439-3f77-41c8-b09e-08ad63272aa3 */ MOZ_DEFINE_GUID(
|
|
||||||
MOZ_GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE, 0x317fc439, 0x3f77, 0x41c8,
|
|
||||||
0xb0, 0x9e, 0x08, 0xad, 0x63, 0x27, 0x2a, 0xa3);
|
|
||||||
|
|
||||||
void WindowsUIUtils::UpdateInWin11TabletMode() {
|
|
||||||
// The OS-level getter itself is threadsafe, but we retain the main-thread
|
|
||||||
// restriction to parallel the Win10 getter's (presumed) restriction.
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
if (!IsWin11OrLater()) {
|
|
||||||
// We should ordinarily never reach this point in Win10 -- but there may
|
|
||||||
// well be some third-party application out there that synthesizes Win11-
|
|
||||||
// style tablet-mode notifications.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** *** *** WARNING: RELIANCE ON UNDOCUMENTED BEHAVIOR *** *** ***
|
|
||||||
//
|
|
||||||
// Windows 10's `UserInteractionMode` API is no longer useful under Windows
|
|
||||||
// 11: it always returns `UserInteractionMode_Mouse`.
|
|
||||||
//
|
|
||||||
// The documented API to query whether we're in tablet mode (alt.: "slate
|
|
||||||
// mode") under Windows 11 is `::GetSystemMetrics(SM_CONVERTIBLESLATEMODE)`.
|
|
||||||
// This returns 0 if we are in slate mode and 1 otherwise... except on devices
|
|
||||||
// where tablet mode is unavailable (such as desktops), in which case it
|
|
||||||
// returns 0 unconditionally.
|
|
||||||
//
|
|
||||||
// Unfortunately, there is no documented API to determine whether
|
|
||||||
// `SM_CONVERTIBLESLATEMODE` is `0` because the device is currently in slate
|
|
||||||
// mode or because the device can never be in slate mode.
|
|
||||||
//
|
|
||||||
// As such, we follow Chromium's lead here, and attempt to determine
|
|
||||||
// heuristically whether that API is going to return anything sensible.
|
|
||||||
// (Indeed, the heuristic below is in large part taken from Chromium.)
|
|
||||||
|
|
||||||
if (sIsTabletCapable.isNothing()) {
|
|
||||||
bool const heuristic = ([]() -> bool {
|
|
||||||
// If the user has set the relevant pref to override our tablet-detection
|
|
||||||
// heuristics, go with that.
|
|
||||||
switch (StaticPrefs::widget_windows_tablet_detection_override()) {
|
|
||||||
case -1:
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: override detected (-1)"));
|
|
||||||
return false;
|
|
||||||
case 1:
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: override detected (+1)"));
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If ::GSM(SM_CONVERTIBLESLATEMODE) is _currently_ nonzero, we must be on
|
|
||||||
// a system that does somnething with SM_CONVERTIBLESLATEMODE, so we can
|
|
||||||
// trust it.
|
|
||||||
if (::GetSystemMetrics(SM_CONVERTIBLESLATEMODE) != 0) {
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: SM_CONVERTIBLESLATEMODE != 0"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the device does not support touch it can't possibly be a tablet.
|
|
||||||
if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) {
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: SM_MAXIMUMTOUCHES != 0"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if a particular registry key [1] exists. If so, this is
|
|
||||||
// probably a tablet-capable device.
|
|
||||||
//
|
|
||||||
// Comments in Chromium [2] claim that not all devices actually set this
|
|
||||||
// registry key, but do not actually state that there are _convertible_
|
|
||||||
// devices which do not. No exceptions are presently known.
|
|
||||||
//
|
|
||||||
// [1] https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-gpiobuttons-convertibleslatemode
|
|
||||||
// [2] https://source.chromium.org/chromium/chromium/src/+/main:base/win/win_util.cc;l=240;drc=5a02fc6cdee77d0a39e9c43a4c2a29bbccc88852
|
|
||||||
namespace Reg = mozilla::widget::WinRegistry;
|
|
||||||
Reg::Key key(HKEY_LOCAL_MACHINE,
|
|
||||||
uR"(System\CurrentControlSet\Control\PriorityControl)"_ns,
|
|
||||||
Reg::KeyMode::QueryValue);
|
|
||||||
if (key && key.GetValueType(u"ConvertibleSlateMode"_ns) !=
|
|
||||||
Reg::ValueType::None) {
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: 'ConvertibleSlateMode' found"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the device has this GUID mapped to a GPIO pin, it's almost certainly
|
|
||||||
// tablet-capable. (It's not certain whether the converse is true.)
|
|
||||||
//
|
|
||||||
// https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/continuum#designing-your-device-for-tablet-mode
|
|
||||||
bool const hasTabletGpioPin = [&]() {
|
|
||||||
ULONG size = 0;
|
|
||||||
GUID guid{MOZ_GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE};
|
|
||||||
|
|
||||||
CONFIGRET const err = ::CM_Get_Device_Interface_List_SizeW(
|
|
||||||
&size, &guid, nullptr, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
|
|
||||||
|
|
||||||
// (The next step at this point would usually be to call the function
|
|
||||||
// "::CM_Get_Device_Interface_ListW()" -- but we don't care where the
|
|
||||||
// associated device interface is actually mapped to; we only care
|
|
||||||
// whether it's mapped at all.
|
|
||||||
//
|
|
||||||
// For our purposes, a zero-length null-terminated string doesn't count
|
|
||||||
// as "present".)
|
|
||||||
return err == CR_SUCCESS && size > 1;
|
|
||||||
}();
|
|
||||||
if (hasTabletGpioPin) {
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: relevant GPIO interface found"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the device has no rotation sensor, it's _probably_ not a convertible
|
|
||||||
// device. (There are exceptions! See bug 1918292.)
|
|
||||||
AR_STATE rotation_state;
|
|
||||||
if (HRESULT hr = ::GetAutoRotationState(&rotation_state); !FAILED(hr)) {
|
|
||||||
if ((rotation_state & (AR_NOT_SUPPORTED | AR_LAPTOP | AR_NOSENSOR)) !=
|
|
||||||
0) {
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info, ("TCH: no rotation sensor"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the device returns `PlatformRoleSlate` for its POWER_PLATFORM_ROLE,
|
|
||||||
// it's probably tablet capable.
|
|
||||||
//
|
|
||||||
// The converse is known to be false; a Dell Inspiron 14 7445 2-in-1
|
|
||||||
// returns `PlatformRoleMobile`.
|
|
||||||
//
|
|
||||||
// (Chromium checks for PlatformRoleMobile as well, but (e.g.) a Dell XPS
|
|
||||||
// 15 9500 returns `PlatformRoleMobile` despite not being tablet-capable.)
|
|
||||||
POWER_PLATFORM_ROLE const role =
|
|
||||||
mozilla::widget::WinUtils::GetPowerPlatformRole();
|
|
||||||
if (role == PlatformRoleSlate) {
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: role == PlatformRoleSlate"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Without some specific indicator of tablet-capability, assume that we're
|
|
||||||
// tablet-incapable.
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("TCH: no indication; falling through"));
|
|
||||||
return false;
|
|
||||||
})();
|
|
||||||
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Info,
|
|
||||||
("tablet-capability heuristic: %s", heuristic ? "true" : "false"));
|
|
||||||
|
|
||||||
sIsTabletCapable = Some(heuristic);
|
|
||||||
// If we appear not to be tablet-capable, don't bother doing the check.
|
|
||||||
// (We also don't need to send a signal.)
|
|
||||||
if (!heuristic) {
|
|
||||||
sInTabletModeState = TabletModeState::Off;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (sIsTabletCapable == Some(false)) {
|
|
||||||
// We've been in here before, and the heuristic came back false... but
|
|
||||||
// somehow, we've just gotten an update for the convertible-slate-mode
|
|
||||||
// state.
|
|
||||||
//
|
|
||||||
// Clearly the heuristic was wrong!
|
|
||||||
//
|
|
||||||
// TODO(rkraesig): should we add telemetry to see how often this gets hit?
|
|
||||||
MOZ_LOG(gTabletModeLog, LogLevel::Warning,
|
|
||||||
("recv'd update signal after false heuristic run; reversing"));
|
|
||||||
sIsTabletCapable = Some(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// at this point, we must be tablet-capable
|
|
||||||
MOZ_ASSERT(sIsTabletCapable == Some(true));
|
|
||||||
|
|
||||||
TabletModeState const oldState = sInTabletModeState;
|
|
||||||
bool const isTableting =
|
|
||||||
::GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0 /* [sic!] */;
|
|
||||||
sInTabletModeState = isTableting ? TabletModeState::On : TabletModeState::Off;
|
|
||||||
if (oldState != sInTabletModeState) {
|
|
||||||
nsCOMPtr<nsIObserverService> observerService =
|
|
||||||
mozilla::services::GetObserverService();
|
|
||||||
observerService->NotifyObservers(nullptr, "tablet-mode-change",
|
|
||||||
sInTabletModeState == TabletModeState::On
|
|
||||||
? u"win11-tablet-mode"
|
|
||||||
: u"normal-mode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
struct HStringDeleter {
|
struct HStringDeleter {
|
||||||
using pointer = HSTRING;
|
using pointer = HSTRING;
|
||||||
|
|||||||
@@ -29,21 +29,8 @@ class WindowsUIUtils final : public nsIWindowsUIUtils {
|
|||||||
static RefPtr<SharePromise> Share(nsAutoString aTitle, nsAutoString aText,
|
static RefPtr<SharePromise> Share(nsAutoString aTitle, nsAutoString aText,
|
||||||
nsAutoString aUrl);
|
nsAutoString aUrl);
|
||||||
|
|
||||||
static void UpdateInWin10TabletMode();
|
static void UpdateInTabletMode();
|
||||||
static void UpdateInWin11TabletMode();
|
static bool GetInTabletMode();
|
||||||
|
|
||||||
// Check whether we're in Win10 tablet mode.
|
|
||||||
//
|
|
||||||
// (Win10 tablet mode is considered sufficiently different from Win11 tablet
|
|
||||||
// mode that there is no single getter to retrieve whether we're in a generic
|
|
||||||
// "tablet mode".)
|
|
||||||
static bool GetInWin10TabletMode();
|
|
||||||
// Check whether we're in Win11 tablet mode.
|
|
||||||
//
|
|
||||||
// (Win11 tablet mode is considered sufficiently different from Win10 tablet
|
|
||||||
// mode that there is no single getter to retrieve whether we're in a generic
|
|
||||||
// "tablet mode".)
|
|
||||||
static bool GetInWin11TabletMode();
|
|
||||||
|
|
||||||
// Gets the system accent color, or one of the darker / lighter variants
|
// Gets the system accent color, or one of the darker / lighter variants
|
||||||
// (darker = -1/2/3, lighter=+1/2/3, values outside of that range are
|
// (darker = -1/2/3, lighter=+1/2/3, values outside of that range are
|
||||||
|
|||||||
@@ -73,7 +73,6 @@
|
|||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
# include "mozilla/PreXULSkeletonUI.h"
|
# include "mozilla/PreXULSkeletonUI.h"
|
||||||
# include "mozilla/WindowsVersion.h"
|
|
||||||
# include "nsIWindowsUIUtils.h"
|
# include "nsIWindowsUIUtils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1812,17 +1811,14 @@ nsresult AppWindow::MaybeSaveEarlyWindowPersistentValues(
|
|||||||
|
|
||||||
settings.rtlEnabled = intl::LocaleService::GetInstance()->IsAppLocaleRTL();
|
settings.rtlEnabled = intl::LocaleService::GetInstance()->IsAppLocaleRTL();
|
||||||
|
|
||||||
bool const autoTouchModePref =
|
bool isInTabletMode = false;
|
||||||
|
bool autoTouchModePref =
|
||||||
Preferences::GetBool("browser.touchmode.auto", false);
|
Preferences::GetBool("browser.touchmode.auto", false);
|
||||||
if (autoTouchModePref) {
|
if (autoTouchModePref) {
|
||||||
bool isInTabletMode = false;
|
|
||||||
nsCOMPtr<nsIWindowsUIUtils> uiUtils(
|
nsCOMPtr<nsIWindowsUIUtils> uiUtils(
|
||||||
do_GetService("@mozilla.org/windows-ui-utils;1"));
|
do_GetService("@mozilla.org/windows-ui-utils;1"));
|
||||||
if (!NS_WARN_IF(!uiUtils)) {
|
if (!NS_WARN_IF(!uiUtils)) {
|
||||||
if (IsWin11OrLater()) {
|
uiUtils->GetInTabletMode(&isInTabletMode);
|
||||||
uiUtils->GetInWin11TabletMode(&isInTabletMode);
|
|
||||||
} else {
|
|
||||||
uiUtils->GetInWin10TabletMode(&isInTabletMode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1845,7 +1841,6 @@ nsresult AppWindow::MaybeSaveEarlyWindowPersistentValues(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
settings.verticalTabs = Preferences::GetBool("sidebar.verticalTabs", false);
|
settings.verticalTabs = Preferences::GetBool("sidebar.verticalTabs", false);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user