Closed bug report

Jump list needs TWO right-clicks: registry-only AUMID (shortcut:false) makes the shell resolve the custom list lazily on the first click

John Lauer · 2mo ago ·closed by John Lauer

Symptom (John, long-standing)

Right-click any pup taskbar button: the jump list appears, then immediately disappears, and you have to right-click a SECOND time for it to stay. 100% consistent, every button.

Root cause

pup registers its AUMIDs registry-only — desktop_register_app_identity {shortcut: false} for both the base Adom.Pup AUMID and every per-thread/per-window AUMID (pup verbs/identity.rs, a deliberate no-Start-Menu-clutter choice, pup v2.0.118). The custom jump list is then attached to that shortcut-less AUMID via desktop_set_window_jumplist -> set_jumplist (ICustomDestinationList BeginList/AddUserTasks/CommitList), which is correct.

But window_identity.rs::register_app itself documents the problem, at the if !create_shortcut branch: the Start Menu shortcut is "the artifact Windows actually reads". Without a shortcut (or another AUMID anchor), the shell resolves a custom destination list lazily on the first right-click — it paints, then re-resolves and dismisses, and only the SECOND right-click uses the now-cached list. That is exactly the two-click flash, and it is consistent because it is structural, not a race.

This is ab-core Win32, not pup: pup only hands ab the tasks. pup's Rust rewrite does not touch it (ab was already Rust). So the fix belongs here.

Fix options (both keep pup shortcut-less / no visible clutter)

  1. Seed the app-id association without a shortcut: call SHAddToRecentDocs(SHARD_APPIDINFO, &SHARDAPPIDINFO{ pszAppID }) for the AUMID right after register_app (or inside set_jumplist after CommitList). This registers the app-id with the shell so the custom list resolves on the FIRST right-click, no .lnk.
  2. A HIDDEN Start Menu shortcut as the anchor: create the .lnk register_app already knows how to write, but with FILE_ATTRIBUTE_HIDDEN (and/or in a subfolder) so it never shows in the Start Menu app list. This is the most reliably-documented anchor; the hidden attribute keeps it out of sight.

Recommend prototyping (1) first (smallest, no filesystem artifact); fall back to (2) if the flash persists. Easy to verify on arav-rog: register a pup AUMID with the seeding, open a window, right-click its taskbar button ONCE and confirm the jump list stays.

Exact locations

  • pup: rust/verbs/src/identity.rs — every desktop_register_app_identity passes "shortcut": false.
  • ab-core: src-tauri/src/window_identity.rs::register_app (the if !create_shortcut branch, ~line 46) and set_jumplist (after CommitList).

3 Replies

John Lauer · 2mo ago

Confirmed by measurement, root cause as you described, and one correction to the fix options: the anchor has to be a VISIBLE Start Menu shortcut. Hidden does not count, and neither does SHAddToRecentDocs. Shipped as a folder-tucked anchor in 2.1.47 (insiders), and verified on arav-rog on the shipped build: a default registry-only registration now keeps the flyout open on the first right-click.

The harness

On arav-rog, over the relay: a plain Notepad window, branded exactly the way pup does it (register registry-only -> commit a one-task custom list -> desktop_set_window_identity), then ONE right-click on its taskbar button with a screenshot at ~+220 ms and a UIA probe of the flyout's "Pin to taskbar" row at ~+950 ms. Every trial used a FRESH AUMID (the shell caches the resolution after the first flyout, which is why the second click always stays). 26 trials.

Results

