Repository: nvaccess/nvda

Issue:
winVersion: build 22000 is not recognized as Windows 11
Hi,

First concrete issue under #12585:

### Background:
Since December 2019, Windows Insiders were testing builds not tied to a specific Windows release, eventually going through Manganese (mn), Iron (fe) and Cobalt (co) development cycles. It wasn't until June 24, 2021 that the builds Insiders were testing were revealed to be part of Windows 11 development cycle, with the first Insider Preview released on June 28th (build: 22000). Still, NVDA identifies build 22000 as Windows 10 due to the assumption that Windows NT 10.0 will always be called Windows 10 (see the discussion in #12544 for details).

### Steps to reproduce:

1. Install Windows 11 Insider Preview build 22000.51 or later (one must be a dev channel Insider).
2. With latest alpha (23321,d304ed0c) installed, open Python Console and do:

import winVersion
winVersion.getWinVer()

### Actual behavior:
NVDA says "Windows 10 21H2".

### Expected behavior:
NVDA says "Windows 11 21H2".

### System configuration
#### NVDA installed/portable/running from source:
Installed

#### NVDA version:
alpha-23321,d304ed0c

#### Windows version:
Windows 11 preview (10.0.22000.65)

#### Name and version of other software in use when reproducing the issue:
None

#### Other information about your system:
An Insider Preview virtual machine

### Other questions
#### Does the issue still occur after restarting your computer?
Yes

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Prior to 2021.1: winVersion.getWinVer not implemented
2021.1: NvDA says "Windows 10 prerelease".

#### If add-ons are disabled, is your problem still occurring?
Yes

#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
Not applicable

### Proposed solution:
In winVersion.getWinVer() function, say "Windows 11" if winVer (sys.getwindowsversion() tuple).build is 22000 or later, otherwise "Windows 10", no need to worry about doing this from winVersion.WinVersion class. Another option is defining an official WIN11/WIN11_21H2 constant in winVersion module and check against WIN11.build. Of these, I think the second solution is easier to read and understand.

Thanks.


Discussion:

Resolving patch:
diff --git a/source/winVersion.py b/source/winVersion.py
--- a/source/winVersion.py
+++ b/source/winVersion.py
@@ -31,7 +31,8 @@
 	18363: "Windows 10 1909",
 	19041: "Windows 10 2004",
 	19042: "Windows 10 20H2",
-	19043: "Windows 10 21H1"
+	19043: "Windows 10 21H1",
+	22000: "Windows 11 21H2",
 }
 
 
@@ -150,6 +151,7 @@ def __ge__(self, other):
 WIN10_2004 = WinVersion(major=10, minor=0, build=19041)
 WIN10_20H2 = WinVersion(major=10, minor=0, build=19042)
 WIN10_21H1 = WinVersion(major=10, minor=0, build=19043)
+WIN11 = WIN11_21H2 = WinVersion(major=10, minor=0, build=22000)
 
 
 def getWinVer():
@@ -157,8 +159,17 @@ def getWinVer():
 	"""
 	winVer = sys.getwindowsversion()
 	# #12509: on Windows 10, fetch whatever Windows Registry says for the current build.
+	# #12626: note that not all Windows 10 releases are labeled "Windows 10"
+	# (build 22000 is Windows 11 despite major.minor being 10.0).
 	try:
-		releaseName = f"Windows 10 {_getRunningVersionNameFromWinReg()}"
+		if WinVersion(
+			major=winVer.major,
+			minor=winVer.minor,
+			build=winVer.build
+		) >= WIN11:
+			releaseName = f"Windows 11 {_getRunningVersionNameFromWinReg()}"
+		else:
+			releaseName = f"Windows 10 {_getRunningVersionNameFromWinReg()}"
 	except RuntimeError:
 		releaseName = None
 	return WinVersion(


Test patch: