patch 9.1.1966: MS-Windows: dark mode in gui is not supported

Problem:  MS-Windows: dark mode in gui is not supported
Solution: Inplement the 'd' flag in 'guioptions'
          (Mao-Yining).

related: #12282
closes: #18877

Co-Authored-By: LemonBoy <thatlemon@gmail.com>
Signed-off-by: Mao-Yining <mao.yining@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Mao-Yining
2025-12-09 15:23:39 +01:00
committed by Christian Brabandt
parent 927ad166a4
commit e758eac336
9 changed files with 73 additions and 7 deletions

View File

@ -4527,7 +4527,7 @@ A jump table for the options with a short description can be found at |Q_op|.
See |gui-w32-title-bar| for details. See |gui-w32-title-bar| for details.
*'go-d'* *'go-d'*
'd' Use dark theme variant if available. Currently only works for 'd' Use dark theme variant if available. Currently only works for
GTK+ GUI. Win32 and GTK+ GUI.
*'go-e'* *'go-e'*
'e' Add tab pages when indicated with 'showtabline'. 'e' Add tab pages when indicated with 'showtabline'.
'guitablabel' can be used to change the text in the labels. 'guitablabel' can be used to change the text in the labels.

View File

@ -1,4 +1,4 @@
*todo.txt* For Vim version 9.1. Last change: 2025 Nov 18 *todo.txt* For Vim version 9.1. Last change: 2025 Dec 09
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -309,8 +309,6 @@ Problem with Visual highlight when 'linebreak' and 'showbreak' are set.
GUI Scroll test fails on FreeBSD when using Motif. See FIXME in GUI Scroll test fails on FreeBSD when using Motif. See FIXME in
Test_scrollbars in src/test_gui.vim Test_scrollbars in src/test_gui.vim
Support dark mode for MS-Windows: #12282
Remote command escapes single quote with backslash, should be doubling the Remote command escapes single quote with backslash, should be doubling the
single quote in vim_strsave_escaped_ext() #12202. single quote in vim_strsave_escaped_ext() #12202.

View File

@ -508,7 +508,7 @@
/* /*
* GUI dark theme variant * GUI dark theme variant
*/ */
#if defined(FEAT_GUI_GTK) && defined(USE_GTK3) #if (defined(FEAT_GUI_GTK) && defined(USE_GTK3)) || defined(FEAT_GUI_MSWIN)
# define FEAT_GUI_DARKTHEME # define FEAT_GUI_DARKTHEME
#endif #endif

View File

