From eba963074aa5107168237a765b275ffec47ad461 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:56:32 +0000 Subject: [PATCH 1/5] Initial plan From 893af16bcf416c8878118cd41c36671efeab1aa9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:58:49 +0000 Subject: [PATCH 2/5] Add window size and position persistence to registry Co-authored-by: ForLoopCodes <89027512+ForLoopCodes@users.noreply.github.com> --- src/core/types.h | 4 +++ src/main.cpp | 21 ++++++++++- src/modules/settings.cpp | 76 ++++++++++++++++++++++++++++++++++++++++ src/modules/settings.h | 2 ++ 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/core/types.h b/src/core/types.h index b3fcbfd..3cbd585 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -126,6 +126,10 @@ struct AppState std::deque recentFiles; BackgroundSettings background; std::wstring customIconPath; + int windowX = CW_USEDEFAULT; + int windowY = CW_USEDEFAULT; + int windowWidth = 640; + int windowHeight = 480; }; typedef BOOL(WINAPI *fnAllowDarkModeForWindow)(HWND hWnd, BOOL allow); diff --git a/src/main.cpp b/src/main.cpp index 376aa4b..027fe4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -499,6 +499,24 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) g_state.closing = false; return 0; case WM_DESTROY: + // Save window position and size before destroying + { + WINDOWPLACEMENT wp = {}; + wp.length = sizeof(WINDOWPLACEMENT); + if (GetWindowPlacement(hwnd, &wp)) + { + if (wp.showCmd == SW_SHOWNORMAL) + { + // Save only if window is not maximized or minimized + RECT rect = wp.rcNormalPosition; + g_state.windowX = rect.left; + g_state.windowY = rect.top; + g_state.windowWidth = rect.right - rect.left; + g_state.windowHeight = rect.bottom - rect.top; + } + } + SaveWindowSettings(); + } if (g_state.hFont) { DeleteObject(g_state.hFont); @@ -556,6 +574,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdSh } LoadFontSettings(); + LoadWindowSettings(); WNDCLASSEXW wc = {}; wc.cbSize = sizeof(wc); @@ -578,7 +597,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdSh const auto &lang = GetLangStrings(); std::wstring initialTitle = lang.untitled + L" - " + lang.appName; g_hwndMain = CreateWindowExW(0, L"NotepadClass", initialTitle.c_str(), - WS_OVERLAPPEDWINDOW | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, + WS_OVERLAPPEDWINDOW | WS_MAXIMIZEBOX, g_state.windowX, g_state.windowY, g_state.windowWidth, g_state.windowHeight, nullptr, nullptr, hInstance, nullptr); g_hAccel = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_ACCEL)); ShowWindow(g_hwndMain, nCmdShow); diff --git a/src/modules/settings.cpp b/src/modules/settings.cpp index 3d43bb0..f6cc118 100644 --- a/src/modules/settings.cpp +++ b/src/modules/settings.cpp @@ -25,6 +25,10 @@ #define FONT_ITALIC_VALUE L"FontItalic" #define FONT_UNDERLINE_VALUE L"FontUnderline" #define ALWAYS_ON_TOP_VALUE L"AlwaysOnTop" +#define WINDOW_X_VALUE L"WindowX" +#define WINDOW_Y_VALUE L"WindowY" +#define WINDOW_WIDTH_VALUE L"WindowWidth" +#define WINDOW_HEIGHT_VALUE L"WindowHeight" #define MIN_FONT_SIZE 8 #define MAX_FONT_SIZE 72 @@ -119,3 +123,75 @@ void SaveFontSettings() RegCloseKey(hKey); } } + +void LoadWindowSettings() +{ + HKEY hKey; + if (RegOpenKeyExW(HKEY_CURRENT_USER, SETTINGS_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + DWORD x = 0; + DWORD size = sizeof(x); + if (RegQueryValueExW(hKey, WINDOW_X_VALUE, nullptr, nullptr, reinterpret_cast(&x), &size) == ERROR_SUCCESS) + { + g_state.windowX = static_cast(x); + } + + DWORD y = 0; + size = sizeof(y); + if (RegQueryValueExW(hKey, WINDOW_Y_VALUE, nullptr, nullptr, reinterpret_cast(&y), &size) == ERROR_SUCCESS) + { + g_state.windowY = static_cast(y); + } + + DWORD width = 0; + size = sizeof(width); + if (RegQueryValueExW(hKey, WINDOW_WIDTH_VALUE, nullptr, nullptr, reinterpret_cast(&width), &size) == ERROR_SUCCESS) + { + if (width > 0) + { + g_state.windowWidth = static_cast(width); + } + } + + DWORD height = 0; + size = sizeof(height); + if (RegQueryValueExW(hKey, WINDOW_HEIGHT_VALUE, nullptr, nullptr, reinterpret_cast(&height), &size) == ERROR_SUCCESS) + { + if (height > 0) + { + g_state.windowHeight = static_cast(height); + } + } + + RegCloseKey(hKey); + } +} + +void SaveWindowSettings() +{ + HKEY hKey; + if (RegCreateKeyExW(HKEY_CURRENT_USER, SETTINGS_KEY, 0, nullptr, 0, KEY_WRITE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) + { + DWORD x = static_cast(g_state.windowX); + RegSetValueExW(hKey, WINDOW_X_VALUE, 0, REG_DWORD, + reinterpret_cast(&x), + sizeof(x)); + + DWORD y = static_cast(g_state.windowY); + RegSetValueExW(hKey, WINDOW_Y_VALUE, 0, REG_DWORD, + reinterpret_cast(&y), + sizeof(y)); + + DWORD width = static_cast(g_state.windowWidth); + RegSetValueExW(hKey, WINDOW_WIDTH_VALUE, 0, REG_DWORD, + reinterpret_cast(&width), + sizeof(width)); + + DWORD height = static_cast(g_state.windowHeight); + RegSetValueExW(hKey, WINDOW_HEIGHT_VALUE, 0, REG_DWORD, + reinterpret_cast(&height), + sizeof(height)); + + RegCloseKey(hKey); + } +} diff --git a/src/modules/settings.h b/src/modules/settings.h index ab7bec9..6efbefc 100644 --- a/src/modules/settings.h +++ b/src/modules/settings.h @@ -17,3 +17,5 @@ void LoadFontSettings(); void SaveFontSettings(); +void LoadWindowSettings(); +void SaveWindowSettings(); From 05c85f323588ab44d3cc2a007271ec2f799a0041 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:00:18 +0000 Subject: [PATCH 3/5] Improve window position handling for multi-monitor and off-screen scenarios Co-authored-by: ForLoopCodes <89027512+ForLoopCodes@users.noreply.github.com> --- src/main.cpp | 15 ++++++--------- src/modules/settings.cpp | 14 +++++++++++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 027fe4f..0f6c911 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -505,15 +505,12 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) wp.length = sizeof(WINDOWPLACEMENT); if (GetWindowPlacement(hwnd, &wp)) { - if (wp.showCmd == SW_SHOWNORMAL) - { - // Save only if window is not maximized or minimized - RECT rect = wp.rcNormalPosition; - g_state.windowX = rect.left; - g_state.windowY = rect.top; - g_state.windowWidth = rect.right - rect.left; - g_state.windowHeight = rect.bottom - rect.top; - } + // Always save the normal position, even if maximized or minimized + RECT rect = wp.rcNormalPosition; + g_state.windowX = rect.left; + g_state.windowY = rect.top; + g_state.windowWidth = rect.right - rect.left; + g_state.windowHeight = rect.bottom - rect.top; } SaveWindowSettings(); } diff --git a/src/modules/settings.cpp b/src/modules/settings.cpp index f6cc118..28a7b40 100644 --- a/src/modules/settings.cpp +++ b/src/modules/settings.cpp @@ -10,7 +10,7 @@ ███ ███ ▀ Settings management for persisting user preferences via Windows Registry. - Handles font name and font size storage and retrieval. + Handles font settings, always on top, window size and position storage and retrieval. */ #include "settings.h" @@ -165,6 +165,16 @@ void LoadWindowSettings() RegCloseKey(hKey); } + + // Validate that the window position is visible on at least one monitor + RECT rc = {g_state.windowX, g_state.windowY, g_state.windowX + g_state.windowWidth, g_state.windowY + g_state.windowHeight}; + HMONITOR hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONULL); + if (!hMonitor) + { + // Window would be off-screen, reset to default + g_state.windowX = CW_USEDEFAULT; + g_state.windowY = CW_USEDEFAULT; + } } void SaveWindowSettings() @@ -172,6 +182,8 @@ void SaveWindowSettings() HKEY hKey; if (RegCreateKeyExW(HKEY_CURRENT_USER, SETTINGS_KEY, 0, nullptr, 0, KEY_WRITE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) { + // REG_DWORD stores 32-bit values that can be interpreted as signed or unsigned + // Negative coordinates (multi-monitor setups) are preserved correctly DWORD x = static_cast(g_state.windowX); RegSetValueExW(hKey, WINDOW_X_VALUE, 0, REG_DWORD, reinterpret_cast(&x), From f32786f3b654e91184675c99fdf95e18d279a1f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:01:09 +0000 Subject: [PATCH 4/5] Fix signed/unsigned conversion for window coordinates using reinterpret_cast Co-authored-by: ForLoopCodes <89027512+ForLoopCodes@users.noreply.github.com> --- src/modules/settings.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/modules/settings.cpp b/src/modules/settings.cpp index 28a7b40..ffbe556 100644 --- a/src/modules/settings.cpp +++ b/src/modules/settings.cpp @@ -133,14 +133,16 @@ void LoadWindowSettings() DWORD size = sizeof(x); if (RegQueryValueExW(hKey, WINDOW_X_VALUE, nullptr, nullptr, reinterpret_cast(&x), &size) == ERROR_SUCCESS) { - g_state.windowX = static_cast(x); + // Reinterpret DWORD as signed int to correctly handle negative coordinates + g_state.windowX = *reinterpret_cast(&x); } DWORD y = 0; size = sizeof(y); if (RegQueryValueExW(hKey, WINDOW_Y_VALUE, nullptr, nullptr, reinterpret_cast(&y), &size) == ERROR_SUCCESS) { - g_state.windowY = static_cast(y); + // Reinterpret DWORD as signed int to correctly handle negative coordinates + g_state.windowY = *reinterpret_cast(&y); } DWORD width = 0; @@ -182,27 +184,22 @@ void SaveWindowSettings() HKEY hKey; if (RegCreateKeyExW(HKEY_CURRENT_USER, SETTINGS_KEY, 0, nullptr, 0, KEY_WRITE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) { - // REG_DWORD stores 32-bit values that can be interpreted as signed or unsigned - // Negative coordinates (multi-monitor setups) are preserved correctly - DWORD x = static_cast(g_state.windowX); + // Store coordinates as REG_DWORD, preserving bit pattern for negative values RegSetValueExW(hKey, WINDOW_X_VALUE, 0, REG_DWORD, - reinterpret_cast(&x), - sizeof(x)); + reinterpret_cast(&g_state.windowX), + sizeof(g_state.windowX)); - DWORD y = static_cast(g_state.windowY); RegSetValueExW(hKey, WINDOW_Y_VALUE, 0, REG_DWORD, - reinterpret_cast(&y), - sizeof(y)); + reinterpret_cast(&g_state.windowY), + sizeof(g_state.windowY)); - DWORD width = static_cast(g_state.windowWidth); RegSetValueExW(hKey, WINDOW_WIDTH_VALUE, 0, REG_DWORD, - reinterpret_cast(&width), - sizeof(width)); + reinterpret_cast(&g_state.windowWidth), + sizeof(g_state.windowWidth)); - DWORD height = static_cast(g_state.windowHeight); RegSetValueExW(hKey, WINDOW_HEIGHT_VALUE, 0, REG_DWORD, - reinterpret_cast(&height), - sizeof(height)); + reinterpret_cast(&g_state.windowHeight), + sizeof(g_state.windowHeight)); RegCloseKey(hKey); } From c7f73ed1d80f425a934c394a73318b3eaa9e960d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:02:02 +0000 Subject: [PATCH 5/5] Use static_cast for DWORD to int conversion with explanatory comments Co-authored-by: ForLoopCodes <89027512+ForLoopCodes@users.noreply.github.com> --- src/modules/settings.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/modules/settings.cpp b/src/modules/settings.cpp index ffbe556..c969c55 100644 --- a/src/modules/settings.cpp +++ b/src/modules/settings.cpp @@ -133,16 +133,16 @@ void LoadWindowSettings() DWORD size = sizeof(x); if (RegQueryValueExW(hKey, WINDOW_X_VALUE, nullptr, nullptr, reinterpret_cast(&x), &size) == ERROR_SUCCESS) { - // Reinterpret DWORD as signed int to correctly handle negative coordinates - g_state.windowX = *reinterpret_cast(&x); + // Cast DWORD to int - on Windows, this preserves negative coordinates correctly + g_state.windowX = static_cast(x); } DWORD y = 0; size = sizeof(y); if (RegQueryValueExW(hKey, WINDOW_Y_VALUE, nullptr, nullptr, reinterpret_cast(&y), &size) == ERROR_SUCCESS) { - // Reinterpret DWORD as signed int to correctly handle negative coordinates - g_state.windowY = *reinterpret_cast(&y); + // Cast DWORD to int - on Windows, this preserves negative coordinates correctly + g_state.windowY = static_cast(y); } DWORD width = 0; @@ -184,22 +184,26 @@ void SaveWindowSettings() HKEY hKey; if (RegCreateKeyExW(HKEY_CURRENT_USER, SETTINGS_KEY, 0, nullptr, 0, KEY_WRITE, nullptr, &hKey, nullptr) == ERROR_SUCCESS) { - // Store coordinates as REG_DWORD, preserving bit pattern for negative values + // Store coordinates as REG_DWORD - static_cast preserves bit pattern for negative values + DWORD x = static_cast(g_state.windowX); RegSetValueExW(hKey, WINDOW_X_VALUE, 0, REG_DWORD, - reinterpret_cast(&g_state.windowX), - sizeof(g_state.windowX)); + reinterpret_cast(&x), + sizeof(x)); + DWORD y = static_cast(g_state.windowY); RegSetValueExW(hKey, WINDOW_Y_VALUE, 0, REG_DWORD, - reinterpret_cast(&g_state.windowY), - sizeof(g_state.windowY)); + reinterpret_cast(&y), + sizeof(y)); + DWORD width = static_cast(g_state.windowWidth); RegSetValueExW(hKey, WINDOW_WIDTH_VALUE, 0, REG_DWORD, - reinterpret_cast(&g_state.windowWidth), - sizeof(g_state.windowWidth)); + reinterpret_cast(&width), + sizeof(width)); + DWORD height = static_cast(g_state.windowHeight); RegSetValueExW(hKey, WINDOW_HEIGHT_VALUE, 0, REG_DWORD, - reinterpret_cast(&g_state.windowHeight), - sizeof(g_state.windowHeight)); + reinterpret_cast(&height), + sizeof(height)); RegCloseKey(hKey); }