diff --git a/ui/colors.palette b/ui/colors.palette index bf87e4d..a93505a 100644 --- a/ui/colors.palette +++ b/ui/colors.palette @@ -89,7 +89,7 @@ tooltipBg: #eef2f5; // tooltip background (like when you put mouse over the mess tooltipFg: #5d6c80; // tooltip text tooltipBorderFg: #c9d1db; // tooltip border -// custom title bar for Windows and macOS +// custom title bar titleShadow: #00000003; // one pixel line shadow at the bottom of custom window title titleBg: windowBgOver; // custom window title background when window is inactive titleBgActive: titleBg; // custom window title background when window is active @@ -109,8 +109,8 @@ titleButtonCloseBgActive: titleButtonCloseBg; // custom window title close butto titleButtonCloseFgActive: titleButtonCloseFg; // custom window title close button icon when window is active (Windows only) titleButtonCloseBgActiveOver: titleButtonCloseBgOver; // custom window title close button background with mouse over when window is active (Windows only) titleButtonCloseFgActiveOver: titleButtonCloseFgOver; // custom window title close button icon with mouse over when window is active (Windows only) -titleFg: #acacac; // custom window title text when window is inactive (macOS only) -titleFgActive: #3e3c3e; // custom window title text when window is active (macOS only) +titleFg: #acacac; // custom window title text when window is inactive (Windows 11 and macOS) +titleFgActive: #3e3c3e; // custom window title text when window is active (Windows 11 and macOS) // tray icon trayCounterBg: #f23c34; // tray icon counter background diff --git a/ui/platform/win/ui_window_shadow_win.cpp b/ui/platform/win/ui_window_shadow_win.cpp index 2463aa9..79abd98 100644 --- a/ui/platform/win/ui_window_shadow_win.cpp +++ b/ui/platform/win/ui_window_shadow_win.cpp @@ -8,6 +8,7 @@ #include "ui/rp_widget.h" #include "ui/platform/win/ui_window_win.h" +#include "base/platform/base_platform_info.h" #include "styles/style_widgets.h" #include @@ -42,7 +43,8 @@ base::flat_map> ShadowByHandle; WindowShadow::WindowShadow(not_null window, QColor color) : _window(window) -, _handle(GetWindowHandle(window)) { +, _handle(GetWindowHandle(window)) +, _windows11(::Platform::IsWindows11OrGreater()) { init(color); } @@ -315,7 +317,7 @@ void WindowShadow::horCorners(int w, Gdiplus::Graphics *pgraphics0, Gdiplus::Gra } Gdiplus::Color WindowShadow::getColor(uchar alpha) const { - return Gdiplus::Color(BYTE(alpha), _r, _g, _b); + return Gdiplus::Color(BYTE(_windows11 ? 1 : alpha), _r, _g, _b); } Gdiplus::SolidBrush WindowShadow::getBrush(uchar alpha) const { diff --git a/ui/platform/win/ui_window_shadow_win.h b/ui/platform/win/ui_window_shadow_win.h index c157fa5..db63914 100644 --- a/ui/platform/win/ui_window_shadow_win.h +++ b/ui/platform/win/ui_window_shadow_win.h @@ -78,6 +78,7 @@ private: const not_null _window; const HWND _handle; + const bool _windows11 = false; int _x = 0; int _y = 0; diff --git a/ui/platform/win/ui_window_title_win.cpp b/ui/platform/win/ui_window_title_win.cpp index ba578f9..1e3e63d 100644 --- a/ui/platform/win/ui_window_title_win.cpp +++ b/ui/platform/win/ui_window_title_win.cpp @@ -41,6 +41,10 @@ void TitleWidget::setStyle(const style::WindowTitle &st) { update(); } +not_null TitleWidget::st() const { + return _controls.st(); +} + void TitleWidget::setResizeEnabled(bool enabled) { _controls.setResizeEnabled(enabled); } diff --git a/ui/platform/win/ui_window_title_win.h b/ui/platform/win/ui_window_title_win.h index bc5fed6..c6e7d0e 100644 --- a/ui/platform/win/ui_window_title_win.h +++ b/ui/platform/win/ui_window_title_win.h @@ -45,6 +45,7 @@ public: void setText(const QString &text); void setStyle(const style::WindowTitle &st); + [[nodiscard]] not_null st() const; [[nodiscard]] HitTestResult hitTest(QPoint point) const; void setResizeEnabled(bool enabled); diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 21c9ea8..9fc4b13 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -13,6 +13,7 @@ #include "base/integration.h" #include "base/debug_log.h" #include "styles/palette.h" +#include "styles/style_widgets.h" #include #include @@ -29,7 +30,13 @@ namespace Ui { namespace Platform { namespace { -bool IsCompositionEnabled() { +constexpr auto kDWMWCP_ROUND = DWORD(2); +constexpr auto kDWMWA_WINDOW_CORNER_PREFERENCE = DWORD(33); +constexpr auto kDWMWA_BORDER_COLOR = DWORD(34); +constexpr auto kDWMWA_CAPTION_COLOR = DWORD(35); +constexpr auto kDWMWA_TEXT_COLOR = DWORD(36); + +[[nodiscard]] bool IsCompositionEnabled() { auto result = BOOL(FALSE); const auto success = (DwmIsCompositionEnabled(&result) == S_OK); return success && result; @@ -85,23 +92,6 @@ bool IsTaskbarAutoHidden(LPRECT rcMon = nullptr, PUINT pEdge = nullptr) { return bAutoHidden; } -HRESULT WinApiSetWindowTheme( - HWND hWnd, - LPCWSTR pszSubAppName, - LPCWSTR pszSubIdList) { - static const auto method = [&] { - using f_SetWindowTheme = HRESULT(FAR STDAPICALLTYPE*)( - HWND hWnd, - LPCWSTR pszSubAppName, - LPCWSTR pszSubIdList); - auto result = f_SetWindowTheme(); - const auto loaded = base::Platform::SafeLoadLibrary(L"uxtheme.dll"); - base::Platform::LoadMethod(loaded, "SetWindowTheme", result); - return result; - }(); - return method ? method(hWnd, pszSubAppName, pszSubIdList) : HRESULT(); -} - void FixAeroSnap(HWND handle) { SetWindowLongPtr( handle, @@ -198,6 +188,7 @@ void WindowHelper::setTitle(const QString &title) { void WindowHelper::setTitleStyle(const style::WindowTitle &st) { _title->setStyle(st); + updateWindowFrameColors(); } void WindowHelper::setNativeFrame(bool enabled) { @@ -216,6 +207,7 @@ void WindowHelper::setNativeFrame(bool enabled) { initialShadowUpdate(); } updateMargins(); + updateWindowFrameColors(); fixMaximizedWindow(); } @@ -227,6 +219,15 @@ void WindowHelper::initialShadowUpdate() { } else { _shadow->update(Change::Moved | Change::Resized | Change::Shown); } + + if (::Platform::IsWindows11OrGreater()) { + auto preference = kDWMWCP_ROUND; + DwmSetWindowAttribute( + _handle, + kDWMWA_WINDOW_CORNER_PREFERENCE, + &preference, + sizeof(preference)); + } } void WindowHelper::setMinimumSize(QSize size) { @@ -270,6 +271,7 @@ void WindowHelper::init() { if (_shadow) { _shadow->setColor(st::windowShadowFg->c); } + updateWindowFrameColors(); Ui::ForceFullRepaint(window()); }, window()->lifetime()); @@ -291,9 +293,10 @@ void WindowHelper::init() { updateMargins(); if (!::Platform::IsWindows8OrGreater()) { - WinApiSetWindowTheme(_handle, L" ", L" "); + SetWindowTheme(_handle, L" ", L" "); QApplication::setStyle(QStyleFactory::create("Windows")); } + updateWindowFrameColors(); _menu = GetSystemMenu(_handle, FALSE); updateSystemMenu(); @@ -326,13 +329,15 @@ bool WindowHelper::handleNativeEvent( if (LOWORD(wParam) == WA_CLICKACTIVE) { Ui::MarkInactivePress(window(), true); } + const auto active = (LOWORD(wParam) != WA_INACTIVE); if (_shadow) { - if (LOWORD(wParam) != WA_INACTIVE) { + if (active) { _shadow->update(WindowShadow::Change::Activate); } else { _shadow->update(WindowShadow::Change::Deactivate); } } + updateWindowFrameColors(active); window()->update(); } return false; @@ -553,6 +558,39 @@ int WindowHelper::titleHeight() const { return _title->isHidden() ? 0 : _title->height(); } +void WindowHelper::updateWindowFrameColors() { + updateWindowFrameColors(window()->isActiveWindow()); +} + +void WindowHelper::updateWindowFrameColors(bool active) { + if (!::Platform::IsWindows11OrGreater()) { + return; + } + const auto bg = active + ? _title->st()->bgActive->c + : _title->st()->bg->c; + COLORREF bgRef = RGB(bg.red(), bg.green(), bg.blue()); + DwmSetWindowAttribute( + _handle, + kDWMWA_BORDER_COLOR, + &bgRef, + sizeof(COLORREF)); + DwmSetWindowAttribute( + _handle, + kDWMWA_CAPTION_COLOR, + &bgRef, + sizeof(COLORREF)); + const auto fg = active + ? _title->st()->fgActive->c + : _title->st()->fg->c; + COLORREF fgRef = RGB(fg.red(), fg.green(), fg.blue()); + DwmSetWindowAttribute( + _handle, + kDWMWA_TEXT_COLOR, + &fgRef, + sizeof(COLORREF)); +} + void WindowHelper::updateMargins() { if (_updatingMargins) return; diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index dadf5db..c5fce59 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -38,6 +38,8 @@ private: void init(); void updateMargins(); + void updateWindowFrameColors(); + void updateWindowFrameColors(bool active); void updateSystemMenu(); void updateSystemMenu(Qt::WindowState state); void initialShadowUpdate();