mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-03 02:46:37 +01:00
Compare commits
2 Commits
jay/hotfix
...
stable-bac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b545597997 | ||
|
|
b995ffabd7 |
@@ -9,25 +9,6 @@
|
||||
<RegistryValue Type="string" Name="InstallScope" Value="$(var.InstallScope)" />
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
<?if $(var.PerUser) = "true" ?>
|
||||
<Component Id="powertoys_env_path_user" Bitness="always64">
|
||||
<!-- Anchor registry for component key path -->
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="powertoys_env_path_user" Value="" KeyPath="yes" />
|
||||
</RegistryKey>
|
||||
<!-- Append install folder to current user's PATH -->
|
||||
<Environment Id="AddPowerToysToUserPath" Name="PATH" Action="set" Part="last" System="no" Value="[INSTALLFOLDER]" />
|
||||
</Component>
|
||||
<?else?>
|
||||
<Component Id="powertoys_env_path_machine" Bitness="always64">
|
||||
<!-- Anchor registry for component key path -->
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||
<RegistryValue Type="string" Name="powertoys_env_path_machine" Value="" KeyPath="yes" />
|
||||
</RegistryKey>
|
||||
<!-- Append install folder to machine PATH -->
|
||||
<Environment Id="AddPowerToysToMachinePath" Name="PATH" Action="set" Part="last" System="yes" Value="[INSTALLFOLDER]" />
|
||||
</Component>
|
||||
<?endif?>
|
||||
<Component Id="powertoys_toast_clsid" Bitness="always64">
|
||||
<RemoveFolder Id="Remove_powertoys_toast_clsid" On="uninstall" />
|
||||
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\CLSID\{DD5CACDA-7C2E-4997-A62A-04A597B58F76}">
|
||||
@@ -128,11 +109,6 @@
|
||||
<ComponentRef Id="powertoys_exe" />
|
||||
<ComponentRef Id="PowerToysStartMenuShortcut" />
|
||||
<ComponentRef Id="powertoys_per_machine_comp" />
|
||||
<?if $(var.PerUser) = "true" ?>
|
||||
<ComponentRef Id="powertoys_env_path_user" />
|
||||
<?else?>
|
||||
<ComponentRef Id="powertoys_env_path_machine" />
|
||||
<?endif?>
|
||||
<ComponentRef Id="powertoys_toast_clsid" />
|
||||
<ComponentRef Id="License_rtf" />
|
||||
<ComponentRef Id="Notice_md" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <windows.h>
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include "ThemeScheduler.h"
|
||||
#include "ThemeHelper.h"
|
||||
@@ -11,13 +11,15 @@
|
||||
#include <logger/logger_settings.h>
|
||||
#include <logger/logger.h>
|
||||
#include <utils/logger_helper.h>
|
||||
#include <LightSwitchServiceObserver.h>
|
||||
|
||||
SERVICE_STATUS g_ServiceStatus = {};
|
||||
SERVICE_STATUS_HANDLE g_StatusHandle = nullptr;
|
||||
HANDLE g_ServiceStopEvent = nullptr;
|
||||
static int g_lastUpdatedDay = -1;
|
||||
extern int g_lastUpdatedDay = -1;
|
||||
static ScheduleMode prevMode = ScheduleMode::Off;
|
||||
static std::wstring prevLat, prevLon;
|
||||
static int prevMinutes = -1;
|
||||
|
||||
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
|
||||
VOID WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
||||
@@ -148,7 +150,6 @@ static void update_sun_times(auto& settings)
|
||||
std::wstring wmsg(e.what(), e.what() + strlen(e.what()));
|
||||
Logger::error(L"[LightSwitchService] Exception during sun time update: {}", wmsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
@@ -161,25 +162,18 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
Logger::info(L"[LightSwitchService] Worker thread starting...");
|
||||
Logger::info(L"[LightSwitchService] Parent PID: {}", parentPid);
|
||||
|
||||
// Initialize settings system
|
||||
LightSwitchSettings::instance().InitFileWatcher();
|
||||
|
||||
// Open the manual override event created by the module interface
|
||||
LightSwitchServiceObserver observer({ SettingId::LightTime,
|
||||
SettingId::DarkTime,
|
||||
SettingId::ScheduleMode,
|
||||
SettingId::Sunrise_Offset,
|
||||
SettingId::Sunset_Offset });
|
||||
|
||||
HANDLE hManualOverride = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
|
||||
auto applyTheme = [](int nowMinutes, int lightMinutes, int darkMinutes, const auto& settings) {
|
||||
bool isLightActive = false;
|
||||
|
||||
if (lightMinutes < darkMinutes)
|
||||
{
|
||||
// Normal case: sunrise < sunset
|
||||
isLightActive = (nowMinutes >= lightMinutes && nowMinutes < darkMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wraparound case: e.g. light at 21:00, dark at 06:00
|
||||
isLightActive = (nowMinutes >= lightMinutes || nowMinutes < darkMinutes);
|
||||
}
|
||||
bool isLightActive = (lightMinutes < darkMinutes) ? (nowMinutes >= lightMinutes && nowMinutes < darkMinutes) : (nowMinutes >= lightMinutes || nowMinutes < darkMinutes);
|
||||
|
||||
bool isSystemCurrentlyLight = GetCurrentSystemTheme();
|
||||
bool isAppsCurrentlyLight = GetCurrentAppsTheme();
|
||||
@@ -212,85 +206,72 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
}
|
||||
};
|
||||
|
||||
// --- Initial settings load ---
|
||||
LightSwitchSettings::instance().LoadSettings();
|
||||
auto& settings = LightSwitchSettings::instance().settings();
|
||||
|
||||
// --- Initial theme application (if schedule enabled) ---
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int nowMinutes = st.wHour * 60 + st.wMinute;
|
||||
|
||||
if (settings.scheduleMode != ScheduleMode::Off)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int nowMinutes = st.wHour * 60 + st.wMinute;
|
||||
applyTheme(nowMinutes, settings.lightTime + settings.sunrise_offset, settings.darkTime + settings.sunset_offset, settings);
|
||||
applyTheme(nowMinutes,
|
||||
settings.lightTime + settings.sunrise_offset,
|
||||
settings.darkTime + settings.sunset_offset,
|
||||
settings);
|
||||
Logger::trace(L"[LightSwitchService] Initialized g_lastUpdatedDay = {}", g_lastUpdatedDay);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Schedule mode is OFF - ticker suspended, waiting for manual action or mode change.");
|
||||
}
|
||||
|
||||
// --- Main loop ---
|
||||
g_lastUpdatedDay = st.wDay;
|
||||
ULONGLONG lastSettingsReload = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
HANDLE waits[2] = { g_ServiceStopEvent, hParent };
|
||||
DWORD count = hParent ? 2 : 1;
|
||||
bool skipRest = false;
|
||||
|
||||
LightSwitchSettings::instance().LoadSettings();
|
||||
const auto& settings = LightSwitchSettings::instance().settings();
|
||||
|
||||
// Check for changes in schedule mode or coordinates
|
||||
bool modeChangedToSunset = (prevMode != settings.scheduleMode &&
|
||||
settings.scheduleMode == ScheduleMode::SunsetToSunrise);
|
||||
bool coordsChanged = (prevLat != settings.latitude || prevLon != settings.longitude);
|
||||
bool scheduleJustEnabled = (prevMode == ScheduleMode::Off && settings.scheduleMode != ScheduleMode::Off);
|
||||
prevMode = settings.scheduleMode;
|
||||
|
||||
if ((modeChangedToSunset || coordsChanged) && settings.scheduleMode == ScheduleMode::SunsetToSunrise)
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Mode or coordinates changed, recalculating sun times.");
|
||||
update_sun_times(settings);
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
g_lastUpdatedDay = st.wDay;
|
||||
prevMode = settings.scheduleMode;
|
||||
prevLat = settings.latitude;
|
||||
prevLon = settings.longitude;
|
||||
}
|
||||
|
||||
// If schedule is off, idle but keep watching settings and manual override
|
||||
// ─── Handle "Schedule Off" Mode ─────────────────────────────────────────────
|
||||
if (settings.scheduleMode == ScheduleMode::Off)
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Schedule mode OFF - suspending scheduler but keeping service alive.");
|
||||
|
||||
if (!hManualOverride)
|
||||
{
|
||||
hManualOverride = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
}
|
||||
|
||||
HANDLE waits[4];
|
||||
DWORD count = 0;
|
||||
waits[count++] = g_ServiceStopEvent;
|
||||
HANDLE waitsOff[4];
|
||||
DWORD countOff = 0;
|
||||
waitsOff[countOff++] = g_ServiceStopEvent;
|
||||
if (hParent)
|
||||
waits[count++] = hParent;
|
||||
waitsOff[countOff++] = hParent;
|
||||
if (hManualOverride)
|
||||
waits[count++] = hManualOverride;
|
||||
waits[count++] = LightSwitchSettings::instance().GetSettingsChangedEvent();
|
||||
waitsOff[countOff++] = hManualOverride;
|
||||
waitsOff[countOff++] = LightSwitchSettings::instance().GetSettingsChangedEvent();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DWORD wait = WaitForMultipleObjects(count, waits, FALSE, INFINITE);
|
||||
DWORD wait = WaitForMultipleObjects(countOff, waitsOff, FALSE, INFINITE);
|
||||
|
||||
// --- Handle exit signals ---
|
||||
if (wait == WAIT_OBJECT_0) // stop event
|
||||
if (wait == WAIT_OBJECT_0)
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Stop event triggered - exiting worker loop.");
|
||||
break;
|
||||
goto cleanup;
|
||||
}
|
||||
if (hParent && wait == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Parent exited - stopping service.");
|
||||
break;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// --- Manual override triggered ---
|
||||
if (wait == WAIT_OBJECT_0 + (hParent ? 2 : 1))
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Manual override received while schedule OFF.");
|
||||
@@ -298,15 +279,13 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
continue;
|
||||
}
|
||||
|
||||
// --- Settings file changed ---
|
||||
if (wait == WAIT_OBJECT_0 + (hParent ? 3 : 2))
|
||||
{
|
||||
Logger::trace(L"[LightSwitchService] Settings change event triggered, reloading settings...");
|
||||
|
||||
ResetEvent(LightSwitchSettings::instance().GetSettingsChangedEvent());
|
||||
|
||||
LightSwitchSettings::instance().LoadSettings();
|
||||
const auto& newSettings = LightSwitchSettings::instance().settings();
|
||||
lastSettingsReload = GetTickCount64();
|
||||
|
||||
if (newSettings.scheduleMode != ScheduleMode::Off)
|
||||
{
|
||||
@@ -315,68 +294,170 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// ─── Normal Schedule Loop ───────────────────────────────────────────────────
|
||||
ULONGLONG nowTick = GetTickCount64();
|
||||
bool recentSettingsReload = (nowTick - lastSettingsReload < 5000);
|
||||
|
||||
// --- When schedule is active, run once per minute ---
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int nowMinutes = st.wHour * 60 + st.wMinute;
|
||||
|
||||
// Refresh suntimes at day boundary
|
||||
if ((g_lastUpdatedDay != st.wDay) && (settings.scheduleMode == ScheduleMode::SunsetToSunrise))
|
||||
if (g_lastUpdatedDay != -1)
|
||||
{
|
||||
update_sun_times(settings);
|
||||
g_lastUpdatedDay = st.wDay;
|
||||
Logger::info(L"[LightSwitchService] Recalculated sun times at new day boundary.");
|
||||
}
|
||||
bool manualOverrideActive = (hManualOverride && WaitForSingleObject(hManualOverride, 0) == WAIT_OBJECT_0);
|
||||
|
||||
// Have to do this again in case settings got updated in the refresh suntimes chunk
|
||||
LightSwitchSettings::instance().LoadSettings();
|
||||
const auto& currentSettings = LightSwitchSettings::instance().settings();
|
||||
|
||||
wchar_t msg[160];
|
||||
swprintf_s(msg,
|
||||
L"[LightSwitchService] now=%02d:%02d | light=%02d:%02d | dark=%02d:%02d | mode=%d",
|
||||
st.wHour,
|
||||
st.wMinute,
|
||||
currentSettings.lightTime / 60,
|
||||
currentSettings.lightTime % 60,
|
||||
currentSettings.darkTime / 60,
|
||||
currentSettings.darkTime % 60,
|
||||
static_cast<int>(currentSettings.scheduleMode));
|
||||
Logger::info(msg);
|
||||
|
||||
// --- Manual override check ---
|
||||
bool manualOverrideActive = false;
|
||||
if (hManualOverride)
|
||||
{
|
||||
manualOverrideActive = (WaitForSingleObject(hManualOverride, 0) == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
if (manualOverrideActive)
|
||||
{
|
||||
if (nowMinutes == (currentSettings.lightTime + currentSettings.sunrise_offset) % 1440 ||
|
||||
nowMinutes == (currentSettings.darkTime + currentSettings.sunset_offset) % 1440)
|
||||
if (settings.scheduleMode != ScheduleMode::Off && !recentSettingsReload && !scheduleJustEnabled)
|
||||
{
|
||||
ResetEvent(hManualOverride);
|
||||
Logger::info(L"[LightSwitchService] Manual override cleared at boundary");
|
||||
Logger::debug(L"[LightSwitchService] Checking if manual override is active...");
|
||||
bool manualOverrideActive = (hManualOverride && WaitForSingleObject(hManualOverride, 0) == WAIT_OBJECT_0);
|
||||
Logger::debug(L"[LightSwitchService] Manual override active = {}", manualOverrideActive);
|
||||
|
||||
if (!manualOverrideActive)
|
||||
{
|
||||
bool currentSystemTheme = GetCurrentSystemTheme();
|
||||
bool currentAppsTheme = GetCurrentAppsTheme();
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int nowMinutes = st.wHour * 60 + st.wMinute;
|
||||
|
||||
bool shouldBeLight = (settings.lightTime < settings.darkTime) ? (nowMinutes >= settings.lightTime && nowMinutes < settings.darkTime) : (nowMinutes >= settings.lightTime || nowMinutes < settings.darkTime);
|
||||
|
||||
Logger::debug(L"[LightSwitchService] shouldBeLight = {}", shouldBeLight);
|
||||
|
||||
if ((settings.changeSystem && (currentSystemTheme != shouldBeLight)) ||
|
||||
(settings.changeApps && (currentAppsTheme != shouldBeLight)))
|
||||
{
|
||||
Logger::debug(L"[LightSwitchService] External theme change detected - enabling manual override");
|
||||
|
||||
if (!hManualOverride)
|
||||
{
|
||||
hManualOverride = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
if (!hManualOverride)
|
||||
hManualOverride = CreateEventW(nullptr, TRUE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");
|
||||
}
|
||||
|
||||
if (hManualOverride)
|
||||
{
|
||||
SetEvent(hManualOverride);
|
||||
Logger::info(L"[LightSwitchService] Detected manual theme change outside of LightSwitch. Triggering manual override.");
|
||||
skipRest = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Skipping schedule due to manual override");
|
||||
goto sleep_until_next_minute;
|
||||
Logger::debug(L"[LightSwitchService] Skipping external-change detection (schedule off, recent reload, or just enabled).");
|
||||
}
|
||||
}
|
||||
|
||||
applyTheme(nowMinutes, currentSettings.lightTime + currentSettings.sunrise_offset, currentSettings.darkTime + currentSettings.sunset_offset, currentSettings);
|
||||
// ─── Apply Schedule Logic ───────────────────────────────────────────────────
|
||||
if (!skipRest)
|
||||
{
|
||||
bool modeChangedToSunset = (prevMode != settings.scheduleMode &&
|
||||
settings.scheduleMode == ScheduleMode::SunsetToSunrise);
|
||||
bool coordsChanged = (prevLat != settings.latitude || prevLon != settings.longitude);
|
||||
|
||||
sleep_until_next_minute:
|
||||
if ((modeChangedToSunset || coordsChanged) && settings.scheduleMode == ScheduleMode::SunsetToSunrise)
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Mode or coordinates changed, recalculating sun times.");
|
||||
update_sun_times(settings);
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
g_lastUpdatedDay = st.wDay;
|
||||
prevMode = settings.scheduleMode;
|
||||
prevLat = settings.latitude;
|
||||
prevLon = settings.longitude;
|
||||
}
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int nowMinutes = st.wHour * 60 + st.wMinute;
|
||||
|
||||
if ((g_lastUpdatedDay != st.wDay) && (settings.scheduleMode == ScheduleMode::SunsetToSunrise))
|
||||
{
|
||||
update_sun_times(settings);
|
||||
g_lastUpdatedDay = st.wDay;
|
||||
prevMinutes = -1;
|
||||
Logger::info(L"[LightSwitchService] Recalculated sun times at new day boundary.");
|
||||
}
|
||||
|
||||
LightSwitchSettings::instance().LoadSettings();
|
||||
const auto& currentSettings = LightSwitchSettings::instance().settings();
|
||||
|
||||
wchar_t msg[160];
|
||||
swprintf_s(msg,
|
||||
L"[LightSwitchService] now=%02d:%02d | light=%02d:%02d | dark=%02d:%02d | mode=%d",
|
||||
st.wHour,
|
||||
st.wMinute,
|
||||
currentSettings.lightTime / 60,
|
||||
currentSettings.lightTime % 60,
|
||||
currentSettings.darkTime / 60,
|
||||
currentSettings.darkTime % 60,
|
||||
static_cast<int>(currentSettings.scheduleMode));
|
||||
Logger::info(msg);
|
||||
|
||||
bool manualOverrideActive = false;
|
||||
if (hManualOverride)
|
||||
manualOverrideActive = (WaitForSingleObject(hManualOverride, 0) == WAIT_OBJECT_0);
|
||||
|
||||
if (manualOverrideActive)
|
||||
{
|
||||
int lightBoundary = (currentSettings.lightTime + currentSettings.sunrise_offset) % 1440;
|
||||
int darkBoundary = (currentSettings.darkTime + currentSettings.sunset_offset) % 1440;
|
||||
|
||||
bool crossedLight = false;
|
||||
bool crossedDark = false;
|
||||
|
||||
if (prevMinutes != -1)
|
||||
{
|
||||
if (nowMinutes < prevMinutes)
|
||||
{
|
||||
crossedLight = (prevMinutes <= lightBoundary || nowMinutes >= lightBoundary);
|
||||
crossedDark = (prevMinutes <= darkBoundary || nowMinutes >= darkBoundary);
|
||||
}
|
||||
else
|
||||
{
|
||||
crossedLight = (prevMinutes < lightBoundary && nowMinutes >= lightBoundary);
|
||||
crossedDark = (prevMinutes < darkBoundary && nowMinutes >= darkBoundary);
|
||||
}
|
||||
}
|
||||
|
||||
Logger::debug(L"[LightSwitchService] prevMinutes={} nowMinutes={} light={} dark={}",
|
||||
prevMinutes,
|
||||
nowMinutes,
|
||||
lightBoundary,
|
||||
darkBoundary);
|
||||
|
||||
if (crossedLight || crossedDark)
|
||||
{
|
||||
ResetEvent(hManualOverride);
|
||||
Logger::info(L"[LightSwitchService] Manual override cleared after crossing schedule boundary.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Skipping schedule due to manual override");
|
||||
skipRest = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipRest)
|
||||
applyTheme(nowMinutes,
|
||||
currentSettings.lightTime + currentSettings.sunrise_offset,
|
||||
currentSettings.darkTime + currentSettings.sunset_offset,
|
||||
currentSettings);
|
||||
}
|
||||
|
||||
// ─── Wait For Next Minute Tick Or Stop Event ────────────────────────────────
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int msToNextMinute = (60 - st.wSecond) * 1000 - st.wMilliseconds;
|
||||
if (msToNextMinute < 50)
|
||||
msToNextMinute = 50;
|
||||
|
||||
prevMinutes = nowMinutes;
|
||||
|
||||
DWORD wait = WaitForMultipleObjects(count, waits, FALSE, msToNextMinute);
|
||||
if (wait == WAIT_OBJECT_0)
|
||||
{
|
||||
@@ -390,6 +471,7 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (hManualOverride)
|
||||
CloseHandle(hManualOverride);
|
||||
if (hParent)
|
||||
@@ -398,6 +480,53 @@ DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ApplyThemeNow()
|
||||
{
|
||||
LightSwitchSettings::instance().LoadSettings();
|
||||
const auto& settings = LightSwitchSettings::instance().settings();
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int nowMinutes = st.wHour * 60 + st.wMinute;
|
||||
|
||||
bool shouldBeLight = false;
|
||||
if (settings.lightTime < settings.darkTime)
|
||||
shouldBeLight = (nowMinutes >= settings.lightTime && nowMinutes < settings.darkTime);
|
||||
else
|
||||
shouldBeLight = (nowMinutes >= settings.lightTime || nowMinutes < settings.darkTime);
|
||||
|
||||
bool isSystemCurrentlyLight = GetCurrentSystemTheme();
|
||||
bool isAppsCurrentlyLight = GetCurrentAppsTheme();
|
||||
|
||||
Logger::info(L"[LightSwitchService] Applying (if needed) theme immediately due to schedule change.");
|
||||
|
||||
if (shouldBeLight)
|
||||
{
|
||||
if (settings.changeSystem && !isSystemCurrentlyLight)
|
||||
{
|
||||
SetSystemTheme(true);
|
||||
Logger::info(L"[LightSwitchService] Changing system theme to light mode.");
|
||||
}
|
||||
if (settings.changeApps && !isAppsCurrentlyLight)
|
||||
{
|
||||
SetAppsTheme(true);
|
||||
Logger::info(L"[LightSwitchService] Changing apps theme to light mode.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings.changeSystem && isSystemCurrentlyLight)
|
||||
{
|
||||
SetSystemTheme(false);
|
||||
Logger::info(L"[LightSwitchService] Changing system theme to dark mode.");
|
||||
}
|
||||
if (settings.changeApps && isAppsCurrentlyLight)
|
||||
{
|
||||
SetAppsTheme(false);
|
||||
Logger::info(L"[LightSwitchService] Changing apps theme to dark mode.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
{
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="LightSwitchService.cpp" />
|
||||
<ClCompile Include="LightSwitchServiceObserver.cpp" />
|
||||
<ClCompile Include="LightSwitchSettings.cpp" />
|
||||
<ClCompile Include="SettingsConstants.cpp" />
|
||||
<ClCompile Include="ThemeHelper.cpp" />
|
||||
@@ -84,6 +85,7 @@
|
||||
<ResourceCompile Include="LightSwitchService.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="LightSwitchServiceObserver.h" />
|
||||
<ClInclude Include="LightSwitchSettings.h" />
|
||||
<ClInclude Include="SettingsConstants.h" />
|
||||
<ClInclude Include="SettingsObserver.h" />
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
<ClCompile Include="WinHookEventIDs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LightSwitchServiceObserver.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ThemeScheduler.h">
|
||||
@@ -53,6 +56,9 @@
|
||||
<ClInclude Include="WinHookEventIDs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LightSwitchServiceObserver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "LightSwitchServiceObserver.h"
|
||||
#include <logger.h>
|
||||
#include "LightSwitchSettings.h"
|
||||
|
||||
// These are defined elsewhere in your service module (ServiceWorkerThread.cpp)
|
||||
extern int g_lastUpdatedDay;
|
||||
void ApplyThemeNow();
|
||||
|
||||
void LightSwitchServiceObserver::SettingsUpdate(SettingId id)
|
||||
{
|
||||
Logger::info(L"[LightSwitchService] Setting changed: {}", static_cast<int>(id));
|
||||
g_lastUpdatedDay = -1;
|
||||
ApplyThemeNow();
|
||||
}
|
||||
|
||||
bool LightSwitchServiceObserver::WantsToBeNotified(SettingId id) const noexcept
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SettingId::LightTime:
|
||||
case SettingId::DarkTime:
|
||||
case SettingId::ScheduleMode:
|
||||
case SettingId::Sunrise_Offset:
|
||||
case SettingId::Sunset_Offset:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "SettingsObserver.h"
|
||||
|
||||
// The LightSwitchServiceObserver reacts when LightSwitchSettings changes.
|
||||
class LightSwitchServiceObserver : public SettingsObserver
|
||||
{
|
||||
public:
|
||||
explicit LightSwitchServiceObserver(std::unordered_set<SettingId> observedSettings) :
|
||||
SettingsObserver(std::move(observedSettings))
|
||||
{
|
||||
}
|
||||
|
||||
void SettingsUpdate(SettingId id) override;
|
||||
bool WantsToBeNotified(SettingId id) const noexcept override;
|
||||
};
|
||||
@@ -39,6 +39,7 @@ void LightSwitchSettings::InitFileWatcher()
|
||||
GetSettingsFileName(),
|
||||
[this]() {
|
||||
Logger::info(L"[LightSwitchSettings] Settings file changed, signaling event.");
|
||||
LoadSettings();
|
||||
SetEvent(m_settingsChangedEvent);
|
||||
});
|
||||
}
|
||||
@@ -65,6 +66,11 @@ void LightSwitchSettings::NotifyObservers(SettingId id) const
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE LightSwitchSettings::GetSettingsChangedEvent() const
|
||||
{
|
||||
return m_settingsChangedEvent;
|
||||
}
|
||||
|
||||
void LightSwitchSettings::LoadSettings()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
|
||||
void LoadSettings();
|
||||
|
||||
HANDLE GetSettingsChangedEvent() const { return m_settingsChangedEvent; }
|
||||
HANDLE GetSettingsChangedEvent() const;
|
||||
|
||||
private:
|
||||
LightSwitchSettings();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <unordered_set>
|
||||
#include "SettingsConstants.h"
|
||||
#include "LightSwitchSettings.h"
|
||||
|
||||
class LightSwitchSettings;
|
||||
|
||||
@@ -22,7 +23,7 @@ public:
|
||||
// Override this in your class to respond to updates
|
||||
virtual void SettingsUpdate(SettingId type) {}
|
||||
|
||||
bool WantsToBeNotified(SettingId type) const noexcept
|
||||
virtual bool WantsToBeNotified(SettingId type) const noexcept
|
||||
{
|
||||
return m_observedSettings.contains(type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user