 <PRIVATE
 
 : update-ui-loop ( -- )
-    [ ui-running? ui-thread get-global self eq? and ]
-    [ ui-notify-flag get lower-flag update-ui ]
-    while ;
+    #! Note the logic: if update-ui fails, we open an error window
+    #! and run one iteration of update-ui. If that also fails, well,
+    #! the whole UI subsystem is broken so we exit out of the
+    #! update-ui-loop.
+    [ { [ ui-running? ] [ ui-thread get-global self eq? ] } 0&& ]
+    [
+        ui-notify-flag get lower-flag
+        [ update-ui ] [ ui-error update-ui ] recover
+    ] while ;
 
 : start-ui-thread ( -- )
     [ self ui-thread set-global update-ui-loop ]

PRIVATE>

: find-window ( quot -- world )
    windows get values
    [ gadget-child swap call ] with find-last nip ; inline

: ui-running? ( -- ? )
    \ ui-running get-global ;

    gesture-queue [ send-queued-gesture notify-queued ] slurp-deque ;

: update-ui ( -- )
    notify-queued
    layout-queued
    redraw-worlds
    send-queued-gestures ;

SYMBOL: ui-thread

