I often run into two types of issues when working with canvases: either the redraw doesn’t happen when it should, or it happens too frequently — and quite often both problems occur in the same app.
To address the first issue (missed redraws), I end up calling the redraw logic from an increasing number of events to ensure it eventually runs.
But this creates the second issue (excessive redraws), which I solve using a debounced redraw mechanism with a timer. I define two functions — schedule_redraw() and perform_redraw().
schedule_redraw() sets the timer interval to 0.1 seconds and returns immediately.
The timer’s tick event triggers perform_redraw(), which does the actual canvas drawing and then disables the timer by setting the interval back to 0.
This way, multiple rapid redraw triggers are collapsed into a single one, avoiding unnecessary redraws.
You might also find this related thread helpful — it describes a similar issue with redrawing custom components: