patch 9.2.0171: MS-Windows: version detection is deprecated

Problem:  MS-Windows: GetVersionEx() is deprecated since Windows 8.
          Version checks for specific features (like dark mode or title
          bar colors) are duplicated across files using multiple boolean flags.
Solution: Use RtlGetVersion() to centralize detection in a single
          win_version variable. Use the MAKE_VER() macro to check
          against major, minor, and build numbers. Update titlebar
          colors and dark theme to use proper version thresholds
          (Mao-Yining).

closes: #19673

Signed-off-by: Mao-Yining <mao.yining@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Mao-Yining
2026-03-15 09:49:33 +00:00
committed by Christian Brabandt
parent 98fe2b6c71
commit ca62f84503
5 changed files with 63 additions and 89 deletions
+10 -14
View File
@@ -1572,7 +1572,7 @@ dyn_dwm_load(void)
}
}
extern BOOL win11_or_later; // this is in os_win32.c
extern DWORD win_version; // this is in os_mswin.c
/*
* Set TitleBar's color. Handle hl-TitleBar and hl-TitleBarNC.
@@ -1584,11 +1584,12 @@ extern BOOL win11_or_later; // this is in os_win32.c
void
gui_mch_set_titlebar_colors(void)
{
if (pDwmSetWindowAttribute == NULL || !win11_or_later)
#define DWMWA_COLOR_DEFAULT 0xFFFFFFFF
if (pDwmSetWindowAttribute == NULL || win_version < MAKE_VER(10, 0, 22000))
return;
guicolor_T captionColor = 0xFFFFFFFF;
guicolor_T textColor = 0xFFFFFFFF;
guicolor_T captionColor = DWMWA_COLOR_DEFAULT;
guicolor_T textColor = DWMWA_COLOR_DEFAULT;
if (vim_strchr(p_go, GO_TITLEBAR) != NULL)
{
@@ -1604,9 +1605,9 @@ gui_mch_set_titlebar_colors(void)
}
if (captionColor == INVALCOLOR)
captionColor = 0xFFFFFFFF;
captionColor = DWMWA_COLOR_DEFAULT;
if (textColor == INVALCOLOR)
textColor = 0xFFFFFFFF;
textColor = DWMWA_COLOR_DEFAULT;
}
pDwmSetWindowAttribute(s_hwnd, DWMWA_CAPTION_COLOR,
@@ -3131,22 +3132,17 @@ gui_mch_set_curtab(int nr)
#endif
#ifdef FEAT_GUI_DARKTHEME
extern BOOL win10_22H2_or_later; // this is in os_win32.c
void
gui_mch_set_dark_theme(int dark)
{
if (!win10_22H2_or_later)
return;
if (pDwmSetWindowAttribute != NULL)
if (pDwmSetWindowAttribute != NULL && win_version >= MAKE_VER(10, 0, 18985))
pDwmSetWindowAttribute(s_hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark,
sizeof(dark));
if (pSetPreferredAppMode != NULL)
if (pSetPreferredAppMode != NULL && win_version >= MAKE_VER(10, 0, 18362))
pSetPreferredAppMode(dark);
if (pFlushMenuThemes != NULL)
if (pFlushMenuThemes != NULL && win_version >= MAKE_VER(10, 0, 18362))
pFlushMenuThemes();
}
+30 -1
View File
@@ -16,7 +16,6 @@
#include "vim.h"
#include <sys/types.h>
#include <signal.h>
#include <limits.h>
#include <process.h>
@@ -105,6 +104,34 @@ mch_exit_g(int r)
#endif // FEAT_GUI_MSWIN
/*
* Get version number including build number
*/
typedef BOOL (WINAPI *PfnRtlGetVersion)(LPOSVERSIONINFOW);
DWORD win_version;
static void
win_version_init(void)
{
OSVERSIONINFOW osver;
HMODULE hNtdll;
PfnRtlGetVersion pRtlGetVersion;
hNtdll = GetModuleHandle("ntdll.dll");
if (hNtdll == NULL)
return;
pRtlGetVersion =
(PfnRtlGetVersion) GetProcAddress(hNtdll, "RtlGetVersion");
if (pRtlGetVersion == NULL)
return;
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
pRtlGetVersion(&osver);
win_version =
MAKE_VER(osver.dwMajorVersion, osver.dwMinorVersion,
osver.dwBuildNumber);
}
/*
* Init the tables for toupper() and tolower().
*/
@@ -113,6 +140,8 @@ mch_early_init(void)
{
int i;
win_version_init();
PlatformId();
// Init the tables for toupper() and tolower()
+17 -74
View File
@@ -160,42 +160,11 @@ static int suppress_winsize = 1; // don't fiddle with console
static WCHAR *exe_pathw = NULL;
static BOOL win8_or_later = FALSE;
BOOL win10_22H2_or_later = FALSE;
BOOL win11_or_later = FALSE; // used in gui_mch_set_titlebar_colors(void)
#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
static BOOL use_alternate_screen_buffer = FALSE;
#endif
/*
* Get version number including build number
*/
typedef BOOL (WINAPI *PfnRtlGetVersion)(LPOSVERSIONINFOW);
#define MAKE_VER(major, minor, build) \
(((major) << 24) | ((minor) << 16) | (build))
static DWORD
get_build_number(void)
{
OSVERSIONINFOW osver;
HMODULE hNtdll;
PfnRtlGetVersion pRtlGetVersion;
DWORD ver = MAKE_VER(0, 0, 0);
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
hNtdll = GetModuleHandle("ntdll.dll");
if (hNtdll == NULL)
return ver;
pRtlGetVersion =
(PfnRtlGetVersion)GetProcAddress(hNtdll, "RtlGetVersion");
pRtlGetVersion(&osver);
ver = MAKE_VER(min(osver.dwMajorVersion, 255),
min(osver.dwMinorVersion, 255),
min(osver.dwBuildNumber, 32767));
return ver;
}
extern DWORD win_version; // this is in os_mswin.c
#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
static BOOL
@@ -257,7 +226,7 @@ read_console_input(
if (nLength == -2)
return (s_dwMax > 0) ? TRUE : FALSE;
if (!win8_or_later)
if (win_version < MAKE_VER(6, 2, 0)) // Before Windows 8
{
if (nLength == -1)
return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
@@ -918,39 +887,17 @@ win32_enable_privilege(LPTSTR lpszPrivilege)
}
#endif
#ifdef _MSC_VER
// Suppress the deprecation warning for using GetVersionEx().
// It is needed for implementing "windowsversion()".
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
/*
* Set "win8_or_later" and fill in "windowsVersion" if possible.
* Fill in "windowsVersion" if possible and enable security privilege for ACL.
*/
void
PlatformId(void)
{
OSVERSIONINFO ovi;
ovi.dwOSVersionInfoSize = sizeof(ovi);
if (!GetVersionEx(&ovi))
return;
#ifdef FEAT_EVAL
vim_snprintf(windowsVersion, sizeof(windowsVersion), "%d.%d",
(int)ovi.dwMajorVersion, (int)ovi.dwMinorVersion);
DWORD major = (win_version >> 24) & 0xFF;
DWORD minor = (win_version >> 16) & 0xFF;
vim_snprintf(windowsVersion, sizeof(windowsVersion), "%d.%d", major, minor);
#endif
if ((ovi.dwMajorVersion == 6 && ovi.dwMinorVersion >= 2)
|| ovi.dwMajorVersion > 6)
win8_or_later = TRUE;
if ((ovi.dwMajorVersion == 10 && ovi.dwBuildNumber >= 19045)
|| ovi.dwMajorVersion > 10)
win10_22H2_or_later = TRUE;
if ((ovi.dwMajorVersion == 10 && ovi.dwBuildNumber >= 22000)
|| ovi.dwMajorVersion > 10)
win11_or_later = TRUE;
#ifdef HAVE_ACL
// Enable privilege for getting or setting SACLs.
@@ -958,9 +905,6 @@ PlatformId(void)
return;
#endif
}
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
@@ -8537,7 +8481,7 @@ mch_setenv(char *var, char *value, int x UNUSED)
* Support for 256 colors and 24-bit colors was added in Windows 10
* version 1703 (Creators update).
*/
#define VTP_FIRST_SUPPORT_BUILD MAKE_VER(10, 0, 15063)
#define VTP_FIRST_SUPPORT_BUILD MAKE_VER(10, 0, 15063)
/*
* Support for pseudo-console (ConPTY) was added in windows 10
@@ -8582,7 +8526,6 @@ mch_setenv(char *var, char *value, int x UNUSED)
static void
vtp_flag_init(void)
{
DWORD ver = get_build_number();
#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)
DWORD mode;
HANDLE out;
@@ -8593,7 +8536,7 @@ vtp_flag_init(void)
{
out = GetStdHandle(STD_OUTPUT_HANDLE);
vtp_working = (ver >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0;
vtp_working = (win_version >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0;
GetConsoleMode(out, &mode);
mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
if (SetConsoleMode(out, mode) == 0)
@@ -8601,26 +8544,26 @@ vtp_flag_init(void)
// VTP uses alternate screen buffer.
// But, not if running in a nested terminal
use_alternate_screen_buffer = win10_22H2_or_later && p_rs && vtp_working
&& !mch_getenv("VIM_TERMINAL");
use_alternate_screen_buffer = win_version >= MAKE_VER(10, 0, 19045)
&& p_rs && vtp_working && !mch_getenv("VIM_TERMINAL");
}
#endif
if (ver >= CONPTY_FIRST_SUPPORT_BUILD)
if (win_version >= CONPTY_FIRST_SUPPORT_BUILD)
conpty_working = 1;
if (ver >= CONPTY_STABLE_BUILD)
if (win_version >= CONPTY_STABLE_BUILD)
conpty_stable = 1;
if (ver <= CONPTY_INSIDER_BUILD)
if (win_version <= CONPTY_INSIDER_BUILD)
conpty_type = 3;
if (ver <= CONPTY_1909_BUILD)
if (win_version <= CONPTY_1909_BUILD)
conpty_type = 2;
if (ver <= CONPTY_1903_BUILD)
if (win_version <= CONPTY_1903_BUILD)
conpty_type = 2;
if (ver < CONPTY_FIRST_SUPPORT_BUILD)
if (win_version < CONPTY_FIRST_SUPPORT_BUILD)
conpty_type = 1;
if (ver >= CONPTY_NEXT_UPDATE_BUILD)
if (win_version >= CONPTY_NEXT_UPDATE_BUILD)
conpty_fix_type = 1;
}
+4
View File
@@ -224,3 +224,7 @@ Trace(char *pszFormat, ...);
#endif
#define mch_getenv(x) (char_u *)getenv((char *)(x))
#define vim_mkdir(x, y) mch_mkdir(x)
// Windows Version
#define MAKE_VER(major, minor, build) \
((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((build) & 0x7FFF))
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
171,
/**/
170,
/**/