Tryst::CanvasBindInterceptor
@api private
Registered for the "canvas" CommandInterceptors entry below.
Canvas items aren't windows (only the canvas itself is one), so a
bound item's callback never fires <Destroy> on its own, and canvas delete is silent - the same leak shape menu entries have. Unlike
menu or text/treeview tags, canvas has no "list every live binding"
enumeration command (no analogue to menu's index end or text's tag
names), so this can't do a full-scan reconcile. Instead it re-queries
only the (tagOrId, sequence) keys it already knows about - via
canvas bind tagOrId sequence, the 2-arg read form - after every
bind/delete call, and lets whatever no longer resolves drop out.
A binding on a numeric item id is released this way once that item is deleted (Tk's Tk_DeleteAllBindings clears its binding-table entries along with it). A binding on a tag is NOT released by deleting a tagged item - the tag itself isn't an item, so its binding-table entry persists independent of which (if any) items currently carry that tag.
Constants
Matches a bare crystal_callback <id> or one followed by
%-substitution codes (crystal_callback <id> %x %y) - raw_command's
generic positional-Proc handling allows a caller to pass
%-substitutions to a canvas-bind-shaped app.command call (the same
mechanism App#bind uses). \S+ is greedy and stops at the first
space, so it can't overrun into the substitution codes themselves.