diff --git a/launcher/Application.cpp b/launcher/Application.cpp index aa937964..c4179b49 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -60,6 +60,10 @@ #include "ui/themes/BrightTheme.h" #include "ui/themes/CustomTheme.h" +#ifdef Q_OS_WIN +#include "ui/WinDarkmode.h" +#endif + #include "ui/setupwizard/SetupWizard.h" #include "ui/setupwizard/LanguageWizardPage.h" #include "ui/setupwizard/JavaWizardPage.h" @@ -1195,6 +1199,15 @@ void Application::setApplicationTheme(const QString& name, bool initial) { auto & theme = (*themeIter).second; theme->apply(initial); +#ifdef Q_OS_WIN + if (m_mainWindow) { + if (QString::compare(theme->id(), "dark") == 0) { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + } else { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + } + } +#endif } else { @@ -1425,6 +1438,13 @@ MainWindow* Application::showMainWindow(bool minimized) m_mainWindow = new MainWindow(); m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray())); m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); +#ifdef Q_OS_WIN + if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + } else { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + } +#endif if(minimized) { m_mainWindow->showMinimized(); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 6e93b530..e44b98eb 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -868,6 +868,16 @@ SET(LAUNCHER_SOURCES ui/instanceview/VisualGroup.h ) +if(WIN32) + set(LAUNCHER_SOURCES + ${LAUNCHER_SOURCES} + + # GUI - dark titlebar for Windows 10/11 + ui/WinDarkmode.h + ui/WinDarkmode.cpp + ) +endif() + qt_wrap_ui(LAUNCHER_UI ui/setupwizard/PasteWizardPage.ui ui/pages/global/AccountListPage.ui diff --git a/launcher/ui/WinDarkmode.cpp b/launcher/ui/WinDarkmode.cpp new file mode 100644 index 00000000..eac68e4f --- /dev/null +++ b/launcher/ui/WinDarkmode.cpp @@ -0,0 +1,32 @@ +#include + +#include "WinDarkmode.h" + +namespace WinDarkmode { + +/* See https://github.com/statiolake/neovim-qt/commit/da8eaba7f0e38b6b51f3bacd02a8cc2d1f7a34d8 */ +void setDarkWinTitlebar(WId winid, bool darkmode) +{ + HWND hwnd = reinterpret_cast(winid); + BOOL dark = (BOOL) darkmode; + + HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + HMODULE hUser32 = GetModuleHandleW(L"user32.dll"); + fnAllowDarkModeForWindow AllowDarkModeForWindow + = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133))); + fnSetPreferredAppMode SetPreferredAppMode + = reinterpret_cast(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135))); + fnSetWindowCompositionAttribute SetWindowCompositionAttribute + = reinterpret_cast(GetProcAddress(hUser32, "SetWindowCompositionAttribute")); + + SetPreferredAppMode(AllowDark); + AllowDarkModeForWindow(hwnd, dark); + WINDOWCOMPOSITIONATTRIBDATA data = { + WCA_USEDARKMODECOLORS, + &dark, + sizeof(dark) + }; + SetWindowCompositionAttribute(hwnd, &data); +} + +} diff --git a/launcher/ui/WinDarkmode.h b/launcher/ui/WinDarkmode.h new file mode 100644 index 00000000..5b567c6b --- /dev/null +++ b/launcher/ui/WinDarkmode.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include + + +namespace WinDarkmode { + +void setDarkWinTitlebar(WId winid, bool darkmode); + +enum PreferredAppMode { + Default, + AllowDark, + ForceDark, + ForceLight, + Max +}; + +enum WINDOWCOMPOSITIONATTRIB { + WCA_UNDEFINED = 0, + WCA_NCRENDERING_ENABLED = 1, + WCA_NCRENDERING_POLICY = 2, + WCA_TRANSITIONS_FORCEDISABLED = 3, + WCA_ALLOW_NCPAINT = 4, + WCA_CAPTION_BUTTON_BOUNDS = 5, + WCA_NONCLIENT_RTL_LAYOUT = 6, + WCA_FORCE_ICONIC_REPRESENTATION = 7, + WCA_EXTENDED_FRAME_BOUNDS = 8, + WCA_HAS_ICONIC_BITMAP = 9, + WCA_THEME_ATTRIBUTES = 10, + WCA_NCRENDERING_EXILED = 11, + WCA_NCADORNMENTINFO = 12, + WCA_EXCLUDED_FROM_LIVEPREVIEW = 13, + WCA_VIDEO_OVERLAY_ACTIVE = 14, + WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15, + WCA_DISALLOW_PEEK = 16, + WCA_CLOAK = 17, + WCA_CLOAKED = 18, + WCA_ACCENT_POLICY = 19, + WCA_FREEZE_REPRESENTATION = 20, + WCA_EVER_UNCLOAKED = 21, + WCA_VISUAL_OWNER = 22, + WCA_HOLOGRAPHIC = 23, + WCA_EXCLUDED_FROM_DDA = 24, + WCA_PASSIVEUPDATEMODE = 25, + WCA_USEDARKMODECOLORS = 26, + WCA_LAST = 27 +}; + +struct WINDOWCOMPOSITIONATTRIBDATA { + WINDOWCOMPOSITIONATTRIB Attrib; + PVOID pvData; + SIZE_T cbData; +}; + +using fnAllowDarkModeForWindow = BOOL (WINAPI *)(HWND hWnd, BOOL allow); +using fnSetPreferredAppMode = PreferredAppMode (WINAPI *)(PreferredAppMode appMode); +using fnSetWindowCompositionAttribute = BOOL (WINAPI *)(HWND hwnd, WINDOWCOMPOSITIONATTRIBDATA *); + +}