Skip to content

Commit 647b3a8

Browse files
committed
Fix: Added copilots suggestions
**Major Changes:** 1. **Window Subclassing System Overhaul (Comments [1](ramensoftware#2267 (comment)), [10](ramensoftware#2267 (comment) - Replaced `SetWindowLongPtrW` with `WindhawkUtils::SetWindowSubclassFromAnyThread` for all window subclassing - Updated subclass callbacks to use the standard `DWORD_PTR` refData parameter (matches `SetWindowSubclass`/WindhawkUtils expectations) - Removed fallback ListView subclassing (SHELLDLL_DefView handles input properly) - Added proper cleanup with `RemoveWindowSubclassFromAnyThread` in WM_NCDESTROY handlers - Updated function signatures to use `DefSubclassProc` instead of `CallWindowProcW` 2. **Process Isolation (Comments [4](ramensoftware#2267 (comment)), [6](ramensoftware#2267 (comment) - Added `IsWindowInCurrentProcess()` helper function - Now verifies ListView and ShellView belong to current explorer.exe process - Added a process check for `SHELLDLL_DefView` under Progman; if not current-process, falls back to WorkerW search - Prevents the mod from affecting other explorer processes 3. **Settings API Fixes (Comments [2](ramensoftware#2267 (comment)), [3](ramensoftware#2267 (comment) - Fixed `Wh_GetIntSetting` calls to use single argument (removed incorrect TRUE parameter) - Added `Wh_FreeStringSetting` to properly free string memory - Changed settings structure to nested `modifierKeys` object (matches Windhawk patterns) 4. **Initialization Improvements (Comments [7](ramensoftware#2267 (comment)), [8](ramensoftware#2267 (comment) - Removed `Sleep(2000)` hack from `Wh_ModAfterInit` - Removed unnecessary `bInitialized` flag - Added `EnsureValidListView()` helper for dynamic ListView validation - ListView now re-discovered on-demand if window becomes invalid - After settings changes, re-discovers shell/ListView handles and refreshes visibility state before re-establishing subclasses (hotkeys keep working) 5. **Code Cleanup (Comments [5](ramensoftware#2267 (comment)), [9](ramensoftware#2267 (comment) - Removed redundant `RestoreIconsToVisible` call from `Wh_ModBeforeUninit` (already in Wh_ModUninit) - Added null checks and proper error handling throughout - Added `ToUpperCase()` helper for case-insensitive key matching - WM_CHAR handling now requires Ctrl when configured and respects Alt, preventing false positives from control codes **Additional Improvements:** - Added `<commctrl.h>` and `<windhawk_utils.h>` includes - Added `--optimize=0 --debug` compiler options - Enhanced documentation in readme with modifier key details - Better logging and error messages throughout
1 parent 72fd67c commit 647b3a8

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

mods/desktop-icons-toggle.wh.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ BOOL SetupHotkeyHandling();
8989
void CleanupHotkeyHandling();
9090
void RestoreIconsToVisible();
9191
BOOL IsWindowInCurrentProcess(HWND hwnd);
92-
LRESULT CALLBACK CustomShellViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass);
93-
LRESULT CALLBACK CustomListViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass);
94-
LRESULT CALLBACK CustomProgmanWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass);
92+
LRESULT CALLBACK CustomShellViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData);
93+
LRESULT CALLBACK CustomListViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData);
94+
LRESULT CALLBACK CustomProgmanWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData);
9595

9696
// Helper function to convert character to uppercase
9797
WCHAR ToUpperCase(WCHAR ch) {
@@ -173,6 +173,10 @@ HWND FindDesktopListView() {
173173

174174
// Find SHELLDLL_DefView under Program Manager
175175
HWND hShellView = FindWindowExW(hProgman, nullptr, L"SHELLDLL_DefView", nullptr);
176+
if (hShellView && !IsWindowInCurrentProcess(hShellView)) {
177+
Wh_Log(L"SHELLDLL_DefView under Progman not in current process, ignoring");
178+
hShellView = nullptr;
179+
}
176180

177181
// If not found under Progman, try WorkerW windows
178182
if (!hShellView) {
@@ -251,7 +255,7 @@ void ToggleDesktopIcons() {
251255
}
252256

253257
// Custom window procedure for SHELLDLL_DefView
254-
LRESULT CALLBACK CustomShellViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass) {
258+
LRESULT CALLBACK CustomShellViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData) {
255259
switch (uMsg) {
256260
case WM_KEYDOWN:
257261
case WM_SYSKEYDOWN:
@@ -264,14 +268,22 @@ LRESULT CALLBACK CustomShellViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPA
264268

265269
case WM_CHAR:
266270
// Handle Ctrl+character combinations that produce control codes
267-
if (wParam > 0 && wParam < 32) {
271+
if (wParam > 0 && wParam < 32 && g_state.bUseCtrl) {
272+
SHORT ctrlState = GetAsyncKeyState(VK_CONTROL);
273+
if ((ctrlState & 0x8000) == 0) {
274+
break; // Control not pressed; ignore
275+
}
276+
268277
WCHAR expectedChar = (WCHAR)(wParam + 64); // Convert control code back to character
269278
WCHAR upperExpected = ToUpperCase(expectedChar);
270279
WCHAR upperConfig = ToUpperCase(g_state.cHotkeyChar);
271280

272281
if (upperExpected == upperConfig) {
282+
BOOL altRequired = g_state.bUseAlt;
273283
SHORT altState = GetAsyncKeyState(VK_MENU);
274-
if ((altState & 0x8000) && g_state.bUseAlt) {
284+
BOOL altPressed = (altState & 0x8000) != 0;
285+
286+
if (!altRequired || altPressed) {
275287
Wh_Log(L"Hotkey detected via WM_CHAR in ShellView window");
276288
ToggleDesktopIcons();
277289
return 0;
@@ -289,7 +301,7 @@ LRESULT CALLBACK CustomShellViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPA
289301
}
290302

291303
// Custom window procedure for ListView
292-
LRESULT CALLBACK CustomListViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass) {
304+
LRESULT CALLBACK CustomListViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData) {
293305
switch (uMsg) {
294306
case WM_KEYDOWN:
295307
case WM_SYSKEYDOWN:
@@ -309,7 +321,7 @@ LRESULT CALLBACK CustomListViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR
309321
}
310322

311323
// Custom window procedure for Program Manager (for global hotkey handling)
312-
LRESULT CALLBACK CustomProgmanWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass) {
324+
LRESULT CALLBACK CustomProgmanWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD_PTR dwRefData) {
313325
switch (uMsg) {
314326
case WM_HOTKEY:
315327
if (wParam == HOTKEY_ID) {
@@ -545,6 +557,16 @@ void Wh_ModSettingsChanged() {
545557

546558
// Reload settings
547559
LoadSettings();
560+
561+
// Refresh handles after settings change
562+
g_state.hDesktopListView = FindDesktopListView();
563+
if (g_state.hDesktopListView && !IsWindowInCurrentProcess(g_state.hDesktopListView)) {
564+
Wh_Log(L"Desktop ListView belongs to a different process after settings change, ignoring");
565+
g_state.hDesktopListView = nullptr;
566+
}
567+
if (g_state.hDesktopListView) {
568+
g_state.bIconsVisible = IsWindowVisible(g_state.hDesktopListView);
569+
}
548570

549571
// Setup hotkey handling with new settings
550572
SetupHotkeyHandling();

0 commit comments

Comments
 (0)