Skip to content

windows: host-side tray menu + subclass recipe (align with the set-tray-menu! contract) #216

Closed

Description

@turinglambdaai

Shipped movebit's tray this week (tray-resident break reminder, Windows host on the current WinUI 3 template). The first-party rivet::system::TrayIcon covers registration, tooltip relabeling (#212) and balloons — but every tray-resident host still has to hand-roll the same ~80 lines on top:

  • SetWindowSubclass on the main-window HWND to intercept the tray callback_message (left click = reopen, right click = context menu) and to forward TaskbarCreated into Readd();
  • the TrackPopupMenu block with its foreground-window quirk (menu won't dismiss on outside clicks unless the owning window is foreground first);
  • WM_COMMAND routing back into application actions.

Proposal

Either:

  1. a menu-aware host-side controller in platform/windows/system (labels + ids + std::function callbacks — the menu semantics stay app-side: labels come from the app's i18n single source, actions are app RPCs), or
  2. if the menu is judged app business all the way down, document the subclass recipe (SetWindowSubclass + TaskbarCreated forward + SetForegroundWindow quirk) as the blessed pattern in platform/windows docs so hosts stop rediscovering the foreground quirk.

Family-contract note

rivet/system already exposes set-tray-menu! on the Racket side, and #118 keeps the Linux StatusNotifierItem adapter aligned with it. A Windows menu-aware controller would give the three platforms the same shape: registration/tooltip/balloon in the runtime, menu contents and actions in the app.

Reference implementation

movebit windows/TrayIcon.h (TrayController, ~180 lines, shipped in f509fd8): subclass + TaskbarCreated forward + context menu + four action bindings, built on rivet::system::TrayIcon + #212. Happy to split it into a PR if (1) sounds right.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions