name: pup-jumplist description: How pup taskbar jump lists work AND the one bug John has reported ~10 times that keeps not getting fixed - the FIRST right-click shows the menu for a blip then it vanishes, and you must right-click a SECOND time ~1s later for it to stay. Cause, the 2nd-click workaround, and the real fix. READ THIS before touching updateWikiJumplist, any desktop_set_window_jumplist call, or any code that re-commits a jump list on a timer/stamp/nav.

pup taskbar jump lists

🔴 THE BUG John keeps reporting (write it here so it is NEVER forgotten again)

John, verbatim and repeatedly ("i've fucking told you about this 10 fucking times"):

"The FIRST time you right-click it, the jump list shows for a BLIP and then goes away. Then you always have to right-click a SECOND time ~1 second later, and THEN it works and stays open."

This is real, reproducible, and long-standing. Do not "fix jump lists," verify they COMMIT, and call it done - committing is necessary but the BLIP is the bug he actually feels. The menu appearing and then self-dismissing on the first right-click is the whole complaint.

Cause: a CommitList lands while the shell is showing the menu

desktop_set_window_jumplist → the Windows shell ICustomDestinationList::CommitList, and every CommitList REBUILDS the menu from scratch. If a commit fires WHILE the user is opening (or has just opened) the jump list, the shell DISMISSES the open menu - the blip. The second right-click works because by then no commit is in flight, so nothing rebuilds it out from under the user.

So the bug is pup re-committing the jump list too close to the user's right-click. The prime suspects, all in updateWikiJumplist's callers, are re-commits that fire on events that coincide with a right-click:

  • The post-stamp-settle re-commit (a setTimeout(..., 1600) that clears the dedup key and re-commits "on the live button"). ~1.6s is suspiciously close to John's "~1s later." A focus change from the user clicking the taskbar can trigger a re-stamp → this re-commit → dismiss.
  • Any timer/nav/overlay-driven call into updateWikiJumplist that isn't gated on the task set ACTUALLY changing.

The old dedup key was (appId | view | jlViewTasks | jlCloseAll). That still re-commits whenever the appId changes (a re-stamp) even though the TASKS are identical, which is a redundant CommitList that can eat the menu.

The fix (do this, don't just document it)

  1. Dedup on the exact TASK-SET, not on appId/view. Hash the committed tasks array (titles + args); if the hash is unchanged, do NOT call desktop_set_window_jumplist at all. A re-stamp with identical tasks must be a no-op - no CommitList, no blip.
  2. Kill the periodic / post-stamp-settle re-commit unless the task-set hash changed. "Hygiene" re-commits are exactly what dismiss the menu. One commit per real content change, ever.
  3. Never commit in response to a focus/foreground change - that is when the user is opening the menu.
  4. If a genuine shell race remains after pup stops over-committing, THAT part is AD's (it owns the shell interaction) - file it there with a repro, don't paper over it with another re-commit.

The 2nd-click workaround (tell the user, honestly)

Until the over-committing is gone: right-click, if it blips away, right-click again ~1s later. Say this plainly; do not pretend the first click works.

The "Switch to logged-in view" task did NOTHING (v1.9.332)

John clicked the "Switch to logged-in view" jump-list task and nothing happened. Cause: the callback pup_wiki_set_view short-circuited with {unchanged:true} (just bringToFront, NO reload) whenever pup BELIEVED the window was already in the requested view. And pup makes wiki windows default to authed, so it almost always believed "already logged in" → the click was a silent no-op. Worse, pup's view belief is unreliable (the default-authed may never have actually signed the page in; a cookie expired), so "do nothing because I think you're already there" is exactly the wrong call.

FIX: a real USER click (caller aiThread: 'user-taskbar-menu', which every jump-list task carries via jarg) must ALWAYS re-assert the requested view — fall through to the mint/navigate path, which is a genuine reload that GUARANTEES the view (for authed it re-mints a magic link / auto-signs from AD's desktop token, actually signing the page in). Only a PROGRAMMATIC same-view call keeps the unchanged short-circuit. The task's own description promises a "harmless reload" — honor it. Detect the user click by _callerThread === 'user-taskbar-menu' (the header the CLI sets from the task's JSON caller).

How jump lists work (the parts that ARE correct)

  • Tasks attach to the AUMID, so a per-session appId gives that window its own menu. Requires aumidIcons ON (jump lists ride on the stamp) - see pup-icon-consistency.
  • Commit MUST target the window by hwnd, not title (it was silently failing on title - see pup-window-targeting). Pass hwnd: session._hwnd.
  • Do NOT gate the commit on _registeredPupAumids - that set is filled only by desktop_register_app_identity, a silent no-op on some AD builds, and it blocked EVERY commit (v1.9.314). The window stamp already binds the AUMID; the commit works with just hwnd+appId+tasks.
  • Tasks: wiki view-switch tasks (jlViewTasks, only on Adom wiki URLs) + a "Close ALL Adom Pup windows" task (jlCloseAll). Each needs an iconPath or the row shows a blank document glyph.
  • Real screenshots of the flyout can only be captured under a real pointer; an AD right-click opens the Win11 TASK-VIEW THUMBNAILS, not the flyout. See the MOUSE-TAKEOVER section in pup-bridge-dev.