From 175403d86df03f109c03c05a66bef92893a16f6b Mon Sep 17 00:00:00 2001 From: moooyo <42196638+moooyo@users.noreply.github.com> Date: Wed, 14 Jan 2026 14:03:32 +0800 Subject: [PATCH] fix: Improve tray icon theming and installer icon handling (#44715) Add "svgs" directory and icon files to installer, ensuring proper install/uninstall and registry registration. Enhance logging in general_settings.cpp for theme-adaptive tray icon config changes. Refactor tray_icon.cpp to improve icon loading robustness, add detailed diagnostics, and ensure fallback to default icon if theme-adaptive icon fails to load. These changes improve error handling and maintainability for tray icon theming. ## Summary of the Pull Request ## PR Checklist - [ ] Closes: #xxx - [ ] **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 ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed Co-authored-by: Yu Leng --- installer/PowerToysSetupVNext/Core.wxs | 12 +++++++ src/runner/general_settings.cpp | 10 ++++++ src/runner/tray_icon.cpp | 47 +++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/installer/PowerToysSetupVNext/Core.wxs b/installer/PowerToysSetupVNext/Core.wxs index a9cf083512..aaf9bb5550 100644 --- a/installer/PowerToysSetupVNext/Core.wxs +++ b/installer/PowerToysSetupVNext/Core.wxs @@ -61,6 +61,16 @@ + + + + + + + + + + @@ -112,6 +122,7 @@ + @@ -120,6 +131,7 @@ + diff --git a/src/runner/general_settings.cpp b/src/runner/general_settings.cpp index 5024e39753..4deb36ec17 100644 --- a/src/runner/general_settings.cpp +++ b/src/runner/general_settings.cpp @@ -367,11 +367,21 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save) if (json::has(general_configs, L"show_theme_adaptive_tray_icon", json::JsonValueType::Boolean)) { bool new_theme_adaptive = general_configs.GetNamedBoolean(L"show_theme_adaptive_tray_icon"); + Logger::info(L"apply_general_settings: show_theme_adaptive_tray_icon current={}, new={}", + show_theme_adaptive_tray_icon, new_theme_adaptive); if (show_theme_adaptive_tray_icon != new_theme_adaptive) { show_theme_adaptive_tray_icon = new_theme_adaptive; set_tray_icon_theme_adaptive(show_theme_adaptive_tray_icon); } + else + { + Logger::info(L"apply_general_settings: show_theme_adaptive_tray_icon unchanged, skipping update"); + } + } + else + { + Logger::warn(L"apply_general_settings: show_theme_adaptive_tray_icon not found in config"); } if (json::has(general_configs, L"ignored_conflict_properties", json::JsonValueType::Object)) diff --git a/src/runner/tray_icon.cpp b/src/runner/tray_icon.cpp index 9cff0c36ff..633c2c1b42 100644 --- a/src/runner/tray_icon.cpp +++ b/src/runner/tray_icon.cpp @@ -273,12 +273,19 @@ static HICON get_icon(Theme theme) { std::wstring icon_path = get_module_folderpath(); icon_path += theme == Theme::Dark ? L"\\svgs\\PowerToysWhite.ico" : L"\\svgs\\PowerToysDark.ico"; - return static_cast(LoadImage(NULL, + Logger::trace(L"get_icon: Loading icon from path: {}", icon_path); + + HICON icon = static_cast(LoadImage(NULL, icon_path.c_str(), IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED)); + if (!icon) + { + Logger::warn(L"get_icon: Failed to load icon from {}, error: {}", icon_path, GetLastError()); + } + return icon; } @@ -374,13 +381,45 @@ void set_tray_icon_visible(bool shouldIconBeVisible) void set_tray_icon_theme_adaptive(bool theme_adaptive) { - theme_adaptive_enabled = theme_adaptive; + Logger::info(L"set_tray_icon_theme_adaptive: Called with theme_adaptive={}, current theme_adaptive_enabled={}", + theme_adaptive, theme_adaptive_enabled); + auto h_instance = reinterpret_cast(&__ImageBase); - HICON const icon = theme_adaptive ? get_icon(theme_listener.AppTheme) : LoadIcon(h_instance, MAKEINTRESOURCE(APPICON)); + HICON icon = nullptr; + + if (theme_adaptive) + { + icon = get_icon(theme_listener.AppTheme); + if (!icon) + { + Logger::warn(L"set_tray_icon_theme_adaptive: Failed to load theme adaptive icon, falling back to default"); + } + } + + // If not requesting adaptive icon, or if adaptive icon failed to load, use default icon + if (!icon) + { + icon = LoadIcon(h_instance, MAKEINTRESOURCE(APPICON)); + if (theme_adaptive && icon) + { + // We requested adaptive but had to fall back, so update the flag + theme_adaptive = false; + Logger::info(L"set_tray_icon_theme_adaptive: Using default icon as fallback"); + } + } + + theme_adaptive_enabled = theme_adaptive; + if (icon) { tray_icon_data.hIcon = icon; - Shell_NotifyIcon(NIM_MODIFY, &tray_icon_data); + BOOL result = Shell_NotifyIcon(NIM_MODIFY, &tray_icon_data); + Logger::info(L"set_tray_icon_theme_adaptive: Icon updated, theme_adaptive_enabled={}, Shell_NotifyIcon result={}", + theme_adaptive_enabled, result); + } + else + { + Logger::error(L"set_tray_icon_theme_adaptive: Failed to load any icon"); } }