@ -3480,7 +3480,7 @@ static int prev_which_scrollbars[3];
gui_init_which_components(char_u *oldval UNUSED) gui_init_which_components(char_u *oldval UNUSED)
{ {
#ifdef FEAT_GUI_DARKTHEME #ifdef FEAT_GUI_DARKTHEME
static int prev_dark_theme = -1; static int prev_dark_theme = FALSE;
int using_dark_theme = FALSE; int using_dark_theme = FALSE;
#endif #endif
#ifdef FEAT_MENU #ifdef FEAT_MENU

View File

@ -315,6 +315,10 @@ gui_mch_set_rendering_options(char_u *s)
# define SPI_SETWHEELSCROLLCHARS 0x006D # define SPI_SETWHEELSCROLLCHARS 0x006D
#endif #endif
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
# define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
#ifndef DWMWA_CAPTION_COLOR #ifndef DWMWA_CAPTION_COLOR
# define DWMWA_CAPTION_COLOR 35 # define DWMWA_CAPTION_COLOR 35
#endif #endif
@ -417,6 +421,14 @@ static HINSTANCE hLibDwm = NULL;
static HRESULT (WINAPI *pDwmSetWindowAttribute)(HWND, DWORD, LPCVOID, DWORD); static HRESULT (WINAPI *pDwmSetWindowAttribute)(HWND, DWORD, LPCVOID, DWORD);
static void dyn_dwm_load(void); static void dyn_dwm_load(void);
#ifdef FEAT_GUI_DARKTHEME
static HINSTANCE hUxThemeLib = NULL;
static DWORD (WINAPI *pSetPreferredAppMode)(DWORD) = NULL;
static void (WINAPI *pFlushMenuThemes)(void) = NULL;
static void dyn_uxtheme_load(void);
#endif
static int WINAPI static int WINAPI
stubGetSystemMetricsForDpi(int nIndex, UINT dpi UNUSED) stubGetSystemMetricsForDpi(int nIndex, UINT dpi UNUSED)
{ {
@ -3116,6 +3128,48 @@ gui_mch_set_curtab(int nr)
#endif #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)
pDwmSetWindowAttribute(s_hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark,
sizeof(dark));
if (pSetPreferredAppMode != NULL)
pSetPreferredAppMode(dark);
if (pFlushMenuThemes != NULL)
pFlushMenuThemes();
}
static void
dyn_uxtheme_load(void)
{
hUxThemeLib = vimLoadLib("uxtheme.dll");
if (hUxThemeLib == NULL)
return;
pSetPreferredAppMode = (DWORD (WINAPI *)(DWORD))
GetProcAddress(hUxThemeLib, MAKEINTRESOURCE(135));
pFlushMenuThemes = (void (WINAPI *)(void))
GetProcAddress(hUxThemeLib, MAKEINTRESOURCE(136));
if (pSetPreferredAppMode == NULL || pFlushMenuThemes == NULL)
{
FreeLibrary(hUxThemeLib);
hUxThemeLib = NULL;
return;
}
}
#endif // FEAT_GUI_DARKTHEME
/* /*
* ":simalt" command. * ":simalt" command.
*/ */
@ -5646,6 +5700,10 @@ gui_mch_init(void)
load_dpi_func(); load_dpi_func();
#ifdef FEAT_GUI_DARKTHEME
dyn_uxtheme_load();
#endif
dyn_dwm_load(); dyn_dwm_load();
s_dpi = pGetDpiForSystem(); s_dpi = pGetDpiForSystem();

View File

@ -161,7 +161,7 @@ static int suppress_winsize = 1; // don't fiddle with console
static WCHAR *exe_pathw = NULL; static WCHAR *exe_pathw = NULL;
static BOOL win8_or_later = FALSE; static BOOL win8_or_later = FALSE;
static BOOL win10_22H2_or_later = FALSE; BOOL win10_22H2_or_later = FALSE;
BOOL win11_or_later = FALSE; // used in gui_mch_set_titlebar_colors(void) BOOL win11_or_later = FALSE; // used in gui_mch_set_titlebar_colors(void)
#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) #if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL)

View File

@ -43,6 +43,7 @@ void gui_mch_show_tabline(int showit);
int gui_mch_showing_tabline(void); int gui_mch_showing_tabline(void);
void gui_mch_update_tabline(void); void gui_mch_update_tabline(void);
void gui_mch_set_curtab(int nr); void gui_mch_set_curtab(int nr);
void gui_mch_set_dark_theme(int dark);
void ex_simalt(exarg_T *eap); void ex_simalt(exarg_T *eap);
void gui_mch_find_dialog(exarg_T *eap); void gui_mch_find_dialog(exarg_T *eap);
void gui_mch_replace_dialog(exarg_T *eap); void gui_mch_replace_dialog(exarg_T *eap);

View File

@ -671,6 +671,13 @@ func Test_set_guioptions()
exec 'sleep' . duration exec 'sleep' . duration
call assert_equal('egmrLtT', &guioptions) call assert_equal('egmrLtT', &guioptions)
set guioptions+=d
exec 'sleep' . duration
call assert_equal('egmrLtTd', &guioptions)
set guioptions-=d
exec 'sleep' . duration
call assert_equal('egmrLtT', &guioptions)
else else
" Default Value " Default Value
set guioptions& set guioptions&

View File

@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1966,
/**/ /**/
1965, 1965,
/**/ /**/