@@ -167,6 +167,7 @@ static uint32_t getActionIconPadding(UiDensity uiDensity) {
167167/* ── Event Callbacks (declared here so createWidgets can wire them up) ── */
168168
169169static void onTick (lv_timer_t * timer);
170+ static void onGameAreaDeleted (lv_event_t * e);
170171static void onPressed (lv_event_t * e);
171172static void onClicked (lv_event_t * e);
172173static void onKey (lv_event_t * e);
@@ -404,6 +405,7 @@ void breakoutCreateWidgets(lv_obj_t* parent, void* userData) {
404405 lv_obj_add_event_cb (ctx->gameArea , onClicked, LV_EVENT_SHORT_CLICKED , ctx);
405406 lv_obj_add_event_cb (ctx->gameArea , onKey, LV_EVENT_KEY , ctx);
406407 lv_obj_add_event_cb (ctx->gameArea , onReenterKeyMode, LV_EVENT_CLICKED , ctx);
408+ lv_obj_add_event_cb (ctx->gameArea , onGameAreaDeleted, LV_EVENT_DELETE , ctx);
407409
408410 // Keyboard focus - explicit enter/exit, no focus/defocus handlers
409411 lv_group_t * group = lv_group_get_default ();
@@ -417,16 +419,16 @@ void breakoutCreateWidgets(lv_obj_t* parent, void* userData) {
417419 ctx->gameTimer = lv_timer_create (onTick, TICK_MS , ctx);
418420}
419421
420- void breakoutTeardown (Context* ctx) {
422+ // The window manager deletes the widgets when the app closes, and when another window covers it.
423+ // The game timer moves the widgets, so it must stop with them.
424+ static void onGameAreaDeleted (lv_event_t * e) {
425+ auto * ctx = static_cast <Context*>(lv_event_get_user_data (e));
421426 if (ctx->gameTimer ) {
422427 lv_timer_delete (ctx->gameTimer );
423428 ctx->gameTimer = nullptr ;
424429 }
425- if (ctx->gameArea ) {
426- lv_group_t * group = lv_group_get_default ();
427- if (group) lv_group_set_editing (group, false );
428- lv_group_remove_obj (ctx->gameArea );
429- }
430+ lv_group_t * group = lv_group_get_default ();
431+ if (group) lv_group_set_editing (group, false );
430432 ctx->gameArea = nullptr ;
431433 ctx->paddle = nullptr ;
432434 for (int i = 0 ; i < MAX_BRICKS ; i++) ctx->bricks [i] = nullptr ;
@@ -441,7 +443,9 @@ void breakoutTeardown(Context* ctx) {
441443 ctx->livesLabel = nullptr ;
442444 ctx->messageLabel = nullptr ;
443445 ctx->soundBtnIcon = nullptr ;
446+ }
444447
448+ void breakoutTeardown (Context* ctx) {
445449 // Clean up sfx engine
446450 if (ctx->sfxEngine ) {
447451 ctx->sfxEngine ->stop ();
0 commit comments