mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-11 05:52:19 +02:00
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. <!-- 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 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] 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 Co-authored-by: Yu Leng <yuleng@microsoft.com>
This commit is contained in:
@@ -61,6 +61,16 @@
|
||||
</RegistryKey>
|
||||
<File Source="$(var.RepoDir)\Notice.md" Id="Notice.md" />
|
||||
</Component>
|
||||
<Directory Id="SvgsFolder" Name="svgs">
|
||||
<Component Id="svgs_icons" Guid="A9B7C5D3-E1F2-4A6B-8C9D-0E1F2A3B4C5D" Bitness="always64">
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="svgs_icons" Value="" KeyPath="yes" />
|
||||
</RegistryKey>
|
||||
<File Id="icon.ico" Source="$(var.BinDir)svgs\icon.ico" />
|
||||
<File Id="PowerToysWhite.ico" Source="$(var.BinDir)svgs\PowerToysWhite.ico" />
|
||||
<File Id="PowerToysDark.ico" Source="$(var.BinDir)svgs\PowerToysDark.ico" />
|
||||
</Component>
|
||||
</Directory>
|
||||
</DirectoryRef>
|
||||
|
||||
<?if $(var.PerUser) = "true" ?>
|
||||
@@ -112,6 +122,7 @@
|
||||
<RemoveFolder Id="RemoveBaseApplicationsAssetsFolder" Directory="BaseApplicationsAssetsFolder" On="uninstall" />
|
||||
<RemoveFolder Id="RemoveWinUI3AppsInstallFolder" Directory="WinUI3AppsInstallFolder" On="uninstall" />
|
||||
<RemoveFolder Id="RemoveWinUI3AppsAssetsFolder" Directory="WinUI3AppsAssetsFolder" On="uninstall" />
|
||||
<RemoveFolder Id="RemoveSvgsFolder" Directory="SvgsFolder" On="uninstall" />
|
||||
<RemoveFolder Id="RemoveINSTALLFOLDER" Directory="INSTALLFOLDER" On="uninstall" />
|
||||
</Component>
|
||||
<ComponentRef Id="powertoys_exe" />
|
||||
@@ -120,6 +131,7 @@
|
||||
<ComponentRef Id="powertoys_toast_clsid" />
|
||||
<ComponentRef Id="License_rtf" />
|
||||
<ComponentRef Id="Notice_md" />
|
||||
<ComponentRef Id="svgs_icons" />
|
||||
<ComponentRef Id="DesktopShortcut" />
|
||||
<?if $(var.PerUser) = "true" ?>
|
||||
<ComponentRef Id="powertoys_env_path_user" />
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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<HICON>(LoadImage(NULL,
|
||||
Logger::trace(L"get_icon: Loading icon from path: {}", icon_path);
|
||||
|
||||
HICON icon = static_cast<HICON>(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<HINSTANCE>(&__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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user