mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-23 04:27:14 +01:00
<!-- 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 Adds new "Off" mode for the schedule mode options which disable the schedule. Adds explicit function to disable light switch by default. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist Closes: - #42402 New behavior: "Off" mode added. when off, the regular service loop stops and all actions are event driven to either resume the loop or listen for hotkey. - #42386 New behavior: Disabled explicitly by default - #42389 New behavior: When switching from dark to light mode the system theme will remove the accent color. - #42513 New behavior: Manual mode no longer gets reset. It was being overridden by the sun calculations that were invertedly running when in manual mode. Todo: - [ ] **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 @alvinashcraft we will need to add this new mode to the documentation. ## Validation Steps Performed - Removed all default settings and tested new logic. Light Switch is set to off by default. - Updated UI and tested new "Off" mode, logs indicate mode switched and ticker stopped. Polling resumes on mode change. (need to check that the shortcut still works) --------- Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Gordon Lam <73506701+yeelam-gordon@users.noreply.github.com>
642 lines
20 KiB
C++
642 lines
20 KiB
C++
#include "pch.h"
|
|
#include <interface/powertoy_module_interface.h>
|
|
#include "trace.h"
|
|
#include <common/logger/logger.h>
|
|
#include <common/SettingsAPI/settings_objects.h>
|
|
#include <common/SettingsAPI/settings_helpers.h>
|
|
#include <locale>
|
|
#include <codecvt>
|
|
#include <common/utils/logger_helper.h>
|
|
#include "ThemeHelper.h"
|
|
|
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
|
|
|
namespace
|
|
{
|
|
const wchar_t JSON_KEY_PROPERTIES[] = L"properties";
|
|
const wchar_t JSON_KEY_WIN[] = L"win";
|
|
const wchar_t JSON_KEY_ALT[] = L"alt";
|
|
const wchar_t JSON_KEY_CTRL[] = L"ctrl";
|
|
const wchar_t JSON_KEY_SHIFT[] = L"shift";
|
|
const wchar_t JSON_KEY_CODE[] = L"code";
|
|
const wchar_t JSON_KEY_TOGGLE_THEME_HOTKEY[] = L"toggle-theme-hotkey";
|
|
const wchar_t JSON_KEY_VALUE[] = L"value";
|
|
}
|
|
|
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
|
{
|
|
switch (ul_reason_for_call)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
Trace::RegisterProvider();
|
|
break;
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
Trace::UnregisterProvider();
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// The PowerToy name that will be shown in the settings.
|
|
const static wchar_t* MODULE_NAME = L"LightSwitch";
|
|
// Add a description that will we shown in the module settings page.
|
|
const static wchar_t* MODULE_DESC = L"This is a module that allows you to control light/dark theming via set times, sun rise, or directly invoking the change.";
|
|
|
|
enum class ScheduleMode
|
|
{
|
|
Off,
|
|
FixedHours,
|
|
SunsetToSunrise,
|
|
// add more later
|
|
};
|
|
|
|
inline std::wstring ToString(ScheduleMode mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case ScheduleMode::SunsetToSunrise:
|
|
return L"SunsetToSunrise";
|
|
case ScheduleMode::FixedHours:
|
|
return L"FixedHours";
|
|
default:
|
|
return L"Off";
|
|
}
|
|
}
|
|
|
|
inline ScheduleMode FromString(const std::wstring& str)
|
|
{
|
|
if (str == L"SunsetToSunrise")
|
|
return ScheduleMode::SunsetToSunrise;
|
|
if (str == L"FixedHours")
|
|
return ScheduleMode::FixedHours;
|
|
return ScheduleMode::Off;
|
|
}
|
|
|
|
// These are the properties shown in the Settings page.
|
|
struct ModuleSettings
|
|
{
|
|
bool m_changeSystem = true;
|
|
bool m_changeApps = true;
|
|
ScheduleMode m_scheduleMode = ScheduleMode::Off;
|
|
int m_lightTime = 480;
|
|
int m_darkTime = 1200;
|
|
int m_sunrise_offset = 0;
|
|
int m_sunset_offset = 0;
|
|
std::wstring m_latitude = L"0.0";
|
|
std::wstring m_longitude = L"0.0";
|
|
} g_settings;
|
|
|
|
class LightSwitchInterface : public PowertoyModuleIface
|
|
{
|
|
private:
|
|
bool m_enabled = false;
|
|
|
|
HANDLE m_process{ nullptr };
|
|
HANDLE m_force_light_event_handle;
|
|
HANDLE m_force_dark_event_handle;
|
|
HANDLE m_manual_override_event_handle;
|
|
|
|
static const constexpr int NUM_DEFAULT_HOTKEYS = 4;
|
|
|
|
Hotkey m_toggle_theme_hotkey = { .win = true, .ctrl = true, .shift = true, .alt = false, .key = 'D' };
|
|
|
|
void init_settings();
|
|
|
|
public:
|
|
LightSwitchInterface()
|
|
{
|
|
LoggerHelpers::init_logger(L"LightSwitch", L"ModuleInterface", LogSettings::lightSwitchLoggerName);
|
|
|
|
m_force_light_event_handle = CreateDefaultEvent(L"POWERTOYS_LIGHTSWITCH_FORCE_LIGHT");
|
|
m_force_dark_event_handle = CreateDefaultEvent(L"POWERTOYS_LIGHTSWITCH_FORCE_DARK");
|
|
m_manual_override_event_handle = CreateEventW(nullptr, TRUE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
|
|
|
init_settings();
|
|
};
|
|
|
|
virtual const wchar_t* get_key() override
|
|
{
|
|
return L"LightSwitch";
|
|
}
|
|
|
|
// Destroy the powertoy and free memory
|
|
virtual void destroy() override
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
// Return the display name of the powertoy, this will be cached by the runner
|
|
virtual const wchar_t* get_name() override
|
|
{
|
|
return MODULE_NAME;
|
|
}
|
|
|
|
// Return the configured status for the gpo policy for the module
|
|
virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
|
|
{
|
|
return powertoys_gpo::getConfiguredLightSwitchEnabledValue();
|
|
}
|
|
|
|
// Return JSON with the configuration options.
|
|
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
|
|
{
|
|
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
|
|
|
// Create a Settings object with your module name
|
|
PowerToysSettings::Settings settings(hinstance, get_name());
|
|
settings.set_description(MODULE_DESC);
|
|
settings.set_overview_link(L"https://aka.ms/powertoys");
|
|
|
|
// Boolean toggles
|
|
settings.add_bool_toggle(
|
|
L"changeSystem",
|
|
L"Change System Theme",
|
|
g_settings.m_changeSystem);
|
|
|
|
settings.add_bool_toggle(
|
|
L"changeApps",
|
|
L"Change Apps Theme",
|
|
g_settings.m_changeApps);
|
|
|
|
settings.add_choice_group(
|
|
L"scheduleMode",
|
|
L"Theme schedule mode",
|
|
ToString(g_settings.m_scheduleMode),
|
|
{ { L"Off", L"Disable the schedule" },
|
|
{ L"FixedHours", L"Set hours manually" },
|
|
{ L"SunsetToSunrise", L"Use sunrise/sunset times" } });
|
|
|
|
// Integer spinners
|
|
settings.add_int_spinner(
|
|
L"lightTime",
|
|
L"Time to switch to light theme (minutes after midnight).",
|
|
g_settings.m_lightTime,
|
|
0,
|
|
1439,
|
|
1);
|
|
|
|
settings.add_int_spinner(
|
|
L"darkTime",
|
|
L"Time to switch to dark theme (minutes after midnight).",
|
|
g_settings.m_darkTime,
|
|
0,
|
|
1439,
|
|
1);
|
|
|
|
settings.add_int_spinner(
|
|
L"sunrise_offset",
|
|
L"Time to offset turning on your light theme.",
|
|
g_settings.m_sunrise_offset,
|
|
0,
|
|
1439,
|
|
1);
|
|
|
|
settings.add_int_spinner(
|
|
L"sunset_offset",
|
|
L"Time to offset turning on your dark theme.",
|
|
g_settings.m_sunset_offset,
|
|
0,
|
|
1439,
|
|
1);
|
|
|
|
// Strings for latitude and longitude
|
|
settings.add_string(
|
|
L"latitude",
|
|
L"Your latitude in decimal degrees (e.g. 39.95).",
|
|
g_settings.m_latitude);
|
|
|
|
settings.add_string(
|
|
L"longitude",
|
|
L"Your longitude in decimal degrees (e.g. -75.16).",
|
|
g_settings.m_longitude);
|
|
|
|
// One-shot actions (buttons)
|
|
settings.add_custom_action(
|
|
L"forceLight",
|
|
L"Switch immediately to light theme",
|
|
L"Force Light",
|
|
L"{}");
|
|
|
|
settings.add_custom_action(
|
|
L"forceDark",
|
|
L"Switch immediately to dark theme",
|
|
L"Force Dark",
|
|
L"{}");
|
|
|
|
// Hotkeys
|
|
PowerToysSettings::HotkeyObject dm_hk = PowerToysSettings::HotkeyObject::from_settings(
|
|
m_toggle_theme_hotkey.win,
|
|
m_toggle_theme_hotkey.ctrl,
|
|
m_toggle_theme_hotkey.alt,
|
|
m_toggle_theme_hotkey.shift,
|
|
m_toggle_theme_hotkey.key);
|
|
|
|
settings.add_hotkey(
|
|
L"toggle-theme-hotkey",
|
|
L"Shortcut to toggle theme immediately",
|
|
dm_hk);
|
|
|
|
// Serialize to buffer for the PowerToys runner
|
|
return settings.serialize_to_buffer(buffer, buffer_size);
|
|
}
|
|
|
|
// Signal from the Settings editor to call a custom action.
|
|
// This can be used to spawn more complex editors.
|
|
void call_custom_action(const wchar_t* action) override
|
|
{
|
|
try
|
|
{
|
|
auto action_object = PowerToysSettings::CustomActionObject::from_json_string(action);
|
|
|
|
if (action_object.get_name() == L"forceLight")
|
|
{
|
|
Logger::info(L"[Light Switch] Custom action triggered: Force Light");
|
|
SetSystemTheme(true);
|
|
SetAppsTheme(true);
|
|
}
|
|
else if (action_object.get_name() == L"forceDark")
|
|
{
|
|
Logger::info(L"[Light Switch] Custom action triggered: Force Dark");
|
|
SetSystemTheme(false);
|
|
SetAppsTheme(false);
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
Logger::error(L"[Light Switch] Invalid custom action JSON");
|
|
}
|
|
}
|
|
|
|
// Called by the runner to pass the updated settings values as a serialized JSON.
|
|
virtual void set_config(const wchar_t* config) override
|
|
{
|
|
try
|
|
{
|
|
auto values = PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
|
|
|
parse_hotkey(values);
|
|
|
|
if (auto v = values.get_bool_value(L"changeSystem"))
|
|
{
|
|
g_settings.m_changeSystem = *v;
|
|
}
|
|
|
|
if (auto v = values.get_bool_value(L"changeApps"))
|
|
{
|
|
g_settings.m_changeApps = *v;
|
|
}
|
|
|
|
auto previousMode = g_settings.m_scheduleMode;
|
|
|
|
if (auto v = values.get_string_value(L"scheduleMode"))
|
|
{
|
|
auto newMode = FromString(*v);
|
|
if (newMode != g_settings.m_scheduleMode)
|
|
{
|
|
Logger::info(L"[LightSwitchInterface] Schedule mode changed from {} to {}",
|
|
ToString(g_settings.m_scheduleMode),
|
|
ToString(newMode));
|
|
g_settings.m_scheduleMode = newMode;
|
|
|
|
start_service_if_needed();
|
|
}
|
|
}
|
|
|
|
if (auto v = values.get_int_value(L"lightTime"))
|
|
{
|
|
g_settings.m_lightTime = *v;
|
|
}
|
|
|
|
if (auto v = values.get_int_value(L"darkTime"))
|
|
{
|
|
g_settings.m_darkTime = *v;
|
|
}
|
|
|
|
if (auto v = values.get_int_value(L"sunrise_offset"))
|
|
{
|
|
g_settings.m_sunrise_offset = *v;
|
|
}
|
|
|
|
if (auto v = values.get_int_value(L"sunset_offset"))
|
|
{
|
|
g_settings.m_sunset_offset = *v;
|
|
}
|
|
|
|
if (auto v = values.get_string_value(L"latitude"))
|
|
{
|
|
g_settings.m_latitude = *v;
|
|
}
|
|
if (auto v = values.get_string_value(L"longitude"))
|
|
{
|
|
g_settings.m_longitude = *v;
|
|
}
|
|
|
|
values.save_to_settings_file();
|
|
}
|
|
catch (const std::exception&)
|
|
{
|
|
Logger::error("[Light Switch] set_config: Failed to parse or apply config.");
|
|
}
|
|
}
|
|
|
|
virtual void start_service_if_needed()
|
|
{
|
|
if (!m_process || WaitForSingleObject(m_process, 0) != WAIT_TIMEOUT)
|
|
{
|
|
Logger::info(L"[LightSwitchInterface] Starting LightSwitchService due to active schedule mode.");
|
|
enable();
|
|
}
|
|
else
|
|
{
|
|
Logger::debug(L"[LightSwitchInterface] Service already running, skipping start.");
|
|
}
|
|
}
|
|
|
|
/*virtual void stop_worker_only()
|
|
{
|
|
if (m_process)
|
|
{
|
|
Logger::info(L"[LightSwitchInterface] Stopping LightSwitchService (worker only).");
|
|
constexpr DWORD timeout_ms = 1500;
|
|
DWORD result = WaitForSingleObject(m_process, timeout_ms);
|
|
|
|
if (result == WAIT_TIMEOUT)
|
|
{
|
|
Logger::warn("Light Switch: Process didn't exit in time. Forcing termination.");
|
|
TerminateProcess(m_process, 0);
|
|
}
|
|
|
|
CloseHandle(m_process);
|
|
m_process = nullptr;
|
|
}
|
|
}*/
|
|
|
|
/*virtual void stop_service_if_running()
|
|
{
|
|
if (m_process)
|
|
{
|
|
Logger::info(L"[LightSwitchInterface] Stopping LightSwitchService due to schedule OFF.");
|
|
stop_worker_only();
|
|
}
|
|
}*/
|
|
|
|
virtual void enable()
|
|
{
|
|
m_enabled = true;
|
|
Logger::info(L"Enabling Light Switch module...");
|
|
|
|
unsigned long powertoys_pid = GetCurrentProcessId();
|
|
std::wstring args = L"--pid " + std::to_wstring(powertoys_pid);
|
|
std::wstring exe_name = L"LightSwitchService\\PowerToys.LightSwitchService.exe";
|
|
|
|
std::wstring resolved_path(MAX_PATH, L'\0');
|
|
DWORD result = SearchPathW(
|
|
nullptr,
|
|
exe_name.c_str(),
|
|
nullptr,
|
|
static_cast<DWORD>(resolved_path.size()),
|
|
resolved_path.data(),
|
|
nullptr);
|
|
|
|
if (result == 0 || result >= resolved_path.size())
|
|
{
|
|
Logger::error(
|
|
L"Failed to locate Light Switch executable named '{}' at location '{}'",
|
|
exe_name,
|
|
resolved_path.c_str());
|
|
return;
|
|
}
|
|
|
|
resolved_path.resize(result);
|
|
Logger::debug(L"Resolved executable path: {}", resolved_path);
|
|
|
|
std::wstring command_line = L"\"" + resolved_path + L"\" " + args;
|
|
|
|
STARTUPINFO si = { sizeof(si) };
|
|
PROCESS_INFORMATION pi;
|
|
|
|
if (!CreateProcessW(
|
|
resolved_path.c_str(),
|
|
command_line.data(),
|
|
nullptr,
|
|
nullptr,
|
|
TRUE,
|
|
0,
|
|
nullptr,
|
|
nullptr,
|
|
&si,
|
|
&pi))
|
|
{
|
|
Logger::error(L"Failed to launch Light Switch process. {}", get_last_error_or_default(GetLastError()));
|
|
return;
|
|
}
|
|
|
|
Logger::info(L"Light Switch process launched successfully (PID: {}).", pi.dwProcessId);
|
|
m_process = pi.hProcess;
|
|
CloseHandle(pi.hThread);
|
|
}
|
|
|
|
// Disable the powertoy
|
|
virtual void disable()
|
|
{
|
|
Logger::info("Light Switch disabling");
|
|
m_enabled = false;
|
|
|
|
if (m_process)
|
|
{
|
|
constexpr DWORD timeout_ms = 1500;
|
|
DWORD result = WaitForSingleObject(m_process, timeout_ms);
|
|
|
|
if (result == WAIT_TIMEOUT)
|
|
{
|
|
Logger::warn("Light Switch: Process didn't exit in time. Forcing termination.");
|
|
TerminateProcess(m_process, 0);
|
|
}
|
|
|
|
CloseHandle(m_manual_override_event_handle);
|
|
m_manual_override_event_handle = nullptr;
|
|
|
|
CloseHandle(m_process);
|
|
m_process = nullptr;
|
|
}
|
|
}
|
|
|
|
// Returns if the powertoys is enabled
|
|
virtual bool is_enabled() override
|
|
{
|
|
return m_enabled;
|
|
}
|
|
|
|
// Returns whether the PowerToys should be enabled by default
|
|
virtual bool is_enabled_by_default() const override
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void parse_hotkey(PowerToysSettings::PowerToyValues& settings)
|
|
{
|
|
auto settingsObject = settings.get_raw_json();
|
|
if (settingsObject.GetView().Size())
|
|
{
|
|
try
|
|
{
|
|
Hotkey _temp_toggle_theme;
|
|
auto jsonHotkeyObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_TOGGLE_THEME_HOTKEY).GetNamedObject(JSON_KEY_VALUE);
|
|
_temp_toggle_theme.win = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_WIN);
|
|
_temp_toggle_theme.alt = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_ALT);
|
|
_temp_toggle_theme.shift = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_SHIFT);
|
|
_temp_toggle_theme.ctrl = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_CTRL);
|
|
_temp_toggle_theme.key = static_cast<unsigned char>(jsonHotkeyObject.GetNamedNumber(JSON_KEY_CODE));
|
|
m_toggle_theme_hotkey = _temp_toggle_theme;
|
|
}
|
|
catch (...)
|
|
{
|
|
Logger::error("Failed to initialize Light Switch force dark mode shortcut from settings. Value will keep unchanged.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logger::info("Light Switch settings are empty");
|
|
}
|
|
}
|
|
|
|
virtual size_t get_hotkeys(Hotkey* hotkeys, size_t buffer_size) override
|
|
{
|
|
if (hotkeys && buffer_size >= 1)
|
|
{
|
|
hotkeys[0] = m_toggle_theme_hotkey;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
virtual bool on_hotkey(size_t hotkeyId) override
|
|
{
|
|
if (m_enabled)
|
|
{
|
|
Logger::trace(L"Light Switch hotkey pressed");
|
|
if (!is_process_running())
|
|
{
|
|
enable();
|
|
}
|
|
else if (hotkeyId == 0)
|
|
{
|
|
// get current will return true if in light mode; otherwise false
|
|
Logger::info(L"[Light Switch] Hotkey triggered: Toggle Theme");
|
|
if (g_settings.m_changeSystem)
|
|
{
|
|
SetSystemTheme(!GetCurrentSystemTheme());
|
|
}
|
|
if (g_settings.m_changeApps)
|
|
{
|
|
SetAppsTheme(!GetCurrentAppsTheme());
|
|
}
|
|
|
|
if (!m_manual_override_event_handle)
|
|
{
|
|
m_manual_override_event_handle = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
|
if (!m_manual_override_event_handle)
|
|
{
|
|
m_manual_override_event_handle = CreateEventW(nullptr, TRUE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
|
}
|
|
}
|
|
|
|
if (m_manual_override_event_handle)
|
|
{
|
|
SetEvent(m_manual_override_event_handle);
|
|
Logger::debug(L"[Light Switch] Manual override event set");
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool is_process_running()
|
|
{
|
|
return WaitForSingleObject(m_process, 0) == WAIT_TIMEOUT;
|
|
}
|
|
};
|
|
|
|
std::wstring utf8_to_wstring(const std::string& str)
|
|
{
|
|
if (str.empty())
|
|
return std::wstring();
|
|
|
|
int size_needed = MultiByteToWideChar(
|
|
CP_UTF8,
|
|
0,
|
|
str.c_str(),
|
|
static_cast<int>(str.size()),
|
|
nullptr,
|
|
0);
|
|
|
|
std::wstring wstr(size_needed, 0);
|
|
|
|
MultiByteToWideChar(
|
|
CP_UTF8,
|
|
0,
|
|
str.c_str(),
|
|
static_cast<int>(str.size()),
|
|
&wstr[0],
|
|
size_needed);
|
|
|
|
return wstr;
|
|
}
|
|
|
|
// Load the settings file.
|
|
void LightSwitchInterface::init_settings()
|
|
{
|
|
Logger::info(L"[Light Switch] init_settings: starting to load settings for module");
|
|
|
|
try
|
|
{
|
|
PowerToysSettings::PowerToyValues settings =
|
|
PowerToysSettings::PowerToyValues::load_from_settings_file(get_name());
|
|
|
|
parse_hotkey(settings);
|
|
|
|
if (auto v = settings.get_bool_value(L"changeSystem"))
|
|
g_settings.m_changeSystem = *v;
|
|
if (auto v = settings.get_bool_value(L"changeApps"))
|
|
g_settings.m_changeApps = *v;
|
|
if (auto v = settings.get_string_value(L"scheduleMode"))
|
|
g_settings.m_scheduleMode = FromString(*v);
|
|
if (auto v = settings.get_int_value(L"lightTime"))
|
|
g_settings.m_lightTime = *v;
|
|
if (auto v = settings.get_int_value(L"darkTime"))
|
|
g_settings.m_darkTime = *v;
|
|
if (auto v = settings.get_int_value(L"sunrise_offset"))
|
|
g_settings.m_sunrise_offset = *v;
|
|
if (auto v = settings.get_int_value(L"sunset_offset"))
|
|
g_settings.m_sunset_offset = *v;
|
|
if (auto v = settings.get_string_value(L"latitude"))
|
|
g_settings.m_latitude = *v;
|
|
if (auto v = settings.get_string_value(L"longitude"))
|
|
g_settings.m_longitude = *v;
|
|
|
|
Logger::info(L"[Light Switch] init_settings: loaded successfully");
|
|
}
|
|
catch (const winrt::hresult_error& e)
|
|
{
|
|
Logger::error(L"[Light Switch] init_settings: hresult_error 0x{:08X} - {}", e.code(), e.message().c_str());
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
std::wstring whatStr = utf8_to_wstring(e.what());
|
|
Logger::error(L"[Light Switch] init_settings: std::exception - {}", whatStr);
|
|
}
|
|
catch (...)
|
|
{
|
|
Logger::error(L"[Light Switch] init_settings: unknown exception while loading settings");
|
|
}
|
|
}
|
|
|
|
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
|
|
{
|
|
return new LightSwitchInterface();
|
|
} |