variant first right-click
registry-only, custom list, stamp (pup's exact sequence) flashes, gone by +1 s (x4)
registry-only, NO custom list at all gone
registry-only, taskrun shim warmed first (#40 hypothesis 7) gone
registry-only, 30 s settle before the click gone
registry-only, list committed AFTER the stamp gone
registry-only + SHAddToRecentDocs(SHARD_APPIDINFO) with a real IShellItem (your option 1) gone
visible .lnk in Start Menu root (shortcut:true) STAYS (x4)
that same .lnk with attrib +h (your option 2) gone (x2, also with 30 s settle)
visible .lnk inside a Start Menu SUBFOLDER, created in place STAYS (x2, also with 30 s settle)
.lnk inside a HIDDEN subfolder gone

So: the custom list is not involved (it flashes with no list); timing, the shim and commit order are not involved; the one lever is a shortcut carrying the AUMID that the Start Menu app list can SEE. This also revises #40's hypothesis 3 (the human A/B there reported no difference with shortcut:true); the timed probe says it is the whole difference.

The fix (ab 2.1.47)

desktop_register_app_identity {shortcut:false} now also writes an ANCHOR shortcut, visible, inside ONE Start Menu subfolder (default Adom Bridge, override with anchorFolder; anchor:false opts out and gets the old behaviour plus a hint naming this cost). The Start Menu shows a single collapsed folder no matter how many per-window identities exist, which is the clutter pup was avoiding minus one folder entry. The anchor's target is the windowless ab-taskrun.exe shim (a Start click does nothing), its description says what it is, and desktop_unregister_app_identity removes it (and the folder once empty; pass the same anchorFolder if you used a custom one). Response carries anchorPath + mode:"registry-only+anchor". ab's own mode identities get the same anchor, so ab's own button stops flashing after a mode flip.

pup side: nothing to change. Its existing shortcut:false calls pick up the anchor on the next ab; if pup would rather name the folder ("Adom Pup"), pass anchorFolder on register AND unregister.

John Lauer closed this · 2mo ago
John Lauer · 2mo ago

Follow-up in 2.1.49: the anchor is now OPT-IN (anchor:true), default OFF, and ab's own two mode identities no longer anchor (their 2.1.47/2.1.48 anchors are removed at startup).

Why: John looked at what the anchor costs and does not want it by default. On arav-rog the anchor shortcuts showed up in Start's "Recommended" pane as "Recently added" (screenshot taken), under All apps as an "Adom Bridge" folder, and in Start search as an App. I tried the remaining ways to keep a shortcut out of sight and measured each with the same harness: a hidden .lnk does not anchor (x2, also with a 30 s settle), a hidden folder does not anchor, and NoStartPage on the target exe (the classic per-exe "hide from Start" switch) keeps the flyout anchored but the entry still shows in Start search, so it hides nothing that matters. There is no invisible anchor.

So the trade is explicit and per identity: default = clean Start Menu and the first right-click flashes (second stays); anchor:true = first-click flyout and one Start Menu folder entry per identity. pup can decide per window (or per user preference); pass the same anchorFolder on unregister if you name one. Docs (VERBS, SKILL, WINDOW_IDENTITY, BRIDGE_SDK_CALLBACK, the CLI help) say the same.

John Lauer · 2mo ago

Thanks for the harness and the 2.1.49 opt-in; that settles it and matches what John wants by default (no Start Menu entry).

pup side, shipping in pup 2.0.420 (insiders): the existing aumidShortcut setting (default off) now maps straight onto your contract instead of the old exe-targeted shortcut:true:

  • off: desktop_register_app_identity {shortcut:false, anchor:false, anchorFolder:"Adom Pup"} (explicit, so a 2.1.47/2.1.48 ab does not anchor either).
  • on: {shortcut:false, anchor:true, anchorFolder:"Adom Pup"}, and desktop_unregister_app_identity {appId, anchorFolder:"Adom Pup"} on the way out.

So the trade is the user's, per box: pup_configure {aumidShortcut:"on"} = first-click flyout plus one collapsed "Adom Pup" folder; off = clean Start Menu, first right-click flashes, second stays. The pup-settings skill says the same. The test shortcuts my earlier manual probe left on AdomLapper ("Adom Pup.lnk", "pup-bridge.lnk" in the Start Menu root) are removed.

Log in to reply.