Skip to content

Commit e5b2ac9

Browse files
committed
🎨 同步 DeviceInfo.uwp
1 parent c0b4bcb commit e5b2ac9

File tree

1 file changed

+78
-5
lines changed

1 file changed

+78
-5
lines changed

src/BD.Common.Essentials.Maui.Runtime/Essentials/DeviceInfo/DeviceInfo.uwp.cs

+78-5
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,89 @@ public DeviceType DeviceType
109109
}
110110
}
111111

112-
static readonly int SM_CONVERTIBLESLATEMODE = 0x2003;
113-
static readonly int SM_TABLETPC = 0x56;
112+
/// <summary>
113+
/// Whether or not the device is in "tablet mode" or not. This
114+
/// has to be implemented by the device manufacturer.
115+
/// </summary>
116+
const int SM_CONVERTIBLESLATEMODE = 0x2003;
117+
118+
/// <summary>
119+
/// How many fingers (aka touches) are supported for touch control
120+
/// </summary>
121+
const int SM_MAXIMUMTOUCHES = 95;
122+
123+
/// <summary>
124+
/// Whether a physical keyboard is attached or not.
125+
/// Manufacturers have to remember to set this.
126+
/// Defaults to not-attached.
127+
/// </summary>
128+
const int SM_ISDOCKED = 0x2004;
129+
114130

115131
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
116132
static extern int GetSystemMetrics(int nIndex);
117133

134+
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
135+
static extern bool GetAutoRotationState(ref AutoRotationState pState);
136+
137+
[DllImport("Powrprof.dll", SetLastError = true, CharSet = CharSet.Auto)]
138+
static extern PowerPlatformRole PowerDeterminePlatformRoleEx(ulong Version);
139+
118140
static bool GetIsInTabletMode()
119141
{
120-
var supportsTablet = GetSystemMetrics(SM_TABLETPC) != 0;
121-
var inTabletMode = GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0;
122-
return inTabletMode && supportsTablet;
142+
// Adopt Chromium's methodology for determining tablet mode
143+
// https://source.chromium.org/chromium/chromium/src/+/main:base/win/win_util.cc;l=537;drc=ac83a5a2d3c04763d86ce16d92f3904cc9566d3a;bpv=0;bpt=1
144+
// Device does not have a touchscreen
145+
if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0)
146+
{
147+
return false;
148+
}
149+
150+
// If the device is docked, user is treating as a PC
151+
if (GetSystemMetrics(SM_ISDOCKED) != 0)
152+
{
153+
return false;
154+
}
155+
156+
// Fetch device rotation. Possible for this to fail.
157+
AutoRotationState rotationState = AutoRotationState.AR_ENABLED;
158+
bool success = GetAutoRotationState(ref rotationState);
159+
160+
// Fetch succeeded and device does not support rotation
161+
if (success && (rotationState & (AutoRotationState.AR_NOT_SUPPORTED | AutoRotationState.AR_LAPTOP | AutoRotationState.AR_NOSENSOR)) != 0)
162+
{
163+
return false;
164+
}
165+
166+
// Check if power management says we are mobile (laptop) or a tablet
167+
if ((PowerDeterminePlatformRoleEx(2) & (PowerPlatformRole.PlatformRoleMobile | PowerPlatformRole.PlatformRoleSlate)) != 0)
168+
{
169+
// Check if tablet mode is 0. 0 is default value.
170+
return GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0;
171+
}
172+
173+
return false;
123174
}
124175
}
176+
177+
/// <summary>
178+
/// Represents the OEM's preferred power management profile,
179+
/// Useful in-case OEM implements one but not the other
180+
/// </summary>
181+
enum PowerPlatformRole
182+
{
183+
PlatformRoleMobile = 2,
184+
PlatformRoleSlate = 8,
185+
}
186+
187+
/// <summary>
188+
/// Whether rotation is supported or not.
189+
/// Rotation is only supported if AR_ENABLED is true
190+
/// </summary>
191+
enum AutoRotationState
192+
{
193+
AR_ENABLED = 0x0,
194+
AR_NOT_SUPPORTED = 0x20,
195+
AR_LAPTOP = 0x80,
196+
AR_NOSENSOR = 0x10,
197+
}

0 commit comments

Comments
 (0)