mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 15:47:11 +02:00
Use dark Windows title bar for night mode.
This commit is contained in:
parent
511067981d
commit
c86ced8a1e
5 changed files with 243 additions and 17 deletions
|
@ -112,11 +112,44 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
|
|||
_shadow->setColor(st::windowShadowFg->c);
|
||||
}
|
||||
});
|
||||
Core::App().settings().nativeWindowFrameChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
initShadows();
|
||||
validateWindowTheme();
|
||||
fixMaximizedWindow();
|
||||
setupNativeWindowFrame();
|
||||
}
|
||||
|
||||
void MainWindow::setupNativeWindowFrame() {
|
||||
auto nativeFrame = rpl::single(
|
||||
Core::App().settings().nativeWindowFrame()
|
||||
) | rpl::then(
|
||||
Core::App().settings().nativeWindowFrameChanges()
|
||||
);
|
||||
|
||||
using BackgroundUpdate = Window::Theme::BackgroundUpdate;
|
||||
auto paletteChanges = base::ObservableViewer(
|
||||
*Window::Theme::Background()
|
||||
) | rpl::filter([=](const BackgroundUpdate &update) {
|
||||
return update.type == BackgroundUpdate::Type::ApplyingTheme;
|
||||
}) | rpl::to_empty;
|
||||
|
||||
auto nightMode = rpl::single(
|
||||
rpl::empty_value()
|
||||
) | rpl::then(
|
||||
std::move(paletteChanges)
|
||||
) | rpl::map([=] {
|
||||
return Window::Theme::IsNightMode();
|
||||
}) | rpl::distinct_until_changed();
|
||||
|
||||
rpl::combine(
|
||||
std::move(nativeFrame),
|
||||
std::move(nightMode)
|
||||
) | rpl::skip(1) | rpl::start_with_next([=](bool native, bool night) {
|
||||
const auto nativeChanged = (_wasNativeFrame != native);
|
||||
if (nativeChanged) {
|
||||
_wasNativeFrame = native;
|
||||
initShadows();
|
||||
}
|
||||
validateWindowTheme(native, night);
|
||||
if (nativeChanged) {
|
||||
fixMaximizedWindow();
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
|
@ -136,11 +169,13 @@ void MainWindow::shadowsUpdate(
|
|||
}
|
||||
|
||||
void MainWindow::shadowsActivate() {
|
||||
_hasActiveFrame = true;
|
||||
// _shadow->setColor(_shActive);
|
||||
shadowsUpdate(Ui::Platform::WindowShadow::Change::Activate);
|
||||
}
|
||||
|
||||
void MainWindow::shadowsDeactivate() {
|
||||
_hasActiveFrame = false;
|
||||
// _shadow->setColor(_shInactive);
|
||||
}
|
||||
|
||||
|
@ -395,7 +430,9 @@ void MainWindow::updateCustomMargins() {
|
|||
}
|
||||
if (!_themeInited) {
|
||||
_themeInited = true;
|
||||
validateWindowTheme();
|
||||
validateWindowTheme(
|
||||
Core::App().settings().nativeWindowFrame(),
|
||||
Window::Theme::IsNightMode());
|
||||
}
|
||||
_inUpdateMargins = false;
|
||||
}
|
||||
|
@ -444,17 +481,104 @@ QMargins MainWindow::computeCustomMargins() {
|
|||
return margins;
|
||||
}
|
||||
|
||||
void MainWindow::validateWindowTheme() {
|
||||
if (IsWindows8OrGreater()) {
|
||||
void MainWindow::validateWindowTheme(bool native, bool night) {
|
||||
if (!Dlls::SetWindowTheme) {
|
||||
return;
|
||||
} else if (!IsWindows8OrGreater()) {
|
||||
const auto empty = native ? nullptr : L" ";
|
||||
Dlls::SetWindowTheme(ps_hWnd, empty, empty);
|
||||
QApplication::setStyle(QStyleFactory::create(u"Windows"_q));
|
||||
} else if (!Platform::IsDarkModeSupported()/*
|
||||
|| (!Dlls::AllowDarkModeForApp && !Dlls::SetPreferredAppMode)
|
||||
|| !Dlls::AllowDarkModeForWindow
|
||||
|| !Dlls::RefreshImmersiveColorPolicyState
|
||||
|| !Dlls::FlushMenuThemes*/) {
|
||||
return;
|
||||
} else if (!native) {
|
||||
Dlls::SetWindowTheme(ps_hWnd, nullptr, nullptr);
|
||||
return;
|
||||
} else if (Dlls::SetWindowTheme != nullptr) {
|
||||
if (Core::App().settings().nativeWindowFrame()) {
|
||||
Dlls::SetWindowTheme(ps_hWnd, nullptr, nullptr);
|
||||
} else {
|
||||
Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
|
||||
}
|
||||
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
|
||||
}
|
||||
|
||||
// See "https://github.com/microsoft/terminal/blob/"
|
||||
// "eb480b6bbbd83a2aafbe62992d360838e0ab9da5/"
|
||||
// "src/interactivity/win32/windowtheme.cpp#L43-L63"
|
||||
|
||||
auto darkValue = BOOL(night ? TRUE : FALSE);
|
||||
|
||||
const auto updateStyle = [&] {
|
||||
static const auto kSystemVersion = QOperatingSystemVersion::current();
|
||||
if (kSystemVersion.microVersion() < 18362) {
|
||||
SetPropW(
|
||||
ps_hWnd,
|
||||
L"UseImmersiveDarkModeColors",
|
||||
reinterpret_cast<HANDLE>(static_cast<INT_PTR>(darkValue)));
|
||||
} else if (Dlls::SetWindowCompositionAttribute) {
|
||||
Dlls::WINDOWCOMPOSITIONATTRIBDATA data = {
|
||||
Dlls::WINDOWCOMPOSITIONATTRIB::WCA_USEDARKMODECOLORS,
|
||||
&darkValue,
|
||||
sizeof(darkValue)
|
||||
};
|
||||
Dlls::SetWindowCompositionAttribute(ps_hWnd, &data);
|
||||
} else if (Dlls::DwmSetWindowAttribute) {
|
||||
static constexpr auto DWMWA_USE_IMMERSIVE_DARK_MODE_0 = DWORD(19);
|
||||
static constexpr auto DWMWA_USE_IMMERSIVE_DARK_MODE = DWORD(20);
|
||||
const auto set = [&](DWORD attribute) {
|
||||
return Dlls::DwmSetWindowAttribute(
|
||||
ps_hWnd,
|
||||
attribute,
|
||||
&darkValue,
|
||||
sizeof(darkValue));
|
||||
};
|
||||
if (FAILED(set(DWMWA_USE_IMMERSIVE_DARK_MODE))) {
|
||||
set(DWMWA_USE_IMMERSIVE_DARK_MODE_0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateStyle();
|
||||
|
||||
// See "https://osdn.net/projects/tortoisesvn/scm/svn/blobs/28812/"
|
||||
// "trunk/src/TortoiseIDiff/MainWindow.cpp"
|
||||
//
|
||||
// But for now it works event with a small part of that.
|
||||
//
|
||||
|
||||
//const auto updateWindowTheme = [&] {
|
||||
// const auto set = [&](LPCWSTR name) {
|
||||
// return Dlls::SetWindowTheme(ps_hWnd, name, nullptr);
|
||||
// };
|
||||
// if (!night || FAILED(set(L"DarkMode_Explorer"))) {
|
||||
// set(L"Explorer");
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//if (night) {
|
||||
// if (Dlls::SetPreferredAppMode) {
|
||||
// Dlls::SetPreferredAppMode(Dlls::PreferredAppMode::AllowDark);
|
||||
// } else {
|
||||
// Dlls::AllowDarkModeForApp(TRUE);
|
||||
// }
|
||||
// Dlls::AllowDarkModeForWindow(ps_hWnd, TRUE);
|
||||
// updateWindowTheme();
|
||||
// updateStyle();
|
||||
// Dlls::FlushMenuThemes();
|
||||
// Dlls::RefreshImmersiveColorPolicyState();
|
||||
//} else {
|
||||
// updateWindowTheme();
|
||||
// Dlls::AllowDarkModeForWindow(ps_hWnd, FALSE);
|
||||
// updateStyle();
|
||||
// Dlls::FlushMenuThemes();
|
||||
// Dlls::RefreshImmersiveColorPolicyState();
|
||||
// if (Dlls::SetPreferredAppMode) {
|
||||
// Dlls::SetPreferredAppMode(Dlls::PreferredAppMode::Default);
|
||||
// } else {
|
||||
// Dlls::AllowDarkModeForApp(FALSE);
|
||||
// }
|
||||
//}
|
||||
|
||||
// Didn't find any other way to definitely repaint with the new style.
|
||||
SendMessage(ps_hWnd, WM_NCACTIVATE, _hasActiveFrame ? 0 : 1, 0);
|
||||
SendMessage(ps_hWnd, WM_NCACTIVATE, _hasActiveFrame ? 1 : 0, 0);
|
||||
}
|
||||
|
||||
void MainWindow::fixMaximizedWindow() {
|
||||
|
|
|
@ -90,9 +90,10 @@ protected:
|
|||
QTimer psUpdatedPositionTimer;
|
||||
|
||||
private:
|
||||
void setupNativeWindowFrame();
|
||||
void updateIconCounters();
|
||||
QMargins computeCustomMargins();
|
||||
void validateWindowTheme();
|
||||
void validateWindowTheme(bool native, bool night);
|
||||
void psDestroyIcons();
|
||||
void fixMaximizedWindow();
|
||||
|
||||
|
@ -102,6 +103,8 @@ private:
|
|||
|
||||
bool _themeInited = false;
|
||||
bool _inUpdateMargins = false;
|
||||
bool _wasNativeFrame = false;
|
||||
bool _hasActiveFrame = false;
|
||||
|
||||
HWND ps_hWnd = nullptr;
|
||||
HWND ps_tbHider_hWnd = nullptr;
|
||||
|
|
|
@ -41,6 +41,7 @@ void init() {
|
|||
u"dwmapi.dll"_q,
|
||||
u"rstrtmgr.dll"_q,
|
||||
u"psapi.dll"_q,
|
||||
u"user32.dll"_q,
|
||||
};
|
||||
for (const auto &lib : list) {
|
||||
SafeLoadLibrary(lib);
|
||||
|
@ -48,6 +49,11 @@ void init() {
|
|||
}
|
||||
|
||||
f_SetWindowTheme SetWindowTheme;
|
||||
//f_RefreshImmersiveColorPolicyState RefreshImmersiveColorPolicyState;
|
||||
//f_AllowDarkModeForApp AllowDarkModeForApp;
|
||||
//f_SetPreferredAppMode SetPreferredAppMode;
|
||||
//f_AllowDarkModeForWindow AllowDarkModeForWindow;
|
||||
//f_FlushMenuThemes FlushMenuThemes;
|
||||
f_OpenAs_RunDLL OpenAs_RunDLL;
|
||||
f_SHOpenWithDialog SHOpenWithDialog;
|
||||
f_SHAssocEnumHandlers SHAssocEnumHandlers;
|
||||
|
@ -63,12 +69,14 @@ f_WindowsDeleteString WindowsDeleteString;
|
|||
f_PropVariantToString PropVariantToString;
|
||||
f_PSStringFromPropertyKey PSStringFromPropertyKey;
|
||||
f_DwmIsCompositionEnabled DwmIsCompositionEnabled;
|
||||
f_DwmSetWindowAttribute DwmSetWindowAttribute;
|
||||
f_RmStartSession RmStartSession;
|
||||
f_RmRegisterResources RmRegisterResources;
|
||||
f_RmGetList RmGetList;
|
||||
f_RmShutdown RmShutdown;
|
||||
f_RmEndSession RmEndSession;
|
||||
f_GetProcessMemoryInfo GetProcessMemoryInfo;
|
||||
f_SetWindowCompositionAttribute SetWindowCompositionAttribute;
|
||||
|
||||
void start() {
|
||||
init();
|
||||
|
@ -84,6 +92,21 @@ void start() {
|
|||
|
||||
const auto LibUxTheme = SafeLoadLibrary(u"uxtheme.dll"_q);
|
||||
LoadMethod(LibUxTheme, "SetWindowTheme", SetWindowTheme);
|
||||
//if (IsWindows10OrGreater()) {
|
||||
// static const auto kSystemVersion = QOperatingSystemVersion::current();
|
||||
// static const auto kMinor = kSystemVersion.minorVersion();
|
||||
// static const auto kBuild = kSystemVersion.microVersion();
|
||||
// if (kMinor > 0 || (kMinor == 0 && kBuild >= 17763)) {
|
||||
// if (kBuild < 18362) {
|
||||
// LoadMethod(LibUxTheme, "AllowDarkModeForApp", AllowDarkModeForApp, 135);
|
||||
// } else {
|
||||
// LoadMethod(LibUxTheme, "SetPreferredAppMode", SetPreferredAppMode, 135);
|
||||
// }
|
||||
// LoadMethod(LibUxTheme, "AllowDarkModeForWindow", AllowDarkModeForWindow, 133);
|
||||
// LoadMethod(LibUxTheme, "RefreshImmersiveColorPolicyState", RefreshImmersiveColorPolicyState, 104);
|
||||
// LoadMethod(LibUxTheme, "FlushMenuThemes", FlushMenuThemes, 136);
|
||||
// }
|
||||
//}
|
||||
|
||||
if (IsWindowsVistaOrGreater()) {
|
||||
const auto LibWtsApi32 = SafeLoadLibrary(u"wtsapi32.dll"_q);
|
||||
|
@ -103,6 +126,7 @@ void start() {
|
|||
|
||||
const auto LibDwmApi = SafeLoadLibrary(u"dwmapi.dll"_q);
|
||||
LoadMethod(LibDwmApi, "DwmIsCompositionEnabled", DwmIsCompositionEnabled);
|
||||
LoadMethod(LibDwmApi, "DwmSetWindowAttribute", DwmSetWindowAttribute);
|
||||
|
||||
const auto LibRstrtMgr = SafeLoadLibrary(u"rstrtmgr.dll"_q);
|
||||
LoadMethod(LibRstrtMgr, "RmStartSession", RmStartSession);
|
||||
|
@ -114,6 +138,9 @@ void start() {
|
|||
|
||||
const auto LibPsApi = SafeLoadLibrary(u"psapi.dll"_q);
|
||||
LoadMethod(LibPsApi, "GetProcessMemoryInfo", GetProcessMemoryInfo);
|
||||
|
||||
const auto LibUser32 = SafeLoadLibrary(u"user32.dll"_q);
|
||||
LoadMethod(LibUser32, "SetWindowCompositionAttribute", SetWindowCompositionAttribute);
|
||||
}
|
||||
|
||||
} // namespace Dlls
|
||||
|
|
|
@ -37,6 +37,29 @@ using f_SetWindowTheme = HRESULT(FAR STDAPICALLTYPE*)(
|
|||
LPCWSTR pszSubIdList);
|
||||
extern f_SetWindowTheme SetWindowTheme;
|
||||
|
||||
//using f_RefreshImmersiveColorPolicyState = void(FAR STDAPICALLTYPE*)();
|
||||
//extern f_RefreshImmersiveColorPolicyState RefreshImmersiveColorPolicyState;
|
||||
//
|
||||
//using f_AllowDarkModeForApp = BOOL(FAR STDAPICALLTYPE*)(BOOL allow);
|
||||
//extern f_AllowDarkModeForApp AllowDarkModeForApp;
|
||||
//
|
||||
//enum class PreferredAppMode {
|
||||
// Default,
|
||||
// AllowDark,
|
||||
// ForceDark,
|
||||
// ForceLight,
|
||||
// Max
|
||||
//};
|
||||
//
|
||||
//using f_SetPreferredAppMode = PreferredAppMode(FAR STDAPICALLTYPE*)(PreferredAppMode appMode);
|
||||
//extern f_SetPreferredAppMode SetPreferredAppMode;
|
||||
//
|
||||
//using f_AllowDarkModeForWindow = BOOL(FAR STDAPICALLTYPE*)(HWND hwnd, BOOL allow);
|
||||
//extern f_AllowDarkModeForWindow AllowDarkModeForWindow;
|
||||
//
|
||||
//using f_FlushMenuThemes = void(FAR STDAPICALLTYPE*)();
|
||||
//extern f_FlushMenuThemes FlushMenuThemes;
|
||||
|
||||
// SHELL32.DLL
|
||||
using f_SHAssocEnumHandlers = HRESULT(FAR STDAPICALLTYPE*)(
|
||||
PCWSTR pszExtra,
|
||||
|
@ -128,6 +151,13 @@ using f_DwmIsCompositionEnabled = HRESULT(FAR STDAPICALLTYPE*)(
|
|||
_Out_ BOOL* pfEnabled);
|
||||
extern f_DwmIsCompositionEnabled DwmIsCompositionEnabled;
|
||||
|
||||
using f_DwmSetWindowAttribute = HRESULT(FAR STDAPICALLTYPE*)(
|
||||
HWND hwnd,
|
||||
DWORD dwAttribute,
|
||||
_In_reads_bytes_(cbAttribute) LPCVOID pvAttribute,
|
||||
DWORD cbAttribute);
|
||||
extern f_DwmSetWindowAttribute DwmSetWindowAttribute;
|
||||
|
||||
// RSTRTMGR.DLL
|
||||
|
||||
using f_RmStartSession = DWORD(FAR STDAPICALLTYPE*)(
|
||||
|
@ -172,5 +202,47 @@ using f_GetProcessMemoryInfo = BOOL(FAR STDAPICALLTYPE*)(
|
|||
DWORD cb);
|
||||
extern f_GetProcessMemoryInfo GetProcessMemoryInfo;
|
||||
|
||||
// USER32.DLL
|
||||
|
||||
enum class 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 f_SetWindowCompositionAttribute = BOOL(WINAPI *)(HWND hWnd, WINDOWCOMPOSITIONATTRIBDATA*);
|
||||
extern f_SetWindowCompositionAttribute SetWindowCompositionAttribute;
|
||||
|
||||
} // namespace Dlls
|
||||
} // namespace Platform
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 01ca681ab3aecda8c372b1bb77999f3b7b7a52c6
|
||||
Subproject commit 6a78e454e5bd61133b3d6c9f8d64fbad00f17618
|
Loading…
Add table
Reference in a new issue