mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 13:35:31 +02:00
Runner TrayIcon: Monochrome icon should adapt to windows theme instead of the app theme (#44931)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request As title <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [X] Closes: #44891 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ============ System light + App Light <img width="903" height="239" alt="image" src="https://github.com/user-attachments/assets/581606fb-99b5-4df9-a520-545a0c04676c" /> ============ System Light + App Dark <img width="991" height="239" alt="image" src="https://github.com/user-attachments/assets/822009e9-57cf-452b-b3aa-f1cbc25883f8" /> ============ System Dark + App Light <img width="932" height="236" alt="image" src="https://github.com/user-attachments/assets/98a56d48-31f0-4f75-95a4-8c7dc83c3866" /> ============ System Dark + App Dark <img width="903" height="236" alt="image" src="https://github.com/user-attachments/assets/2500a0d5-6b27-403e-89b4-69b7d3b91e79" /> ============
This commit is contained in:
5
.github/actions/spell-check/expect.txt
vendored
5
.github/actions/spell-check/expect.txt
vendored
@@ -103,7 +103,6 @@ ASYNCWINDOWPLACEMENT
|
|||||||
ASYNCWINDOWPOS
|
ASYNCWINDOWPOS
|
||||||
atl
|
atl
|
||||||
ATRIOX
|
ATRIOX
|
||||||
ATX
|
|
||||||
aumid
|
aumid
|
||||||
authenticode
|
authenticode
|
||||||
AUTOBUDDY
|
AUTOBUDDY
|
||||||
@@ -298,7 +297,6 @@ cpcontrols
|
|||||||
cph
|
cph
|
||||||
cplusplus
|
cplusplus
|
||||||
CPower
|
CPower
|
||||||
cppcoreguidelines
|
|
||||||
cpptools
|
cpptools
|
||||||
cppvsdbg
|
cppvsdbg
|
||||||
cppwinrt
|
cppwinrt
|
||||||
@@ -327,7 +325,7 @@ CURRENTDIR
|
|||||||
CURSORINFO
|
CURSORINFO
|
||||||
cursorpos
|
cursorpos
|
||||||
CURSORSHOWING
|
CURSORSHOWING
|
||||||
CURSORWRAP
|
cursorwrap
|
||||||
customaction
|
customaction
|
||||||
CUSTOMACTIONTEST
|
CUSTOMACTIONTEST
|
||||||
CUSTOMFORMATPLACEHOLDER
|
CUSTOMFORMATPLACEHOLDER
|
||||||
@@ -1760,7 +1758,6 @@ SUBMODULEUPDATE
|
|||||||
subresource
|
subresource
|
||||||
Superbar
|
Superbar
|
||||||
sut
|
sut
|
||||||
swe
|
|
||||||
svchost
|
svchost
|
||||||
SVGIn
|
SVGIn
|
||||||
SVGIO
|
SVGIO
|
||||||
|
|||||||
@@ -16,13 +16,50 @@ DWORD WINAPI _checkTheme(LPVOID lpParam)
|
|||||||
|
|
||||||
void ThemeListener::AddChangedHandler(THEME_HANDLE handle)
|
void ThemeListener::AddChangedHandler(THEME_HANDLE handle)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
handles.push_back(handle);
|
handles.push_back(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeListener::DelChangedHandler(THEME_HANDLE handle)
|
void ThemeListener::DelChangedHandler(THEME_HANDLE handle)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
auto it = std::find(handles.begin(), handles.end(), handle);
|
auto it = std::find(handles.begin(), handles.end(), handle);
|
||||||
handles.erase(it);
|
if (it != handles.end())
|
||||||
|
{
|
||||||
|
handles.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeListener::AddAppThemeChangedHandler(THEME_HANDLE handle)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
|
appThemeHandles.push_back(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeListener::DelAppThemeChangedHandler(THEME_HANDLE handle)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
|
auto it = std::find(appThemeHandles.begin(), appThemeHandles.end(), handle);
|
||||||
|
if (it != appThemeHandles.end())
|
||||||
|
{
|
||||||
|
appThemeHandles.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeListener::AddSystemThemeChangedHandler(THEME_HANDLE handle)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
|
systemThemeHandles.push_back(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeListener::DelSystemThemeChangedHandler(THEME_HANDLE handle)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
|
auto it = std::find(systemThemeHandles.begin(), systemThemeHandles.end(), handle);
|
||||||
|
if (it != systemThemeHandles.end())
|
||||||
|
{
|
||||||
|
systemThemeHandles.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeListener::CheckTheme()
|
void ThemeListener::CheckTheme()
|
||||||
@@ -48,13 +85,51 @@ void ThemeListener::CheckTheme()
|
|||||||
|
|
||||||
WaitForSingleObject(hEvent, INFINITE);
|
WaitForSingleObject(hEvent, INFINITE);
|
||||||
|
|
||||||
auto _theme = ThemeHelpers::GetAppTheme();
|
auto _appTheme = ThemeHelpers::GetAppTheme();
|
||||||
if (AppTheme != _theme)
|
auto _systemTheme = ThemeHelpers::GetSystemTheme();
|
||||||
|
|
||||||
|
bool appThemeChanged = (AppTheme != _appTheme);
|
||||||
|
bool systemThemeChanged = (SystemTheme != _systemTheme);
|
||||||
|
|
||||||
|
if (appThemeChanged || systemThemeChanged)
|
||||||
{
|
{
|
||||||
AppTheme = _theme;
|
AppTheme = _appTheme;
|
||||||
for (int i = 0; i < handles.size(); i++)
|
SystemTheme = _systemTheme;
|
||||||
|
|
||||||
|
// Copy handlers under lock, then invoke outside lock to avoid deadlock
|
||||||
|
std::vector<THEME_HANDLE> handlesCopy;
|
||||||
|
std::vector<THEME_HANDLE> appThemeHandlesCopy;
|
||||||
|
std::vector<THEME_HANDLE> systemThemeHandlesCopy;
|
||||||
|
|
||||||
{
|
{
|
||||||
handles[i]();
|
std::lock_guard<std::mutex> lock(handlesMutex);
|
||||||
|
handlesCopy = handles;
|
||||||
|
if (appThemeChanged)
|
||||||
|
{
|
||||||
|
appThemeHandlesCopy = appThemeHandles;
|
||||||
|
}
|
||||||
|
if (systemThemeChanged)
|
||||||
|
{
|
||||||
|
systemThemeHandlesCopy = systemThemeHandles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call generic handlers (backward compatible)
|
||||||
|
for (const auto& handler : handlesCopy)
|
||||||
|
{
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call app theme specific handlers
|
||||||
|
for (const auto& handler : appThemeHandlesCopy)
|
||||||
|
{
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call system theme specific handlers
|
||||||
|
for (const auto& handler : systemThemeHandlesCopy)
|
||||||
|
{
|
||||||
|
handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
typedef void (*THEME_HANDLE)();
|
typedef void (*THEME_HANDLE)();
|
||||||
DWORD WINAPI _checkTheme(LPVOID lpParam);
|
DWORD WINAPI _checkTheme(LPVOID lpParam);
|
||||||
@@ -14,6 +15,7 @@ public:
|
|||||||
ThemeListener()
|
ThemeListener()
|
||||||
{
|
{
|
||||||
AppTheme = ThemeHelpers::GetAppTheme();
|
AppTheme = ThemeHelpers::GetAppTheme();
|
||||||
|
SystemTheme = ThemeHelpers::GetSystemTheme();
|
||||||
dwThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_checkTheme, this, 0, &dwThreadId);
|
dwThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_checkTheme, this, 0, &dwThreadId);
|
||||||
}
|
}
|
||||||
~ThemeListener()
|
~ThemeListener()
|
||||||
@@ -23,12 +25,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Theme AppTheme;
|
Theme AppTheme;
|
||||||
|
Theme SystemTheme;
|
||||||
void ThemeListener::AddChangedHandler(THEME_HANDLE handle);
|
void ThemeListener::AddChangedHandler(THEME_HANDLE handle);
|
||||||
void ThemeListener::DelChangedHandler(THEME_HANDLE handle);
|
void ThemeListener::DelChangedHandler(THEME_HANDLE handle);
|
||||||
|
void ThemeListener::AddAppThemeChangedHandler(THEME_HANDLE handle);
|
||||||
|
void ThemeListener::DelAppThemeChangedHandler(THEME_HANDLE handle);
|
||||||
|
void ThemeListener::AddSystemThemeChangedHandler(THEME_HANDLE handle);
|
||||||
|
void ThemeListener::DelSystemThemeChangedHandler(THEME_HANDLE handle);
|
||||||
void CheckTheme();
|
void CheckTheme();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE dwThreadHandle;
|
HANDLE dwThreadHandle;
|
||||||
DWORD dwThreadId;
|
DWORD dwThreadId;
|
||||||
std::vector<THEME_HANDLE> handles;
|
std::vector<THEME_HANDLE> handles;
|
||||||
|
std::vector<THEME_HANDLE> appThemeHandles;
|
||||||
|
std::vector<THEME_HANDLE> systemThemeHandles;
|
||||||
|
mutable std::mutex handlesMutex;
|
||||||
};
|
};
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
#include <common/utils/elevation.h>
|
#include <common/utils/elevation.h>
|
||||||
#include <common/Themes/theme_listener.h>
|
#include <common/Themes/theme_listener.h>
|
||||||
|
#include <common/Themes/theme_helpers.h>
|
||||||
#include "bug_report.h"
|
#include "bug_report.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -293,7 +294,7 @@ static void handle_theme_change()
|
|||||||
{
|
{
|
||||||
if (theme_adaptive_enabled)
|
if (theme_adaptive_enabled)
|
||||||
{
|
{
|
||||||
tray_icon_data.hIcon = get_icon(theme_listener.AppTheme);
|
tray_icon_data.hIcon = get_icon(ThemeHelpers::GetSystemTheme());
|
||||||
Shell_NotifyIcon(NIM_MODIFY, &tray_icon_data);
|
Shell_NotifyIcon(NIM_MODIFY, &tray_icon_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,7 +311,7 @@ void start_tray_icon(bool isProcessElevated, bool theme_adaptive)
|
|||||||
{
|
{
|
||||||
theme_adaptive_enabled = theme_adaptive;
|
theme_adaptive_enabled = theme_adaptive;
|
||||||
auto h_instance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
auto h_instance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||||
HICON const icon = theme_adaptive ? get_icon(theme_listener.AppTheme) : LoadIcon(h_instance, MAKEINTRESOURCE(APPICON));
|
HICON const icon = theme_adaptive ? get_icon(ThemeHelpers::GetSystemTheme()) : LoadIcon(h_instance, MAKEINTRESOURCE(APPICON));
|
||||||
if (icon)
|
if (icon)
|
||||||
{
|
{
|
||||||
UINT id_tray_icon = 1;
|
UINT id_tray_icon = 1;
|
||||||
@@ -357,7 +358,7 @@ void start_tray_icon(bool isProcessElevated, bool theme_adaptive)
|
|||||||
ChangeWindowMessageFilterEx(hwnd, WM_COMMAND, MSGFLT_ALLOW, nullptr);
|
ChangeWindowMessageFilterEx(hwnd, WM_COMMAND, MSGFLT_ALLOW, nullptr);
|
||||||
|
|
||||||
tray_icon_created = Shell_NotifyIcon(NIM_ADD, &tray_icon_data) == TRUE;
|
tray_icon_created = Shell_NotifyIcon(NIM_ADD, &tray_icon_data) == TRUE;
|
||||||
theme_listener.AddChangedHandler(&handle_theme_change);
|
theme_listener.AddSystemThemeChangedHandler(&handle_theme_change);
|
||||||
|
|
||||||
// Register callback to update bug report menu item status
|
// Register callback to update bug report menu item status
|
||||||
BugReportManager::instance().register_callback([](bool isRunning) {
|
BugReportManager::instance().register_callback([](bool isRunning) {
|
||||||
@@ -389,7 +390,7 @@ void set_tray_icon_theme_adaptive(bool theme_adaptive)
|
|||||||
|
|
||||||
if (theme_adaptive)
|
if (theme_adaptive)
|
||||||
{
|
{
|
||||||
icon = get_icon(theme_listener.AppTheme);
|
icon = get_icon(ThemeHelpers::GetSystemTheme());
|
||||||
if (!icon)
|
if (!icon)
|
||||||
{
|
{
|
||||||
Logger::warn(L"set_tray_icon_theme_adaptive: Failed to load theme adaptive icon, falling back to default");
|
Logger::warn(L"set_tray_icon_theme_adaptive: Failed to load theme adaptive icon, falling back to default");
|
||||||
|
|||||||
Reference in New Issue
Block a user