2019-09-05 00:26:26 +08:00
|
|
|
#include "pch.h"
|
|
|
|
#include "general_settings.h"
|
|
|
|
#include "auto_start_helper.h"
|
2020-10-23 00:02:59 +08:00
|
|
|
#include "Generated files/resource.h"
|
2019-12-17 16:21:46 +08:00
|
|
|
|
2020-12-15 20:16:09 +08:00
|
|
|
#include <common/SettingsAPI/settings_helpers.h>
|
2019-09-05 00:26:26 +08:00
|
|
|
#include "powertoy_module.h"
|
2020-12-15 20:16:09 +08:00
|
|
|
#include <common/themes/windows_colors.h>
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-02-12 18:03:40 +08:00
|
|
|
#include "trace.h"
|
2020-12-15 20:16:09 +08:00
|
|
|
#include <common/utils/elevation.h>
|
|
|
|
#include <common/version/version.h>
|
|
|
|
#include <common/utils/resources.h>
|
2020-02-12 18:03:40 +08:00
|
|
|
|
2020-04-21 15:30:12 +08:00
|
|
|
// TODO: would be nice to get rid of these globals, since they're basically cached json settings
|
2019-10-29 04:04:37 +08:00
|
|
|
static std::wstring settings_theme = L"system";
|
2019-12-17 01:36:52 +08:00
|
|
|
static bool run_as_elevated = false;
|
2020-04-21 15:30:12 +08:00
|
|
|
static bool download_updates_automatically = true;
|
2019-10-16 16:21:44 +08:00
|
|
|
|
2020-02-12 18:03:40 +08:00
|
|
|
json::JsonObject GeneralSettings::to_json()
|
|
|
|
{
|
|
|
|
json::JsonObject result;
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
result.SetNamedValue(L"is_elevated", json::value(isElevated));
|
|
|
|
result.SetNamedValue(L"run_elevated", json::value(isRunElevated));
|
2020-04-21 15:30:12 +08:00
|
|
|
result.SetNamedValue(L"download_updates_automatically", json::value(downloadUpdatesAutomatically));
|
2020-02-19 03:56:34 +08:00
|
|
|
result.SetNamedValue(L"is_admin", json::value(isAdmin));
|
2020-02-12 18:03:40 +08:00
|
|
|
result.SetNamedValue(L"theme", json::value(theme));
|
|
|
|
result.SetNamedValue(L"system_theme", json::value(systemTheme));
|
|
|
|
result.SetNamedValue(L"powertoys_version", json::value(powerToysVersion));
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-12-27 00:26:11 +08: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";
|
|
|
|
}
|
|
|
|
run_as_elevated = loaded.GetNamedBoolean(L"run_elevated", false);
|
2020-05-14 17:36:27 +08:00
|
|
|
download_updates_automatically = loaded.GetNamedBoolean(L"download_updates_automatically", true) && check_user_is_admin();
|
2020-04-21 15:30:12 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
return loaded;
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
|
|
|
|
2020-04-21 15:30:12 +08:00
|
|
|
GeneralSettings get_general_settings()
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-04-27 21:02:28 +08:00
|
|
|
const bool is_user_admin = check_user_is_admin();
|
2020-02-12 18:03:40 +08:00
|
|
|
GeneralSettings settings{
|
|
|
|
.isElevated = is_process_elevated(),
|
|
|
|
.isRunElevated = run_as_elevated,
|
2020-04-27 21:02:28 +08:00
|
|
|
.isAdmin = is_user_admin,
|
|
|
|
.downloadUpdatesAutomatically = download_updates_automatically && is_user_admin,
|
2020-02-12 18:03:40 +08:00
|
|
|
.theme = settings_theme,
|
|
|
|
.systemTheme = WindowsColors::is_dark_mode() ? L"dark" : L"light",
|
2020-04-21 15:30:12 +08:00
|
|
|
.powerToysVersion = get_product_version()
|
2020-02-12 18:03:40 +08:00
|
|
|
};
|
2020-01-29 19:59:51 +08:00
|
|
|
|
2021-06-14 17:55:59 +08:00
|
|
|
settings.isStartupEnabled = is_auto_start_task_active_for_this_user();
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
for (auto& [name, powertoy] : modules())
|
|
|
|
{
|
2020-03-13 17:55:15 +08:00
|
|
|
settings.isModulesEnabledMap[name] = powertoy->is_enabled();
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
2019-10-16 16:21:44 +08:00
|
|
|
|
2020-02-12 18:03:40 +08:00
|
|
|
return settings;
|
|
|
|
}
|
|
|
|
|
2020-06-27 05:46:47 +08:00
|
|
|
void apply_general_settings(const json::JsonObject& general_configs, bool save)
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2022-02-22 19:50:20 +08:00
|
|
|
Logger::info(L"apply_general_settings: {}", std::wstring{ general_configs.ToString() });
|
2020-03-17 18:04:45 +08:00
|
|
|
run_as_elevated = general_configs.GetNamedBoolean(L"run_elevated", false);
|
|
|
|
|
2020-04-21 15:30:12 +08:00
|
|
|
download_updates_automatically = general_configs.GetNamedBoolean(L"download_updates_automatically", true);
|
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean))
|
|
|
|
{
|
|
|
|
const bool startup = general_configs.GetNamedBoolean(L"startup");
|
2021-12-02 16:09:16 +08:00
|
|
|
|
2022-03-25 18:04:29 +08:00
|
|
|
if (startup)
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2021-06-14 17:55:59 +08:00
|
|
|
if (is_process_elevated())
|
|
|
|
{
|
|
|
|
delete_auto_start_task_for_this_user();
|
|
|
|
create_auto_start_task_for_this_user(general_configs.GetNamedBoolean(L"run_elevated", false));
|
|
|
|
}
|
|
|
|
else
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2021-06-14 17:55:59 +08:00
|
|
|
if (!is_auto_start_task_active_for_this_user())
|
2020-02-01 01:35:21 +08:00
|
|
|
{
|
2020-03-17 18:04:45 +08:00
|
|
|
delete_auto_start_task_for_this_user();
|
2021-06-14 17:55:59 +08:00
|
|
|
create_auto_start_task_for_this_user(false);
|
|
|
|
|
|
|
|
run_as_elevated = false;
|
2020-02-01 01:35:21 +08:00
|
|
|
}
|
2021-06-14 17:55:59 +08:00
|
|
|
else if (!general_configs.GetNamedBoolean(L"run_elevated", false))
|
2020-02-01 01:35:21 +08:00
|
|
|
{
|
2021-06-14 17:55:59 +08:00
|
|
|
delete_auto_start_task_for_this_user();
|
|
|
|
create_auto_start_task_for_this_user(false);
|
2020-02-01 01:35:21 +08:00
|
|
|
}
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
2021-06-14 17:55:59 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete_auto_start_task_for_this_user();
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
2019-12-27 00:26:11 +08: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 20:17:37 +08:00
|
|
|
PowertoyModule& powertoy = modules().at(name);
|
|
|
|
const bool module_inst_enabled = powertoy->is_enabled();
|
2019-12-27 00:26:11 +08:00
|
|
|
const bool target_enabled = value.GetBoolean();
|
|
|
|
if (module_inst_enabled == target_enabled)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (target_enabled)
|
|
|
|
{
|
2022-02-22 19:50:20 +08:00
|
|
|
Logger::info(L"apply_general_settings: Enabling powertoy {}", name);
|
2022-02-02 20:17:37 +08:00
|
|
|
powertoy->enable();
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-22 19:50:20 +08:00
|
|
|
Logger::info(L"apply_general_settings: Disabling powertoy {}", name);
|
2022-02-02 20:17:37 +08:00
|
|
|
powertoy->disable();
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
2022-02-02 20:17:37 +08:00
|
|
|
// Sync the hotkey state with the module state, so it can be removed for disabled modules.
|
|
|
|
powertoy.UpdateHotkeyEx();
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
2020-03-17 18:04:45 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
if (json::has(general_configs, L"theme", json::JsonValueType::String))
|
|
|
|
{
|
|
|
|
settings_theme = general_configs.GetNamedString(L"theme");
|
|
|
|
}
|
2020-02-12 18:03:40 +08:00
|
|
|
|
2020-06-27 05:46:47 +08:00
|
|
|
if (save)
|
|
|
|
{
|
|
|
|
GeneralSettings save_settings = get_general_settings();
|
|
|
|
PTSettingsHelper::save_general_settings(save_settings.to_json());
|
|
|
|
Trace::SettingsChanged(save_settings);
|
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
|
|
|
|
2021-12-07 21:50:04 +08:00
|
|
|
void start_enabled_powertoys()
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-04-03 02:39:40 +08:00
|
|
|
std::unordered_set<std::wstring> powertoys_to_disable;
|
2021-12-07 21:50:04 +08:00
|
|
|
// Take into account default values supplied by modules themselves
|
|
|
|
for (auto& [name, powertoy] : modules())
|
|
|
|
{
|
|
|
|
if (!powertoy->is_enabled_by_default())
|
|
|
|
powertoys_to_disable.emplace(name);
|
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
json::JsonObject general_settings;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
general_settings = load_general_settings();
|
2020-03-19 16:21:10 +08:00
|
|
|
if (general_settings.HasKey(L"enabled"))
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-03-19 16:21:10 +08:00
|
|
|
json::JsonObject enabled = general_settings.GetNamedObject(L"enabled");
|
2020-04-03 02:39:40 +08:00
|
|
|
for (const auto& disabled_element : enabled)
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2021-12-07 21:50:04 +08:00
|
|
|
std::wstring disable_module_name{ static_cast<std::wstring_view>(disabled_element.Key()) };
|
|
|
|
// Disable explicitly disabled modules
|
2020-04-03 02:39:40 +08:00
|
|
|
if (!disabled_element.Value().GetBoolean())
|
2020-03-19 16:21:10 +08:00
|
|
|
{
|
2022-02-22 19:50:20 +08:00
|
|
|
Logger::info(L"start_enabled_powertoys: Powertoy {} explicitly disabled", disable_module_name);
|
2021-12-07 21: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 19:50:20 +08:00
|
|
|
Logger::info(L"start_enabled_powertoys: Overriding default enabled value for {} powertoy", disable_module_name);
|
2021-12-07 21:50:04 +08:00
|
|
|
powertoys_to_disable.erase(it);
|
2020-03-19 16:21:10 +08:00
|
|
|
}
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-21 15:30:12 +08:00
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
}
|
2020-04-03 02:39:40 +08:00
|
|
|
|
2021-12-07 21:50:04 +08:00
|
|
|
for (auto& [name, powertoy] : modules())
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2021-12-07 21:50:04 +08:00
|
|
|
if (!powertoys_to_disable.contains(name))
|
2020-04-03 02:39:40 +08:00
|
|
|
{
|
2022-02-22 19:50:20 +08:00
|
|
|
Logger::info(L"start_enabled_powertoys: Enabling powertoy {}", name);
|
2020-04-03 02:39:40 +08:00
|
|
|
powertoy->enable();
|
2022-02-02 20:17:37 +08:00
|
|
|
powertoy.UpdateHotkeyEx();
|
2020-04-03 02:39:40 +08:00
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
|
|
|
}
|