Skip to content

v1.3.3 — the input hold was never actually on

Choose a tag to compare

@desteny-dev desteny-dev released this 01 Aug 17:02
· 20 commits to main since this release

The input hold was never actually on

Install this one. Reported in one sentence, and it undoes an assumption the whole design rested on:

"I could still move my mouse and type while you had my window."

A low-level hook is delivered to the message queue of the thread that installed it. The commands from the server arrive on the overlay's stdin thread — and that thread sits blocked in a read, with no message loop at all. So SetWindowsHookEx succeeded, returned a valid handle, and the callbacks were never dispatched. Windows drops such a hook after LowLevelHooksTimeout and says nothing.

Nothing failed. Nothing was logged. self_test reported the overlay as present, because it checked that the file existed. The pulse drew, the notification appeared, the block opened and closed — and the person's keyboard and mouse were free the entire time, while every layer above was certain they were held.

The fix is one line of architecture

The protocol thread now only records a wish; tick() — which runs on the message-loop thread — installs and removes the hooks. That is the one thread that can receive the callbacks, so it is the only correct place.

And it now says so. The overlay reports hooks:1 / hooks:0 back to the server, and set_guard block:'start' returns input_held. When Windows refuses the hooks, the reply says the screen is shared and to behave accordingly — instead of promising a hold that is not there.

Ending a block now tells you what came back

Found in the same live test: the release wrote its result into _RUECKGABE on every block, with a comment saying tools copy it into their reply. Nothing did. The claim "your focus is restored is a measurement, not a promise" was true of the measurement and false of the reporting.

set_guard block:'end' now returns handed_back:

field
foreground_restored did the call succeed
their_window the window this block owed them
in_front_now what is actually in front, measured after the restore
caret_restored did the text cursor come back with it
attempts how many tries it took

in_front_now is the one that matters. foreground_restored answers whether the call worked; in_front_now answers where the person is looking.

Third defect in this project found by the same rule: a function that does not report whether it worked will eventually stop working, and nobody will notice.

Two downloads — take the one for your AI

Download For How
pc-screen-control.mcpb Claude Desktop Settings → Extensions → Advanced → Install extension
pc-screen-control-gpt.zip ChatGPT desktop, Codex, Cursor, VS Code, Cline, Zed Extract, double-click INSTALL-FOR-GPT.bat, restart

Same server.py, same bundled libraries, same 34 tools. Only the wrapper differs.

Install

Claude: remove the old version first (Settings → Extensions), quit Claude completely including the tray icon, install the .mcpb, start twice. Run self_test — it should report 1.3.3, all green.

ChatGPT / Codex: extract the zip, double-click INSTALL-FOR-GPT.bat, restart ChatGPT.

Needs Windows and Python 3.9+ with "Add python.exe to PATH" ticked.

Verify the downloads (optional)

pc-screen-control.mcpb
  SHA-256: 4c55954cfd2afa0393cab70f9404ed9bfb4c83b5a6d48e1bdab391101473272e
  Size:    7762404 bytes

pc-screen-control-gpt.zip
  SHA-256: 4bfe93bea4eb392e690b4487687b375f9fcb996954b3c5e3d096c89ec3cc0655
  Size:    7668773 bytes