Skip to content

11macos shake to find cursor#4704

Open
samiulislam16 wants to merge 18 commits into
ramensoftware:mainfrom
samiulislam16:11macos-shake-to-find-cursor
Open

11macos shake to find cursor#4704
samiulislam16 wants to merge 18 commits into
ramensoftware:mainfrom
samiulislam16:11macos-shake-to-find-cursor

Conversation

@samiulislam16

Copy link
Copy Markdown

Mod authorship

If this pull request introduces a new mod, please complete the section below.

This mod was created by:

    • The submitter, without AI assistance
    • [ x] The submitter, with AI assistance
    • Claude
    • ChatGPT
    • [ x] Gemini
    • Another AI (please specify):
    • Other (please specify):

Please select the options that best apply. Your selection does not affect the acceptance criteria, but it helps reviewers understand the context of the code and provide relevant feedback.

@m417z

m417z commented Jul 7, 2026

Copy link
Copy Markdown
Member

Submission review

Note: This review was done by Claude, and then refined manually. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding.

Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them.


1. Run this as a tool mod (windhawk.exe), not injected into explorer.exe. The mod has no function hooks — it only uses process-agnostic APIs (GetPhysicalCursorPos, SetSystemCursor, a polling thread) and completely ignores Explorer's own state. Injecting it into explorer.exe has real downsides here:

  • There can be more than one explorer.exe (e.g. when "launch folder windows in a separate process" is enabled). Each injected instance spawns its own polling thread and they'll fight over SetSystemCursor/SPI_SETCURSORS — one enlarges while another restores. The tool-mod launcher gives you a single dedicated instance and removes the need for any home-grown deduplication.
  • A crash or hang in the mod (it runs a Sleep loop) destabilizes the whole shell.

Convert it: set @include windhawk.exe, rename Wh_ModInit/Wh_ModSettingsChanged/Wh_ModUninitWhTool_*, and paste the launcher boilerplate verbatim. See the wiki: Mods as tools, and a working reference at the bottom of mods/explorer-folder-hover-menu.wh.cpp.

2. Remove the redundant/fragile process-path guard. In Wh_ModInit:

// Strict isolation enforcement constraint layout paths
wchar_t processPath[MAX_PATH];
GetModuleFileNameW(NULL, processPath, MAX_PATH);
if (wcsstr(processPath, L"explorer.exe") == nullptr) {
    return TRUE;
}

@include explorer.exe already scopes injection to Explorer, so this check is dead code — and wcsstr is a loose substring match that would also pass for a path like ...\explorer.exe.bak\foo.exe. The comment above it is also meaningless AI-generated filler. Drop the whole block (and once you move to @include windhawk.exe it has to go anyway).

3. CreateScaledCursor doesn't handle monochrome cursors and never checks GetObject. For a monochrome cursor (e.g. the classic cursor scheme), GetIconInfo returns iconInfo.hbmColor == NULL with all data in a double-height hbmMask. Here:

BITMAP bmColor;
GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor);   // fails silently, bmColor left uninitialized
int newWidth  = (int)(bmColor.bmWidth  * scale);          // garbage dimensions
int newHeight = (int)(bmColor.bmHeight * scale);

GetObject fails, bmColor is read uninitialized (UB), and the garbage width/height feed CreateCompatibleBitmap — a broken cursor at best, a wild allocation size at worst. Check the GetObject return, and handle the hbmColor == NULL case (fall back to hbmMask, remembering it's two stacked masks for monochrome cursors).

4. @name has a stray 11 prefix — "11macOS Shake to Find Cursor" (a leftover from the earlier 11macos-... filename), which doesn't match the README title "Shake to Find Cursor". Consider "macOS Shake to Find Cursor".

5. No README visual. This is a very visual effect; a short GIF of the cursor growing/shrinking would help a lot in the catalog. Only i.imgur.com and raw.githubusercontent.com are allowed image hosts.

Optional improvements

Minor polish — none of this affects users, so it's your call.

  • Unused library. @compilerOptions -luser32 -lgdi32 -lshcore links shcore but the mod calls no shcore/DPI API. Drop -lshcore.
  • g_cfg is written on the settings-change thread and read on the polling thread with no synchronization. It's benign (a torn read just uses a stale value for one iteration, and only on a settings change), but if you want it clean, load into a local or guard it.

Functionality notes

Non-critical observations about the feature behavior itself.

  • Only the arrow (OCR_NORMAL) is enlarged. If you're hovering over something showing a different cursor (I-beam, hand, resize, busy), the shake won't enlarge it — macOS enlarges whatever cursor is currently shown. Enlarging the other OCR_* cursors (or the currently-displayed one) would match the original feature more closely.
  • Continuous 60 Hz polling burns a little CPU/battery even when the mouse is idle. Note that it's load-bearing for the auto-restore timing (the else-branch restore only fires because samples keep arriving), so a pure WH_MOUSE_LL hook wouldn't be a drop-in replacement without a timer. Fine as-is — just flagging the cost.
  • Mask scaling quality. The mask is StretchBlt'd into a screen-DC-compatible (color) bitmap with SRCCOPY and the default stretch mode. Using a monochrome mask bitmap and HALFTONE/COLORONCOLOR (with SetStretchBltMode) would give cleaner edges when scaling the cursor up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants