Skip to content

Commit a145ac9

Browse files
committed
fix(reset): fixed reset option not having effect
1 parent a986c5b commit a145ac9

File tree

12 files changed

+183
-55
lines changed

12 files changed

+183
-55
lines changed

include/config/config_applier.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@
1212
#include <windows.h>
1313
#include "config_loader.h"
1414

15+
/* ============================================================================
16+
* Global flags
17+
* ============================================================================ */
18+
19+
/**
20+
* @brief Force apply all config values, bypassing position preservation logic
21+
*
22+
* When TRUE, ApplyDisplaySettings will apply window position from config
23+
* even if current window position differs significantly.
24+
* Used during reset operations to ensure defaults are applied.
25+
* Automatically reset to FALSE after ApplyConfigSnapshot completes.
26+
*/
27+
extern BOOL g_ForceApplyConfig;
28+
1529
/* ============================================================================
1630
* Public API
1731
* ============================================================================ */

src/config/config_applier.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
/* Global text effect */
2323
extern TextEffectType CLOCK_TEXT_EFFECT;
2424

25+
/* Force apply flag - used during reset to bypass position preservation */
26+
BOOL g_ForceApplyConfig = FALSE;
27+
2528
/* ============================================================================
2629
* Helper: Language enum mapping
2730
* ============================================================================ */
@@ -112,24 +115,33 @@ void ApplyDisplaySettings(const ConfigSnapshot* snapshot) {
112115

113116
HWND hwnd = FindWindowW(L"CatimeWindowClass", L"Catime");
114117
if (hwnd) {
115-
/* Get current window position before updating globals */
116-
RECT currentRect;
117-
GetWindowRect(hwnd, &currentRect);
118-
119-
/* Compare current position with config snapshot */
120-
int deltaX = abs(currentRect.left - snapshot->windowPosX);
121-
int deltaY = abs(currentRect.top - snapshot->windowPosY);
122-
123-
if (deltaX > 10 || deltaY > 10) {
124-
/* Significant difference: preserve current position (likely just saved) */
125-
CLOCK_WINDOW_POS_X = currentRect.left;
126-
CLOCK_WINDOW_POS_Y = currentRect.top;
127-
} else {
128-
/* Minor difference: apply config position */
129-
CLOCK_WINDOW_POS_X = snapshot->windowPosX;
118+
/* Force apply mode: always use config values (used during reset) */
119+
if (g_ForceApplyConfig) {
130120
CLOCK_WINDOW_POS_Y = snapshot->windowPosY;
131-
SetWindowPos(hwnd, NULL, CLOCK_WINDOW_POS_X, CLOCK_WINDOW_POS_Y,
132-
0, 0, SWP_NOSIZE | SWP_NOZORDER);
121+
122+
/* For special position values (-2, -1), don't set position here.
123+
* RecalculateWindowSize will handle it with correct window dimensions. */
124+
if (snapshot->windowPosX != -2 && snapshot->windowPosX != -1) {
125+
CLOCK_WINDOW_POS_X = snapshot->windowPosX;
126+
SetWindowPos(hwnd, NULL, CLOCK_WINDOW_POS_X, CLOCK_WINDOW_POS_Y,
127+
0, 0, SWP_NOSIZE | SWP_NOZORDER);
128+
}
129+
} else {
130+
/* Normal mode: preserve position if significantly different */
131+
RECT currentRect;
132+
GetWindowRect(hwnd, &currentRect);
133+
int deltaX = abs(currentRect.left - snapshot->windowPosX);
134+
int deltaY = abs(currentRect.top - snapshot->windowPosY);
135+
136+
if (deltaX > 10 || deltaY > 10) {
137+
CLOCK_WINDOW_POS_X = currentRect.left;
138+
CLOCK_WINDOW_POS_Y = currentRect.top;
139+
} else {
140+
CLOCK_WINDOW_POS_X = snapshot->windowPosX;
141+
CLOCK_WINDOW_POS_Y = snapshot->windowPosY;
142+
SetWindowPos(hwnd, NULL, CLOCK_WINDOW_POS_X, CLOCK_WINDOW_POS_Y,
143+
0, 0, SWP_NOSIZE | SWP_NOZORDER);
144+
}
133145
}
134146

135147
BYTE alphaValue = (BYTE)((CLOCK_WINDOW_OPACITY * 255) / 100);

src/config/config_defaults.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static const ConfigItemMeta CONFIG_METADATA[] = {
5858
{INI_SECTION_DISPLAY, "OPACITY_STEP_FAST", "5", CONFIG_TYPE_INT, CFG_OFFSET(opacityStepFast), CFG_NO_SIZE, "Opacity Ctrl+scroll step (1-100)"},
5959
{INI_SECTION_DISPLAY, "SCALE_STEP_NORMAL", "10", CONFIG_TYPE_INT, CFG_OFFSET(scaleStepNormal), CFG_NO_SIZE, "Scale scroll step (1-100)"},
6060
{INI_SECTION_DISPLAY, "SCALE_STEP_FAST", "15", CONFIG_TYPE_INT, CFG_OFFSET(scaleStepFast), CFG_NO_SIZE, "Scale Ctrl+scroll step (1-100)"},
61-
{INI_SECTION_DISPLAY, "TEXT_EFFECT", "HOLOGRAPHIC", CONFIG_TYPE_ENUM, CFG_OFFSET(textEffect), CFG_NO_SIZE, "Text effect style (NONE/GLOW/GLASS/NEON/HOLOGRAPHIC/LIQUID)"},
61+
{INI_SECTION_DISPLAY, "TEXT_EFFECT", "NONE", CONFIG_TYPE_ENUM, CFG_OFFSET(textEffect), CFG_NO_SIZE, "Text effect style (NONE/GLOW/GLASS/NEON/HOLOGRAPHIC/LIQUID)"},
6262

6363
/* Timer settings */
6464
{INI_SECTION_TIMER, "CLOCK_DEFAULT_START_TIME", "1500", CONFIG_TYPE_INT, CFG_OFFSET(defaultStartTime), CFG_NO_SIZE, "Default timer duration (seconds)"},

src/config/config_recovery.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ BOOL ValidateTimerConfig(ConfigSnapshot* snapshot) {
132132
strcmp(snapshot->startupMode, "SHOW_TIME") != 0 &&
133133
strcmp(snapshot->startupMode, "NO_DISPLAY") != 0 &&
134134
strcmp(snapshot->startupMode, "POMODORO") != 0) {
135-
LOG_WARNING("Invalid startup mode '%s', resetting to COUNTDOWN",
135+
LOG_WARNING("Invalid startup mode '%s', resetting to SHOW_TIME",
136136
snapshot->startupMode);
137-
strncpy(snapshot->startupMode, "COUNTDOWN",
137+
strncpy(snapshot->startupMode, "SHOW_TIME",
138138
sizeof(snapshot->startupMode) - 1);
139139
snapshot->startupMode[sizeof(snapshot->startupMode) - 1] = '\0';
140140
modified = TRUE;

src/main/main_initialization.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ static StartupMode ParseStartupMode(const char* modeStr) {
312312
return STARTUP_MODE_DEFAULT;
313313
}
314314

315-
static void HandleStartupMode(HWND hwnd) {
315+
void HandleStartupMode(HWND hwnd) {
316316
StartupMode mode = ParseStartupMode(CLOCK_STARTUP_MODE);
317317

318318
LOG_INFO("Setting startup mode: %s", CLOCK_STARTUP_MODE);

src/timer/timer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ BOOL CLOCK_SHOW_CURRENT_TIME = FALSE;
2828
BOOL CLOCK_USE_24HOUR = TRUE;
2929
BOOL CLOCK_SHOW_SECONDS = TRUE;
3030
BOOL CLOCK_COUNT_UP = FALSE;
31-
char CLOCK_STARTUP_MODE[20] = "COUNTDOWN";
31+
char CLOCK_STARTUP_MODE[20] = "SHOW_TIME";
3232

3333
int CLOCK_TOTAL_TIME = 0;
3434
int countdown_elapsed_time = 0;

src/tray/tray_menu_submenus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ void BuildPresetManagementSubmenu(HMENU hMenu) {
164164
char configPath[MAX_PATH];
165165
GetConfigPath(configPath, MAX_PATH);
166166

167-
char currentStartupMode[20] = "COUNTDOWN";
168-
ReadIniString(INI_SECTION_TIMER, "STARTUP_MODE", "COUNTDOWN",
167+
char currentStartupMode[20] = "SHOW_TIME";
168+
ReadIniString(INI_SECTION_TIMER, "STARTUP_MODE", "SHOW_TIME",
169169
currentStartupMode, sizeof(currentStartupMode), configPath);
170170

171171
AppendMenuW(hStartupSettingsMenu, MF_STRING |

src/window/window_core.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,24 @@ HWND CreateMainWindow(HINSTANCE hInstance, int nCmdShow) {
136136
int initialWidth = (int)(CLOCK_BASE_WINDOW_WIDTH * CLOCK_WINDOW_SCALE);
137137
int initialHeight = (int)(CLOCK_BASE_WINDOW_HEIGHT * CLOCK_WINDOW_SCALE);
138138

139-
/* Auto-position logic */
140-
if (CLOCK_WINDOW_POS_X == -2) {
141-
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
142-
CLOCK_WINDOW_POS_X = (int)(screenWidth * 0.618f) - (initialWidth / 2);
143-
if (CLOCK_WINDOW_POS_X + initialWidth > screenWidth) {
144-
CLOCK_WINDOW_POS_X = screenWidth - initialWidth - 20;
139+
/* Auto-position logic - use primary monitor dimensions */
140+
if (CLOCK_WINDOW_POS_X == -2 || CLOCK_WINDOW_POS_X == -1) {
141+
POINT pt = {0, 0};
142+
HMONITOR hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
143+
MONITORINFO mi = {sizeof(mi)};
144+
GetMonitorInfo(hMon, &mi);
145+
int screenWidth = mi.rcMonitor.right - mi.rcMonitor.left;
146+
147+
if (CLOCK_WINDOW_POS_X == -2) {
148+
/* Golden ratio: 0.618 from left of primary monitor */
149+
CLOCK_WINDOW_POS_X = mi.rcMonitor.left + (int)(screenWidth * 0.618f) - (initialWidth / 2);
150+
if (CLOCK_WINDOW_POS_X + initialWidth > mi.rcMonitor.right) {
151+
CLOCK_WINDOW_POS_X = mi.rcMonitor.right - initialWidth - 20;
152+
}
153+
} else {
154+
/* Center on primary monitor */
155+
CLOCK_WINDOW_POS_X = mi.rcMonitor.left + (screenWidth - initialWidth) / 2;
145156
}
146-
} else if (CLOCK_WINDOW_POS_X == -1) {
147-
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
148-
CLOCK_WINDOW_POS_X = (screenWidth - initialWidth) / 2;
149157
}
150158

151159
HWND hwnd = CreateWindowExW(

src/window/window_multimonitor.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,25 @@ static void MoveWindowToDefaultPosition(HWND hwnd, HMONITOR hMonitor) {
9797

9898
int width = rect.right - rect.left;
9999
int height = rect.bottom - rect.top;
100+
int screenWidth = mi.rcWork.right - mi.rcWork.left;
100101

101-
/* Use default position from config.h (right-upper area) */
102+
/* Use default position from config.h */
102103
int newX = DEFAULT_WINDOW_POS_X;
103104
int newY = DEFAULT_WINDOW_POS_Y;
104105

105-
/* Handle sentinel value -1: use top of screen */
106+
/* Handle special X position values */
107+
if (newX == -2) {
108+
/* Golden ratio: 0.618 from left of monitor */
109+
newX = mi.rcWork.left + (int)(screenWidth * 0.618f) - (width / 2);
110+
if (newX + width > mi.rcWork.right) {
111+
newX = mi.rcWork.right - width - 20;
112+
}
113+
} else if (newX == -1) {
114+
/* Center on monitor */
115+
newX = mi.rcWork.left + (screenWidth - width) / 2;
116+
}
117+
118+
/* Handle sentinel value -1 for Y: use top of screen */
106119
if (newY < 0) {
107120
newY = mi.rcWork.top;
108121
}

src/window_procedure/window_commands.c

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "timer/timer.h"
1515
#include "window.h"
1616
#include "config.h"
17+
#include "config/config_applier.h"
1718
#include "log.h"
1819
#include "language.h"
1920
#include "startup.h"
@@ -22,6 +23,8 @@
2223
#include "color/color.h"
2324
#include "pomodoro.h"
2425
#include "tray/tray.h"
26+
27+
extern void HandleStartupMode(HWND hwnd);
2528
#include "dialog/dialog_procedure.h"
2629
#include "hotkey.h"
2730
#include "update_checker.h"
@@ -336,18 +339,56 @@ static LRESULT CmdBrowseFile(HWND hwnd, WPARAM wp, LPARAM lp) {
336339
}
337340

338341
static LRESULT CmdResetPosition(HWND hwnd, WPARAM wp, LPARAM lp) {
339-
(void)hwnd; (void)wp; (void)lp;
342+
(void)wp; (void)lp;
340343

341-
/* Use default values from config.h */
342-
char posX[32], posY[32];
343-
snprintf(posX, sizeof(posX), "%d", DEFAULT_WINDOW_POS_X);
344-
snprintf(posY, sizeof(posY), "%d", DEFAULT_WINDOW_POS_Y);
344+
/* Write default values to config */
345+
char posXStr[32], posYStr[32];
346+
snprintf(posXStr, sizeof(posXStr), "%d", DEFAULT_WINDOW_POS_X);
347+
snprintf(posYStr, sizeof(posYStr), "%d", DEFAULT_WINDOW_POS_Y);
345348

346-
WriteConfigKeyValue("CLOCK_WINDOW_POS_X", posX);
347-
WriteConfigKeyValue("CLOCK_WINDOW_POS_Y", posY);
349+
WriteConfigKeyValue("CLOCK_WINDOW_POS_X", posXStr);
350+
WriteConfigKeyValue("CLOCK_WINDOW_POS_Y", posYStr);
348351
WriteConfigKeyValue("WINDOW_SCALE", DEFAULT_WINDOW_SCALE);
349352
WriteConfigKeyValue("PLUGIN_SCALE", DEFAULT_PLUGIN_SCALE);
350353

354+
/* Directly apply position (don't rely on hot-reload for special values) */
355+
RECT windowRect;
356+
GetWindowRect(hwnd, &windowRect);
357+
int windowWidth = windowRect.right - windowRect.left;
358+
359+
POINT pt = {0, 0};
360+
HMONITOR hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
361+
MONITORINFO mi = {sizeof(mi)};
362+
GetMonitorInfo(hMon, &mi);
363+
int screenWidth = mi.rcMonitor.right - mi.rcMonitor.left;
364+
365+
int posX, posY;
366+
367+
/* Handle special X position values */
368+
if (DEFAULT_WINDOW_POS_X == -2) {
369+
posX = mi.rcMonitor.left + (int)(screenWidth * 0.618f) - (windowWidth / 2);
370+
if (posX + windowWidth > mi.rcMonitor.right) {
371+
posX = mi.rcMonitor.right - windowWidth - 20;
372+
}
373+
} else if (DEFAULT_WINDOW_POS_X == -1) {
374+
posX = mi.rcMonitor.left + (screenWidth - windowWidth) / 2;
375+
} else {
376+
posX = mi.rcMonitor.left + DEFAULT_WINDOW_POS_X;
377+
}
378+
379+
/* Handle special Y position value (-1 = top of monitor) */
380+
if (DEFAULT_WINDOW_POS_Y == -1) {
381+
posY = mi.rcMonitor.top;
382+
} else if (DEFAULT_WINDOW_POS_Y < 0) {
383+
posY = mi.rcMonitor.top;
384+
} else {
385+
posY = mi.rcMonitor.top + DEFAULT_WINDOW_POS_Y;
386+
}
387+
388+
CLOCK_WINDOW_POS_X = posX;
389+
CLOCK_WINDOW_POS_Y = posY;
390+
SetWindowPos(hwnd, NULL, posX, posY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
391+
351392
return 0;
352393
}
353394

@@ -375,18 +416,22 @@ static LRESULT CmdResetDefaults(HWND hwnd, WPARAM wp, LPARAM lp) {
375416

376417
/* Step 5: Reload all configuration (same as startup) */
377418
LOG_INFO("Reset: Reloading default configuration...");
419+
g_ForceApplyConfig = TRUE; /* Force apply all config values */
378420
ReadConfig();
421+
g_ForceApplyConfig = FALSE;
379422
LOG_INFO("Reset: Configuration reloaded successfully");
380423

381-
/* Step 5.5: Reset UI runtime state (not in config file) */
424+
/* Step 6: Apply startup mode from config */
425+
HandleStartupMode(hwnd);
426+
LOG_INFO("Reset: Startup mode applied: %s", CLOCK_STARTUP_MODE);
427+
428+
/* Step 7: Reset UI runtime state */
382429
CLOCK_EDIT_MODE = FALSE;
383430
SetClickThrough(hwnd, TRUE);
384-
LOG_INFO("Reset: UI runtime state reset");
385-
386-
/* Force timeout action to default (override config's preserve logic) */
387431
CLOCK_TIMEOUT_ACTION = TIMEOUT_ACTION_MESSAGE;
432+
LOG_INFO("Reset: UI runtime state reset");
388433

389-
/* Step 5.6: Reload font (config sets FONT_FILE_NAME, but font needs to be loaded) */
434+
/* Step 8: Reload font */
390435
if (IsFontsFolderPath(FONT_FILE_NAME)) {
391436
const char* relativePath = ExtractRelativePath(FONT_FILE_NAME);
392437
if (relativePath) {
@@ -401,16 +446,16 @@ static LRESULT CmdResetDefaults(HWND hwnd, WPARAM wp, LPARAM lp) {
401446
}
402447
}
403448

404-
/* Step 6: Refresh UI to match new config */
449+
/* Step 9: Refresh UI to match new config */
405450
RecalculateWindowSize(hwnd);
406451
ShowWindow(hwnd, SW_SHOW);
407452
ResetTimerWithInterval(hwnd);
408453

409-
/* Step 7: Re-enable redraw and refresh display */
454+
/* Step 10: Re-enable redraw and refresh display */
410455
SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
411456
RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
412457

413-
/* Step 8: Re-register hotkeys with new config */
458+
/* Step 11: Re-register hotkeys with new config */
414459
RegisterGlobalHotkeys(hwnd);
415460

416461
LOG_INFO("========== Reset All Settings operation completed ==========\n");

0 commit comments

Comments
 (0)