2019-09-04 18:26:26 +02:00
|
|
|
#include "pch.h"
|
|
|
|
|
#include "general_settings.h"
|
|
|
|
|
#include "auto_start_helper.h"
|
2025-05-26 05:03:35 -04:00
|
|
|
#include "tray_icon.h"
|
2026-01-07 16:38:09 +08:00
|
|
|
#include "quick_access_host.h"
|
2020-10-22 19:02:59 +03:00
|
|
|
#include "Generated files/resource.h"
|
2025-08-20 09:31:52 +08:00
|
|
|
#include "hotkey_conflict_detector.h"
|
2019-12-17 11:21:46 +03:00
|
|
|
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/SettingsAPI/settings_helpers.h>
|
2019-09-04 18:26:26 +02:00
|
|
|
#include "powertoy_module.h"
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/themes/windows_colors.h>
|
2019-09-04 18:26:26 +02:00
|
|
|
|
2020-02-12 13:03:40 +03:00
|
|
|
#include "trace.h"
|
Super resolution with AI for image resizer (#42331)
<!-- 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
From WinAppSDK 1.8, microsoft announced a new feature AI Imaging. We can
use this ability to enhance our image resizer tools to support scale up
the image resolution by AI.
Doc:
https://learn.microsoft.com/en-us/windows/ai/apis/imaging#what-can-i-do-with-image-super-resolution
Target:
1. Add a new config to control use AI or not.
2. Support model download in image resizer.
3. Auto detect if user's computer support AI feature, if not, do not
show the AI related config.
4. Switch the control part if user enable/disable ai feature.
Demo:
Model not ready, user need to download the model:
<img width="694" height="625" alt="image"
src="https://github.com/user-attachments/assets/8079f047-71fa-4abf-b266-003f74cc5d3e"
/>
Model ready:
<img width="543" height="589" alt="image"
src="https://github.com/user-attachments/assets/952eafc6-0af6-4bea-88d0-0724532f4fac"
/>
User's computer doesn't support AI feature (x86 machine)
<img width="685" height="531" alt="image"
src="https://github.com/user-attachments/assets/522ba300-1505-46a2-a29b-3e8e71c49cdd"
/>
Note: **This feature only support for Arm Windows with the latest
Windows version.**
<!-- Please review the items on the PR checklist before submitting-->
## 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
<!-- 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 (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: moooyo <lengyuchn@gmail.com>
Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
2025-12-15 09:42:49 +08:00
|
|
|
#include "ai_detection.h"
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/utils/elevation.h>
|
|
|
|
|
#include <common/version/version.h>
|
|
|
|
|
#include <common/utils/resources.h>
|
2020-02-12 13:03:40 +03:00
|
|
|
|
2025-09-29 08:53:07 +08:00
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
json::JsonValue create_empty_shortcut_array_value()
|
|
|
|
|
{
|
|
|
|
|
return json::JsonValue::Parse(L"[]");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ensure_ignored_conflict_properties_shape(json::JsonObject& obj)
|
|
|
|
|
{
|
|
|
|
|
if (!json::has(obj, L"ignored_shortcuts", json::JsonValueType::Array))
|
|
|
|
|
{
|
|
|
|
|
obj.SetNamedValue(L"ignored_shortcuts", create_empty_shortcut_array_value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json::JsonObject create_default_ignored_conflict_properties()
|
|
|
|
|
{
|
|
|
|
|
json::JsonObject obj;
|
|
|
|
|
ensure_ignored_conflict_properties_shape(obj);
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
2025-11-05 10:42:24 +01:00
|
|
|
|
|
|
|
|
DashboardSortOrder parse_dashboard_sort_order(const json::JsonObject& obj, DashboardSortOrder fallback)
|
|
|
|
|
{
|
|
|
|
|
if (json::has(obj, L"dashboard_sort_order", json::JsonValueType::Number))
|
|
|
|
|
{
|
|
|
|
|
const auto raw_value = static_cast<int>(obj.GetNamedNumber(L"dashboard_sort_order", static_cast<double>(static_cast<int>(fallback))));
|
|
|
|
|
return raw_value == static_cast<int>(DashboardSortOrder::ByStatus) ? DashboardSortOrder::ByStatus : DashboardSortOrder::Alphabetical;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (json::has(obj, L"dashboard_sort_order", json::JsonValueType::String))
|
|
|
|
|
{
|
|
|
|
|
const auto raw = obj.GetNamedString(L"dashboard_sort_order");
|
|
|
|
|
if (raw == L"ByStatus")
|
|
|
|
|
{
|
|
|
|
|
return DashboardSortOrder::ByStatus;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (raw == L"Alphabetical")
|
|
|
|
|
{
|
|
|
|
|
return DashboardSortOrder::Alphabetical;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fallback;
|
|
|
|
|
}
|
2025-09-29 08:53:07 +08:00
|
|
|
}
|
|
|
|
|
|
2020-04-21 10:30:12 +03:00
|
|
|
// TODO: would be nice to get rid of these globals, since they're basically cached json settings
|
2019-10-28 21:04:37 +01:00
|
|
|
static std::wstring settings_theme = L"system";
|
2025-05-26 05:03:35 -04:00
|
|
|
static bool show_tray_icon = true;
|
2026-01-08 14:23:59 +08:00
|
|
|
static bool show_theme_adaptive_tray_icon = false;
|
2019-12-16 18:36:52 +01:00
|
|
|
static bool run_as_elevated = false;
|
2024-01-19 16:18:05 +01:00
|
|
|
static bool show_new_updates_toast_notification = true;
|
2020-04-21 10:30:12 +03:00
|
|
|
static bool download_updates_automatically = true;
|
2024-01-18 16:18:17 +01:00
|
|
|
static bool show_whats_new_after_updates = true;
|
2023-02-14 18:38:53 -08:00
|
|
|
static bool enable_experimentation = true;
|
2024-01-03 20:22:54 +03:00
|
|
|
static bool enable_warnings_elevated_apps = true;
|
2026-01-07 16:38:09 +08:00
|
|
|
static bool enable_quick_access = true;
|
|
|
|
|
static PowerToysSettings::HotkeyObject quick_access_shortcut;
|
2025-11-05 10:42:24 +01:00
|
|
|
static DashboardSortOrder dashboard_sort_order = DashboardSortOrder::Alphabetical;
|
2025-09-29 08:53:07 +08:00
|
|
|
static json::JsonObject ignored_conflict_properties = create_default_ignored_conflict_properties();
|
2019-10-16 10:21:44 +02:00
|
|
|
|
2020-02-12 13:03:40 +03:00
|
|
|
json::JsonObject GeneralSettings::to_json()
|
|
|
|
|
{
|
|
|
|
|
json::JsonObject result;
|
|
|
|
|
|
2025-09-29 08:53:07 +08:00
|
|
|
auto ignoredProps = ignoredConflictProperties;
|
|
|
|
|
ensure_ignored_conflict_properties_shape(ignoredProps);
|
|
|
|
|
|
2020-02-12 13:03:40 +03:00
|
|
|
result.SetNamedValue(L"startup", json::value(isStartupEnabled));
|
|
|
|
|
if (!startupDisabledReason.empty())
|
|
|
|
|
{
|
|
|
|
|
result.SetNamedValue(L"startup_disabled_reason", json::value(startupDisabledReason));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json::JsonObject enabled;
|
|
|
|
|
for (const auto& [name, isEnabled] : isModulesEnabledMap)
|
|
|
|
|
{
|
|
|
|
|
enabled.SetNamedValue(name, json::value(isEnabled));
|
|
|
|
|
}
|
|
|
|
|
result.SetNamedValue(L"enabled", std::move(enabled));
|
|
|
|
|
|
2025-05-26 05:03:35 -04:00
|
|
|
result.SetNamedValue(L"show_tray_icon", json::value(showSystemTrayIcon));
|
2026-01-08 14:23:59 +08:00
|
|
|
result.SetNamedValue(L"show_theme_adaptive_tray_icon", json::value(showThemeAdaptiveTrayIcon));
|
2020-02-12 13:03:40 +03:00
|
|
|
result.SetNamedValue(L"is_elevated", json::value(isElevated));
|
|
|
|
|
result.SetNamedValue(L"run_elevated", json::value(isRunElevated));
|
2024-01-19 16:18:05 +01:00
|
|
|
result.SetNamedValue(L"show_new_updates_toast_notification", json::value(showNewUpdatesToastNotification));
|
2020-04-21 10:30:12 +03:00
|
|
|
result.SetNamedValue(L"download_updates_automatically", json::value(downloadUpdatesAutomatically));
|
2024-01-18 16:18:17 +01:00
|
|
|
result.SetNamedValue(L"show_whats_new_after_updates", json::value(showWhatsNewAfterUpdates));
|
2023-02-14 18:38:53 -08:00
|
|
|
result.SetNamedValue(L"enable_experimentation", json::value(enableExperimentation));
|
2025-11-05 10:42:24 +01:00
|
|
|
result.SetNamedValue(L"dashboard_sort_order", json::value(static_cast<int>(dashboardSortOrder)));
|
2020-02-18 21:56:34 +02:00
|
|
|
result.SetNamedValue(L"is_admin", json::value(isAdmin));
|
2024-01-03 20:22:54 +03:00
|
|
|
result.SetNamedValue(L"enable_warnings_elevated_apps", json::value(enableWarningsElevatedApps));
|
2026-01-07 16:38:09 +08:00
|
|
|
result.SetNamedValue(L"enable_quick_access", json::value(enableQuickAccess));
|
|
|
|
|
result.SetNamedValue(L"quick_access_shortcut", quickAccessShortcut.get_json());
|
2020-02-12 13:03:40 +03:00
|
|
|
result.SetNamedValue(L"theme", json::value(theme));
|
|
|
|
|
result.SetNamedValue(L"system_theme", json::value(systemTheme));
|
|
|
|
|
result.SetNamedValue(L"powertoys_version", json::value(powerToysVersion));
|
2025-09-29 08:53:07 +08:00
|
|
|
result.SetNamedValue(L"ignored_conflict_properties", json::value(ignoredProps));
|
2020-02-12 13:03:40 +03:00
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
json::JsonObject load_general_settings()
|
|
|
|
|
{
|
|
|
|
|
auto loaded = PTSettingsHelper::load_general_settings();
|
|
|
|
|
settings_theme = loaded.GetNamedString(L"theme", L"system");
|
|
|
|
|
if (settings_theme != L"dark" && settings_theme != L"light")
|
|
|
|
|
{
|
|
|
|
|
settings_theme = L"system";
|
|
|
|
|
}
|
2026-01-08 14:23:59 +08:00
|
|
|
show_tray_icon = loaded.GetNamedBoolean(L"show_tray_icon", true);
|
|
|
|
|
show_theme_adaptive_tray_icon = loaded.GetNamedBoolean(L"show_theme_adaptive_tray_icon", false);
|
2019-12-26 17:26:11 +01:00
|
|
|
run_as_elevated = loaded.GetNamedBoolean(L"run_elevated", false);
|
2024-01-19 16:18:05 +01:00
|
|
|
show_new_updates_toast_notification = loaded.GetNamedBoolean(L"show_new_updates_toast_notification", true);
|
2020-05-14 12:36:27 +03:00
|
|
|
download_updates_automatically = loaded.GetNamedBoolean(L"download_updates_automatically", true) && check_user_is_admin();
|
2024-01-18 16:18:17 +01:00
|
|
|
show_whats_new_after_updates = loaded.GetNamedBoolean(L"show_whats_new_after_updates", true);
|
2024-10-24 22:04:32 +02:00
|
|
|
enable_experimentation = loaded.GetNamedBoolean(L"enable_experimentation", true);
|
2024-01-03 20:22:54 +03:00
|
|
|
enable_warnings_elevated_apps = loaded.GetNamedBoolean(L"enable_warnings_elevated_apps", true);
|
2026-01-07 16:38:09 +08:00
|
|
|
enable_quick_access = loaded.GetNamedBoolean(L"enable_quick_access", true);
|
|
|
|
|
if (json::has(loaded, L"quick_access_shortcut", json::JsonValueType::Object))
|
|
|
|
|
{
|
|
|
|
|
quick_access_shortcut = PowerToysSettings::HotkeyObject::from_json(loaded.GetNamedObject(L"quick_access_shortcut"));
|
|
|
|
|
}
|
2025-11-05 10:42:24 +01:00
|
|
|
dashboard_sort_order = parse_dashboard_sort_order(loaded, dashboard_sort_order);
|
2020-04-21 10:30:12 +03:00
|
|
|
|
2025-09-29 08:53:07 +08:00
|
|
|
if (json::has(loaded, L"ignored_conflict_properties", json::JsonValueType::Object))
|
|
|
|
|
{
|
|
|
|
|
ignored_conflict_properties = loaded.GetNamedObject(L"ignored_conflict_properties");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ignored_conflict_properties = create_default_ignored_conflict_properties();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure_ignored_conflict_properties_shape(ignored_conflict_properties);
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
return loaded;
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-21 10:30:12 +03:00
|
|
|
GeneralSettings get_general_settings()
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2020-04-27 16:02:28 +03:00
|
|
|
const bool is_user_admin = check_user_is_admin();
|
2025-05-26 05:03:35 -04:00
|
|
|
GeneralSettings settings
|
|
|
|
|
{
|
|
|
|
|
.showSystemTrayIcon = show_tray_icon,
|
2026-01-08 14:23:59 +08:00
|
|
|
.showThemeAdaptiveTrayIcon = show_theme_adaptive_tray_icon,
|
2020-02-12 13:03:40 +03:00
|
|
|
.isElevated = is_process_elevated(),
|
|
|
|
|
.isRunElevated = run_as_elevated,
|
2020-04-27 16:02:28 +03:00
|
|
|
.isAdmin = is_user_admin,
|
2024-01-03 20:22:54 +03:00
|
|
|
.enableWarningsElevatedApps = enable_warnings_elevated_apps,
|
2026-01-07 16:38:09 +08:00
|
|
|
.enableQuickAccess = enable_quick_access,
|
|
|
|
|
.quickAccessShortcut = quick_access_shortcut,
|
2024-01-19 16:18:05 +01:00
|
|
|
.showNewUpdatesToastNotification = show_new_updates_toast_notification,
|
2020-04-27 16:02:28 +03:00
|
|
|
.downloadUpdatesAutomatically = download_updates_automatically && is_user_admin,
|
2024-01-18 16:18:17 +01:00
|
|
|
.showWhatsNewAfterUpdates = show_whats_new_after_updates,
|
2023-02-14 18:38:53 -08:00
|
|
|
.enableExperimentation = enable_experimentation,
|
2025-11-05 10:42:24 +01:00
|
|
|
.dashboardSortOrder = dashboard_sort_order,
|
2020-02-12 13:03:40 +03:00
|
|
|
.theme = settings_theme,
|
|
|
|
|
.systemTheme = WindowsColors::is_dark_mode() ? L"dark" : L"light",
|
2025-09-29 08:53:07 +08:00
|
|
|
.powerToysVersion = get_product_version(),
|
|
|
|
|
.ignoredConflictProperties = ignored_conflict_properties
|
2020-02-12 13:03:40 +03:00
|
|
|
};
|
2020-01-29 14:59:51 +03:00
|
|
|
|
2025-09-29 08:53:07 +08:00
|
|
|
ensure_ignored_conflict_properties_shape(settings.ignoredConflictProperties);
|
|
|
|
|
|
2021-06-14 12:55:59 +03:00
|
|
|
settings.isStartupEnabled = is_auto_start_task_active_for_this_user();
|
2019-09-04 18:26:26 +02:00
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
for (auto& [name, powertoy] : modules())
|
|
|
|
|
{
|
2020-03-13 12:55:15 +03:00
|
|
|
settings.isModulesEnabledMap[name] = powertoy->is_enabled();
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2019-10-16 10:21:44 +02:00
|
|
|
|
2020-02-12 13:03:40 +03:00
|
|
|
return settings;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 15:29:46 +08:00
|
|
|
void apply_module_status_update(const json::JsonObject& module_config, bool save)
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"apply_module_status_update: {}", std::wstring{ module_config.ToString() });
|
|
|
|
|
|
|
|
|
|
// Expected format: {"ModuleName": true/false} - only one module per update
|
|
|
|
|
auto iter = module_config.First();
|
|
|
|
|
if (!iter.HasCurrent())
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"apply_module_status_update: Empty module config");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto& element = iter.Current();
|
|
|
|
|
const auto value = element.Value();
|
|
|
|
|
if (value.ValueType() != json::JsonValueType::Boolean)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"apply_module_status_update: Invalid value type for module status");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::wstring name{ element.Key().c_str() };
|
|
|
|
|
if (modules().find(name) == modules().end())
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"apply_module_status_update: Module {} not found", name);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PowertoyModule& powertoy = modules().at(name);
|
|
|
|
|
const bool module_inst_enabled = powertoy->is_enabled();
|
|
|
|
|
bool target_enabled = value.GetBoolean();
|
|
|
|
|
|
|
|
|
|
auto gpo_rule = powertoy->gpo_policy_enabled_configuration();
|
|
|
|
|
if (gpo_rule == powertoys_gpo::gpo_rule_configured_enabled || gpo_rule == powertoys_gpo::gpo_rule_configured_disabled)
|
|
|
|
|
{
|
|
|
|
|
// Apply the GPO Rule.
|
|
|
|
|
target_enabled = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (module_inst_enabled == target_enabled)
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"apply_module_status_update: Module {} already in target state {}", name, target_enabled);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (target_enabled)
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"apply_module_status_update: Enabling powertoy {}", name);
|
|
|
|
|
powertoy->enable();
|
|
|
|
|
auto& hkmng = HotkeyConflictDetector::HotkeyConflictManager::GetInstance();
|
|
|
|
|
hkmng.EnableHotkeyByModule(name);
|
|
|
|
|
|
|
|
|
|
// Trigger AI capability detection when ImageResizer is enabled
|
|
|
|
|
if (name == L"Image Resizer")
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"ImageResizer enabled, triggering AI capability detection");
|
|
|
|
|
DetectAiCapabilitiesAsync(true); // Skip settings check since we know it's being enabled
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"apply_module_status_update: Disabling powertoy {}", name);
|
|
|
|
|
powertoy->disable();
|
|
|
|
|
auto& hkmng = HotkeyConflictDetector::HotkeyConflictManager::GetInstance();
|
|
|
|
|
hkmng.DisableHotkeyByModule(name);
|
|
|
|
|
}
|
|
|
|
|
// Sync the hotkey state with the module state, so it can be removed for disabled modules.
|
|
|
|
|
powertoy.UpdateHotkeyEx();
|
|
|
|
|
|
|
|
|
|
if (save)
|
|
|
|
|
{
|
|
|
|
|
// Load existing settings and only update the specific module's enabled state
|
|
|
|
|
json::JsonObject current_settings = PTSettingsHelper::load_general_settings();
|
|
|
|
|
|
|
|
|
|
json::JsonObject enabled;
|
|
|
|
|
if (current_settings.HasKey(L"enabled"))
|
|
|
|
|
{
|
|
|
|
|
enabled = current_settings.GetNamedObject(L"enabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if the saved state is different from the requested state
|
|
|
|
|
bool current_saved = enabled.HasKey(name) ? enabled.GetNamedBoolean(name, true) : true;
|
|
|
|
|
|
|
|
|
|
if (current_saved != target_enabled)
|
|
|
|
|
{
|
|
|
|
|
// Update only this module's enabled state
|
|
|
|
|
enabled.SetNamedValue(name, json::value(target_enabled));
|
|
|
|
|
current_settings.SetNamedValue(L"enabled", enabled);
|
|
|
|
|
|
|
|
|
|
PTSettingsHelper::save_general_settings(current_settings);
|
|
|
|
|
|
|
|
|
|
GeneralSettings settings_for_trace = get_general_settings();
|
|
|
|
|
Trace::SettingsChanged(settings_for_trace);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-26 14:46:47 -07:00
|
|
|
void apply_general_settings(const json::JsonObject& general_configs, bool save)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2026-01-07 16:38:09 +08:00
|
|
|
std::wstring old_settings_json_string;
|
|
|
|
|
if (save)
|
|
|
|
|
{
|
|
|
|
|
old_settings_json_string = get_general_settings().to_json().Stringify().c_str();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info(L"apply_general_settings: {}", std::wstring{ general_configs.ToString() });
|
2020-03-17 11:04:45 +01:00
|
|
|
run_as_elevated = general_configs.GetNamedBoolean(L"run_elevated", false);
|
|
|
|
|
|
2024-01-03 20:22:54 +03:00
|
|
|
enable_warnings_elevated_apps = general_configs.GetNamedBoolean(L"enable_warnings_elevated_apps", true);
|
|
|
|
|
|
2026-01-07 16:38:09 +08:00
|
|
|
bool new_enable_quick_access = general_configs.GetNamedBoolean(L"enable_quick_access", true);
|
|
|
|
|
Logger::info(L"apply_general_settings: enable_quick_access={}, new_enable_quick_access={}", enable_quick_access, new_enable_quick_access);
|
|
|
|
|
|
|
|
|
|
PowerToysSettings::HotkeyObject new_quick_access_shortcut;
|
|
|
|
|
if (json::has(general_configs, L"quick_access_shortcut", json::JsonValueType::Object))
|
|
|
|
|
{
|
|
|
|
|
new_quick_access_shortcut = PowerToysSettings::HotkeyObject::from_json(general_configs.GetNamedObject(L"quick_access_shortcut"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto hotkey_equals = [](const PowerToysSettings::HotkeyObject& a, const PowerToysSettings::HotkeyObject& b) {
|
|
|
|
|
return a.get_code() == b.get_code() &&
|
|
|
|
|
a.get_modifiers() == b.get_modifiers();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (enable_quick_access != new_enable_quick_access || !hotkey_equals(quick_access_shortcut, new_quick_access_shortcut))
|
|
|
|
|
{
|
|
|
|
|
enable_quick_access = new_enable_quick_access;
|
|
|
|
|
quick_access_shortcut = new_quick_access_shortcut;
|
|
|
|
|
|
|
|
|
|
if (enable_quick_access)
|
|
|
|
|
{
|
|
|
|
|
QuickAccessHost::start();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
QuickAccessHost::stop();
|
|
|
|
|
}
|
|
|
|
|
update_quick_access_hotkey(enable_quick_access, quick_access_shortcut);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-19 16:18:05 +01:00
|
|
|
show_new_updates_toast_notification = general_configs.GetNamedBoolean(L"show_new_updates_toast_notification", true);
|
|
|
|
|
|
2020-04-21 10:30:12 +03:00
|
|
|
download_updates_automatically = general_configs.GetNamedBoolean(L"download_updates_automatically", true);
|
2024-01-18 16:18:17 +01:00
|
|
|
show_whats_new_after_updates = general_configs.GetNamedBoolean(L"show_whats_new_after_updates", true);
|
2020-04-21 10:30:12 +03:00
|
|
|
|
2023-02-14 18:38:53 -08:00
|
|
|
enable_experimentation = general_configs.GetNamedBoolean(L"enable_experimentation", true);
|
2025-11-05 10:42:24 +01:00
|
|
|
dashboard_sort_order = parse_dashboard_sort_order(general_configs, dashboard_sort_order);
|
2023-02-14 18:38:53 -08:00
|
|
|
|
2025-02-12 18:49:49 +00:00
|
|
|
// apply_general_settings is called by the runner's WinMain, so we can just force the run at startup gpo rule here.
|
|
|
|
|
auto gpo_run_as_startup = powertoys_gpo::getConfiguredRunAtStartupValue();
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean))
|
|
|
|
|
{
|
2025-02-12 18:49:49 +00:00
|
|
|
bool startup = general_configs.GetNamedBoolean(L"startup");
|
|
|
|
|
|
|
|
|
|
if (gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_enabled)
|
|
|
|
|
{
|
|
|
|
|
startup = true;
|
|
|
|
|
}
|
|
|
|
|
else if (gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_disabled)
|
|
|
|
|
{
|
|
|
|
|
startup = false;
|
|
|
|
|
}
|
2021-12-02 09:09:16 +01:00
|
|
|
|
2022-03-25 13:04:29 +03:00
|
|
|
if (startup)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2021-06-14 12:55:59 +03:00
|
|
|
if (is_process_elevated())
|
|
|
|
|
{
|
|
|
|
|
delete_auto_start_task_for_this_user();
|
2023-08-09 10:23:54 +02:00
|
|
|
create_auto_start_task_for_this_user(run_as_elevated);
|
2021-06-14 12:55:59 +03:00
|
|
|
}
|
|
|
|
|
else
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2021-06-14 12:55:59 +03:00
|
|
|
if (!is_auto_start_task_active_for_this_user())
|
2020-01-31 20:35:21 +03:00
|
|
|
{
|
2020-03-17 11:04:45 +01:00
|
|
|
delete_auto_start_task_for_this_user();
|
2021-06-14 12:55:59 +03:00
|
|
|
create_auto_start_task_for_this_user(false);
|
|
|
|
|
|
|
|
|
|
run_as_elevated = false;
|
2020-01-31 20:35:21 +03:00
|
|
|
}
|
2021-06-14 12:55:59 +03:00
|
|
|
else if (!general_configs.GetNamedBoolean(L"run_elevated", false))
|
2020-01-31 20:35:21 +03:00
|
|
|
{
|
2021-06-14 12:55:59 +03:00
|
|
|
delete_auto_start_task_for_this_user();
|
|
|
|
|
create_auto_start_task_for_this_user(false);
|
2020-01-31 20:35:21 +03:00
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2021-06-14 12:55:59 +03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete_auto_start_task_for_this_user();
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
2023-08-09 10:23:54 +02:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
delete_auto_start_task_for_this_user();
|
Runner: Remove "Show Tray Icon" menu in tray icon (#40190)
<!-- 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
"Show Tray Icon" when you click tray icon has not sense.
If it's visible, show that has no effect,
if it's not, you can't make it visible by click it.
Remove the menu for that
This impl is just not showing the menu item, if open for the choice that
show "hide the tray icon" here
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] **Closes:** #xxx
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **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
Locally tested
2025-06-25 17:31:56 +08:00
|
|
|
if (gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_enabled || gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_not_configured)
|
|
|
|
|
{
|
2025-02-12 18:49:49 +00:00
|
|
|
create_auto_start_task_for_this_user(run_as_elevated);
|
|
|
|
|
}
|
2023-08-09 10:23:54 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
if (json::has(general_configs, L"enabled"))
|
|
|
|
|
{
|
|
|
|
|
for (const auto& enabled_element : general_configs.GetNamedObject(L"enabled"))
|
|
|
|
|
{
|
|
|
|
|
const auto value = enabled_element.Value();
|
|
|
|
|
if (value.ValueType() != json::JsonValueType::Boolean)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const std::wstring name{ enabled_element.Key().c_str() };
|
|
|
|
|
const bool found = modules().find(name) != modules().end();
|
|
|
|
|
if (!found)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-02-02 12:17:37 +00:00
|
|
|
PowertoyModule& powertoy = modules().at(name);
|
|
|
|
|
const bool module_inst_enabled = powertoy->is_enabled();
|
2022-10-26 14:02:31 +01:00
|
|
|
bool target_enabled = value.GetBoolean();
|
|
|
|
|
|
|
|
|
|
auto gpo_rule = powertoy->gpo_policy_enabled_configuration();
|
|
|
|
|
if (gpo_rule == powertoys_gpo::gpo_rule_configured_enabled || gpo_rule == powertoys_gpo::gpo_rule_configured_disabled)
|
|
|
|
|
{
|
|
|
|
|
// Apply the GPO Rule.
|
|
|
|
|
target_enabled = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
if (module_inst_enabled == target_enabled)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (target_enabled)
|
|
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info(L"apply_general_settings: Enabling powertoy {}", name);
|
2022-02-02 12:17:37 +00:00
|
|
|
powertoy->enable();
|
2025-08-20 09:31:52 +08:00
|
|
|
auto& hkmng = HotkeyConflictDetector::HotkeyConflictManager::GetInstance();
|
|
|
|
|
hkmng.EnableHotkeyByModule(name);
|
Super resolution with AI for image resizer (#42331)
<!-- 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
From WinAppSDK 1.8, microsoft announced a new feature AI Imaging. We can
use this ability to enhance our image resizer tools to support scale up
the image resolution by AI.
Doc:
https://learn.microsoft.com/en-us/windows/ai/apis/imaging#what-can-i-do-with-image-super-resolution
Target:
1. Add a new config to control use AI or not.
2. Support model download in image resizer.
3. Auto detect if user's computer support AI feature, if not, do not
show the AI related config.
4. Switch the control part if user enable/disable ai feature.
Demo:
Model not ready, user need to download the model:
<img width="694" height="625" alt="image"
src="https://github.com/user-attachments/assets/8079f047-71fa-4abf-b266-003f74cc5d3e"
/>
Model ready:
<img width="543" height="589" alt="image"
src="https://github.com/user-attachments/assets/952eafc6-0af6-4bea-88d0-0724532f4fac"
/>
User's computer doesn't support AI feature (x86 machine)
<img width="685" height="531" alt="image"
src="https://github.com/user-attachments/assets/522ba300-1505-46a2-a29b-3e8e71c49cdd"
/>
Note: **This feature only support for Arm Windows with the latest
Windows version.**
<!-- Please review the items on the PR checklist before submitting-->
## 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
<!-- 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 (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: moooyo <lengyuchn@gmail.com>
Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
2025-12-15 09:42:49 +08:00
|
|
|
|
|
|
|
|
// Trigger AI capability detection when ImageResizer is enabled
|
|
|
|
|
if (name == L"Image Resizer")
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"ImageResizer enabled, triggering AI capability detection");
|
|
|
|
|
DetectAiCapabilitiesAsync(true); // Skip settings check since we know it's being enabled
|
|
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info(L"apply_general_settings: Disabling powertoy {}", name);
|
2022-02-02 12:17:37 +00:00
|
|
|
powertoy->disable();
|
2025-08-20 09:31:52 +08:00
|
|
|
auto& hkmng = HotkeyConflictDetector::HotkeyConflictManager::GetInstance();
|
|
|
|
|
hkmng.DisableHotkeyByModule(name);
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2022-02-02 12:17:37 +00:00
|
|
|
// Sync the hotkey state with the module state, so it can be removed for disabled modules.
|
|
|
|
|
powertoy.UpdateHotkeyEx();
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
2020-03-17 11:04:45 +01:00
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
if (json::has(general_configs, L"theme", json::JsonValueType::String))
|
|
|
|
|
{
|
|
|
|
|
settings_theme = general_configs.GetNamedString(L"theme");
|
|
|
|
|
}
|
2020-02-12 13:03:40 +03:00
|
|
|
|
2025-05-26 05:03:35 -04:00
|
|
|
if (json::has(general_configs, L"show_tray_icon", json::JsonValueType::Boolean))
|
|
|
|
|
{
|
|
|
|
|
show_tray_icon = general_configs.GetNamedBoolean(L"show_tray_icon");
|
|
|
|
|
set_tray_icon_visible(show_tray_icon);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-08 14:23:59 +08:00
|
|
|
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");
|
2026-01-14 14:03:32 +08:00
|
|
|
Logger::info(L"apply_general_settings: show_theme_adaptive_tray_icon current={}, new={}",
|
|
|
|
|
show_theme_adaptive_tray_icon, new_theme_adaptive);
|
2026-01-08 14:23:59 +08:00
|
|
|
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);
|
|
|
|
|
}
|
2026-01-14 14:03:32 +08:00
|
|
|
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");
|
2026-01-08 14:23:59 +08:00
|
|
|
}
|
|
|
|
|
|
2025-09-29 08:53:07 +08:00
|
|
|
if (json::has(general_configs, L"ignored_conflict_properties", json::JsonValueType::Object))
|
|
|
|
|
{
|
|
|
|
|
ignored_conflict_properties = general_configs.GetNamedObject(L"ignored_conflict_properties");
|
|
|
|
|
ensure_ignored_conflict_properties_shape(ignored_conflict_properties);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-26 14:46:47 -07:00
|
|
|
if (save)
|
|
|
|
|
{
|
|
|
|
|
GeneralSettings save_settings = get_general_settings();
|
2026-01-07 16:38:09 +08:00
|
|
|
std::wstring new_settings_json_string = save_settings.to_json().Stringify().c_str();
|
|
|
|
|
if (old_settings_json_string != new_settings_json_string)
|
|
|
|
|
{
|
|
|
|
|
PTSettingsHelper::save_general_settings(save_settings.to_json());
|
|
|
|
|
Trace::SettingsChanged(save_settings);
|
|
|
|
|
}
|
2020-06-26 14:46:47 -07:00
|
|
|
}
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
2021-12-07 05:50:04 -08:00
|
|
|
void start_enabled_powertoys()
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2020-04-02 21:39:40 +03:00
|
|
|
std::unordered_set<std::wstring> powertoys_to_disable;
|
2022-10-26 14:02:31 +01:00
|
|
|
std::unordered_map<std::wstring, powertoys_gpo::gpo_rule_configured_t> powertoys_gpo_configuration;
|
|
|
|
|
// Take into account default values supplied by modules themselves and gpo configurations
|
2021-12-07 05:50:04 -08:00
|
|
|
for (auto& [name, powertoy] : modules())
|
|
|
|
|
{
|
2022-10-26 14:02:31 +01:00
|
|
|
auto gpo_rule = powertoy->gpo_policy_enabled_configuration();
|
|
|
|
|
powertoys_gpo_configuration[name] = gpo_rule;
|
|
|
|
|
if (gpo_rule == powertoys_gpo::gpo_rule_configured_unavailable)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"start_enabled_powertoys: couldn't read the gpo rule for Powertoy {}", name);
|
|
|
|
|
}
|
|
|
|
|
if (gpo_rule == powertoys_gpo::gpo_rule_configured_wrong_value)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"start_enabled_powertoys: gpo rule for Powertoy {} is set to an unknown value", name);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-07 05:50:04 -08:00
|
|
|
if (!powertoy->is_enabled_by_default())
|
|
|
|
|
powertoys_to_disable.emplace(name);
|
|
|
|
|
}
|
2019-09-04 18:26:26 +02:00
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
json::JsonObject general_settings;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
general_settings = load_general_settings();
|
2020-03-19 09:21:10 +01:00
|
|
|
if (general_settings.HasKey(L"enabled"))
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2020-03-19 09:21:10 +01:00
|
|
|
json::JsonObject enabled = general_settings.GetNamedObject(L"enabled");
|
2020-04-02 21:39:40 +03:00
|
|
|
for (const auto& disabled_element : enabled)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2021-12-07 05:50:04 -08:00
|
|
|
std::wstring disable_module_name{ static_cast<std::wstring_view>(disabled_element.Key()) };
|
2022-10-26 14:02:31 +01:00
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
if (powertoys_gpo_configuration.find(disable_module_name) != powertoys_gpo_configuration.end() && (powertoys_gpo_configuration[disable_module_name] == powertoys_gpo::gpo_rule_configured_enabled || powertoys_gpo_configuration[disable_module_name] == powertoys_gpo::gpo_rule_configured_disabled))
|
2022-10-26 14:02:31 +01:00
|
|
|
{
|
|
|
|
|
// If gpo forces the enabled setting, no need to check the setting for this PowerToy. It will be applied later on this function.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-07 05:50:04 -08:00
|
|
|
// Disable explicitly disabled modules
|
2020-04-02 21:39:40 +03:00
|
|
|
if (!disabled_element.Value().GetBoolean())
|
2020-03-19 09:21:10 +01:00
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info(L"start_enabled_powertoys: Powertoy {} explicitly disabled", disable_module_name);
|
2021-12-07 05:50:04 -08:00
|
|
|
powertoys_to_disable.emplace(std::move(disable_module_name));
|
|
|
|
|
}
|
|
|
|
|
// If module was scheduled for disable, but it's enabled in the settings - override default value
|
|
|
|
|
else if (auto it = powertoys_to_disable.find(disable_module_name); it != end(powertoys_to_disable))
|
|
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info(L"start_enabled_powertoys: Overriding default enabled value for {} powertoy", disable_module_name);
|
2021-12-07 05:50:04 -08:00
|
|
|
powertoys_to_disable.erase(it);
|
2020-03-19 09:21:10 +01:00
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-21 10:30:12 +03:00
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-04-02 21:39:40 +03:00
|
|
|
|
2021-12-07 05:50:04 -08:00
|
|
|
for (auto& [name, powertoy] : modules())
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2022-10-26 14:02:31 +01:00
|
|
|
bool should_powertoy_be_enabled = true;
|
|
|
|
|
|
|
|
|
|
auto gpo_rule = powertoys_gpo_configuration.find(name) != powertoys_gpo_configuration.end() ? powertoys_gpo_configuration[name] : powertoys_gpo::gpo_rule_configured_not_configured;
|
|
|
|
|
|
|
|
|
|
if (gpo_rule == powertoys_gpo::gpo_rule_configured_enabled || gpo_rule == powertoys_gpo::gpo_rule_configured_disabled)
|
|
|
|
|
{
|
|
|
|
|
// Apply the GPO Rule.
|
|
|
|
|
should_powertoy_be_enabled = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled;
|
|
|
|
|
Logger::info(L"start_enabled_powertoys: GPO sets the enabled state for {} powertoy as {}", name, should_powertoy_be_enabled);
|
|
|
|
|
}
|
|
|
|
|
else if (powertoys_to_disable.contains(name))
|
|
|
|
|
{
|
|
|
|
|
// Apply the settings or default information provided by the PowerToy on first run.
|
|
|
|
|
should_powertoy_be_enabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (should_powertoy_be_enabled)
|
2020-04-02 21:39:40 +03:00
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info(L"start_enabled_powertoys: Enabling powertoy {}", name);
|
2020-04-02 21:39:40 +03:00
|
|
|
powertoy->enable();
|
2025-08-20 09:31:52 +08:00
|
|
|
auto& hkmng = HotkeyConflictDetector::HotkeyConflictManager::GetInstance();
|
|
|
|
|
hkmng.EnableHotkeyByModule(name);
|
2022-02-02 12:17:37 +00:00
|
|
|
powertoy.UpdateHotkeyEx();
|
2020-04-02 21:39:40 +03:00
|
|
|
}
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
2026-01-07 16:38:09 +08:00
|
|
|
|
|
|
|
|
|