module

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

CALLBACK_SCRIPT_PATTERN = /\Acrystal_callback (\S+)(?:\s|\z)/

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.

MUTATING_SUBCOMMANDS = ["bind", "delete"] of ::String

Class methods

call(app : App, path : String, args : Array(TclArgValue), kwargs : Hash(String, TclArgValue)) : String | Nil
Source