Here's a video demo of using custom async proc's with Fidget to animate a UI: <https://youtu.be/nRFoflV3MI0> and the [example code](https://github.com/elcritch/fidget/blob/devel/tests/progressbar/progressbar.nim).
It turns out the required user code is as simple as creating an async proc: var progressBar: float = 0.02 var ticks: Future[void] = emptyFuture() ## Create an completed "empty" future proc ticker() {.async.} = ## Every tick will increment the progress bar 10% until its done. for i in 1..10: await sleepAsync(1_000) progressBar = 0.1 * i.toFloat() echo fmt"tick {bar}" refresh() Run Then trigger it in the UI: rectangle "run animation button": box barW-80, 0, 40, 40 onClick: if ticks.finished(): echo "setup new ticker" ticks = ticker() else: echo "ticker already running!" Run Enabling that use case required tweaking Fidget and Nim's async/ioselectors on MacOSX. The Fidget changes were just adding an AsyncEvent callback on keyboard/mouse inputs. Unfortunately on MacOSX it was painfully slow. That's because Nim's AsyncEvent relies on user events in `selectors`. On MacOSX and BSD user events in the `selectors` module are emulated using pipes. This cause me headaches before so I created a [PR](https://github.com/nim-lang/Nim/pull/19587) to enable using kqueues's `EVFILT_USER`. Though it'll need some testing/work the latency is much better at about ~1ms.