Skip to content

Offload a card from the Explorer right-click menu, with a drawn icon - #11

Open
owenpkent wants to merge 2 commits into
stall-watchdogfrom
shell-context-menu
Open

owenpkent wants to merge 2 commits into
stall-watchdogfrom
shell-context-menu

Conversation

@owenpkent

Copy link
Copy Markdown
Owner

Summary

Right-clicking a card and choosing "Offload this card" is how an operator expects to reach a tool like this. The app had no shell presence at all.

offloader shell --install      # add it, and write the icon
offloader shell                # say whether it is installed
offloader shell --uninstall    # remove it

Adds Offload this card on a drive and Offload this folder on a directory, each opening the app with that path already in the source field.

Decisions worth reviewing

  • HKEY_CURRENT_USER, not HKEY_CLASSES_ROOT. No administrator, nothing another account can see, and uninstalling is the deletion of two keys.
  • %V, not %1 — a drive root is the case this exists for, and %1 does not carry it.
  • Prefers the windowed offloader-gui so the entry opens the app rather than flashing a console. Locating it goes through sysconfig, not a guess beside sys.executable: a --user install puts scripts under the user scheme, nowhere near the interpreter. My first attempt guessed and missed exactly that, falling back to pythonw -m.
  • MainWindow(source=...) — without the path arriving pre-filled the menu entry would be pointless.

The icon is drawn, not shipped

Same principle as reports/icons.py draws the PDF's glyphs: the repository carries no binary artwork. shellicon.py renders the report header's filmstrip to a multi-size .ico using zlib and struct alone — PNG encoding and the icon directory by hand. No Pillow, no new dependency (base deps stay xxhash and reportlab).

Small sizes simplify rather than shrink: six sprocket holes and three outlined frames are mush at 16 px, so the counts drop and the frames fill. The desktop app now uses the same mark as its window icon, built in memory, so it needs no file on disk to launch.

Honest limitation, surfaced in the tool

A registry verb cannot appear in the short Windows 11 menu — that list is built from packaged IExplorerCommand COM handlers. So the entry sits under "Show more options". The install command prints this, because a menu entry the operator cannot find is indistinguishable from one that failed to install.

Test plan

  • tests/test_shell.py — 12 tests: ICO directory vs payload sizes agree, PNG chunk CRCs valid, the mark is actually drawn (not a blank tile passing structural checks), corners transparent, the plan is right (%V, quoted launcher, both classes), off-Windows raises rather than pretending
  • Registry round-trip against real HKCU, under a test-only key so a developer's own entry is neither read nor removed
  • Full suite 500 passed, 3 skipped; ruff clean
  • Installed for real; reg query confirms both verbs, icon path and command; offloader-gui.exe launches and stays up with a path argument

Right-clicking a drive and choosing "Offload this card" is how an operator
expects to reach a tool like this, and the app had no shell presence at all.

The verbs live under HKEY_CURRENT_USER\Software\Classes, which is the point of
the choice: installing needs no administrator, touches nothing another account
can see, and uninstalling is the deletion of two keys. The command line uses
%V rather than %1, because a drive root is the case the entry exists for and
%1 does not carry it, and it prefers the windowed offloader-gui script so
clicking the entry opens the app rather than flashing a console. Finding that
script goes through sysconfig rather than guessing beside sys.executable: a
--user install puts it under the user scheme, nowhere near the interpreter,
which is exactly the layout a first attempt missed.

The window now takes an optional source, so the right-clicked path arrives
already in the field. Without that the menu entry would be pointless.

The icon is drawn, not shipped, for the same reason the PDF's glyphs are: the
filmstrip from the report header, rendered to a multi-size .ico with zlib and
struct alone. No Pillow, no new dependency, no binary artwork in the
repository, and the shell entry, the window and the report header now agree on
what this tool looks like. Small sizes simplify rather than shrink, since six
sprocket holes and three outlined frames are mush at 16 px.

What a registry verb cannot do is appear in the short Windows 11 menu, which
is built from packaged COM handlers. The command says so, because a menu entry
the operator cannot find is indistinguishable from one that failed to install.
Locating the launcher is the part of this that was actually wrong once: the
first version guessed beside sys.executable and missed a --user install,
whose entry points live under the user scheme, so it never found the GUI
script and fell back to the module without saying so. It only had an
assertion that the result was quoted. Now the user scheme is required to be
searched, the interpreter's own directory to win over it, duplicates to be
absent, and both the preferred-script and fallback paths to be exercised.

Uninstall gets the test it needed most: DeleteKey refuses a key with
children, so the command subkey has to go first, and the wrong order leaves
the verb's parent behind with its command intact. That is worse than not
removing it at all, because the menu item survives while installed() keeps
answering yes. Re-installing over an existing entry is pinned too, since an
upgrade has to repoint the command rather than fail.

The icon gains the checks its size-dependent drawing implies: 256 written as
zero in the directory, since the field is one byte; the mark staying inside
its own canvas at every size, because the canvas silently drops pixels that
fall outside and a clipped mark would have no other symptom; the frame count
dropping as the tile shrinks, which is the whole claim about simplifying
rather than scaling; and a radius larger than the box being clamped.

@owenpkent owenpkent left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed per-user shell registration/removal, command quoting, source-path dispatch, icon generation, and the GUI handoff. No actionable defect found in this diff.

The review focused on keeping shell registration scoped to the application's own keys and ensuring the Explorer-selected path reaches the source-selection flow without starting a transfer implicitly. The generated icon is an application asset and does not add a runtime media-tool dependency.

Validation: 49 targeted tests passed on this head and git diff --check passed. Three registry round-trip tests could not run because the sandbox denied HKCU writes; those local checks remain unverified here, although the recorded PR CI checks are green. No interactive Explorer verification was performed.

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.

1 participant