iOS: Activate/Deactivate events don't trigger!

I found that Activate and Deactivate events of Stage are not triggering in an iOS app when the app goes to background and back.

Lib.current.stage.addEventListener(Event.DEACTIVATE, onDeactivate); // <== never triggers
Lib.current.stage.addEventListener(Event.ACTIVATE, onActivate); // <== triggers once on start-up

I tested this behavior on Actuate sample code from OpenFL Samples:

I just put traces to stage_onActivate and stage_onDeactivate, built and run on iPhone and it didn’t work.

Is it a bug?

If not, when how to detect that the app goes to background on iOS?

Does it work if you add the listeners to NativeApplication.nativeApplication instead?

NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, onDeactivate);
NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, onActivate);

Will try it tomorrow and share the outcome here, thanks!

It might also be worth trying to add them to Lib.current.stage.nativeWindow.

None of these trigger :sob: I added the listeners as follows:

openfl.desktop.NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, (_)->trace("NApp deactivate"));
openfl.desktop.NativeApplication.nativeApplication.addEventListener(Event.ACTIVATE, (_)->trace("NApp activate"));
openfl.Lib.current.stage.nativeWindow.addEventListener(Event.DEACTIVATE, (_)->trace("NWin deactivate"));
openfl.Lib.current.stage.nativeWindow.addEventListener(Event.ACTIVATE, (_)->trace("NWin activate"));

The Activate events only triggered once on launch, here is the log (“Resume” comes from stage activate):

Launched application with org.openfl.samples.actuateexample bundle identifier.
Waiting for the application to terminate…
2026-03-12 09:27:46.315 ActuateExample[1395:78517] You need UIApplicationSupportsIndirectInputEvents in your Info.plist for mouse support
../../../../Source/Main.hx:16: New
../../../../Source/Main.hx:70: NWin activate
../../../../Source/Main.hx:68: NApp activate
../../../../Source/Main.hx:82: Resume
2026-03-12 09:27:46.360 ActuateExample[1395:78517] Unbalanced calls to begin/end appearance transitions for <SDL_uikitviewcontroller: 0x11ac6c500>.
2026-03-12 09:27:46.360 ActuateExample[1395:78517] Unbalanced calls to begin/end appearance transitions for <SDL_uikitviewcontroller: 0x11ac6c500>.
2026-03-12 09:27:46.360 ActuateExample[1395:78517] Unbalanced calls to begin/end appearance transitions for <SDL_uikitviewcontroller: 0x11ac6c500>.
2026-03-12 09:27:46.360 ActuateExample[1395:78517] Unbalanced calls to begin/end appearance transitions for <SDL_uikitviewcontroller: 0x11ac6c500>.

By the way, when the app goes to background, there are several errors in the console as one below, and I saw these errors in any other app I built recently:

2026-03-12 09:28:16.000 ActuateExample[1395:78766] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=7 “Insufficient Permission (to submit GPU work from background) (00000006:kIOGPUCommandBufferCallbackErrorBackgroundExecutionNotPermitted)” UserInfo={NSLocalizedDescription=Insufficient Permission (to submit GPU work from background) (00000006:kIOGPUCommandBufferCallbackErrorBackgroundExecutionNotPermitted), NSUnderlyingError=0x11af39470 {Error Domain=IOGPUCommandQueueErrorDomain Code=6 “(null)”}}

Looks like this is because the app couldn’t detect that it’s on background and it’s trying to render or such…

@joshtynjala so is it a bug in Lime?.. Should I submit an issue? Or should I try to fix it instead? :slight_smile:

I’ll check if I can find and fix it anyway.

At this point it seems like it’s somewhere in SDL or somewhere in between SDL and Lime. Not sure if I will be able to find and fix it :sweat_smile:

According to the README-ios in SDL, SDL has SDL_APP_WILLENTERBACKGROUND, SDL_APP_DIDENTERBACKGROUND, SDL_APP_WILLENTERFOREGROUND and SDL_APP_DIDENTERFOREGROUND. We handle those in Lime, which should result in the Lime Window to dispatch its onActivate and onDeactivate.

It must be something in OpenFL that isn’t properly listening for that event.

It can be so, I guess. Is it possible to add event listeners to Lime events directly bypassing the OpenFL infrastructure then?

Can I use

lime.app.Application.current.window.onActivete

and

onDeactivate

and add listeners to these?

By the way, is OpenFL platform-specific when handling these events? Asking because they work fine (same project) for html5 and android targets.

Yes, you can certainly listen for events directly from Lime in an OpenFL app.

@joshtynjala looks like it’s Lime or SDL after all. I put traces into handleWindowEvent() of NativeApplication and the result was as follows:

Orientation event is triggered every time:

lime/_internal/backend/native/NativeApplication.hx:551: Lime window event handler: true
lime/_internal/backend/native/NativeApplication.hx:554: Lime window event: 11

And activate/deactivate doesn’t trigger, there is just no trace when I switch apps or lock/unlock the phone. It’s only trigger on startup once:

lime/_internal/backend/native/NativeApplication.hx:551: Lime window event handler: true
lime/_internal/backend/native/NativeApplication.hx:554: Lime window event: 11
lime/_internal/backend/native/NativeApplication.hx:551: Lime window event handler: true
lime/_internal/backend/native/NativeApplication.hx:554: Lime window event: 13

The traces I added:

@joshtynjala I believe it is connected with this:

SDL version that is currently used, doesn’t adopt the scene-based life cycle, unlike the latest version in GIT:

I believe SDL needs update in Lime to address the issue

1 Like

…and the first SDL version where it’s implemented is SDL 3.4.0

I could actually fix it by modifying SDL. It took quite some time :sweat_smile:

So basically I copied the code related to the scene-based UIKit app lifecycle from SDL 3.4 to the current SDL module included in Lime. The fix is not easy to apply, but anyway, this is how you can do it:

  1. Clone a GIT version of Lime ( GitHub - openfl/lime: A foundational Haxe framework for cross-platform development · GitHub ). This can be installed to haxelib directly from GitHub with haxelib git lime https://github.com/openfl/lime. Change the branch if you don’t want the default ‘develop’ branch.
  2. You will need Lime submodules to rebuild lime and tools (and ios later). You can follow these steps (except it’s macos, not windows): How rebuild Lime? - #10 by singmajesty.
  3. Replace the files in Lime/SDL ([YOUR LIME DIR]/project/lib/sdl) with the files from here: Dropbox.
  4. Rebuild lime and tools (see step 2). Most probably it can be done right on step 2, but just in case. You may get ‘error: SDK macosx26 cannot be located’ while trying to rebuild lime, in this case you’ll need a patched version of HXCPP with a fix from @joshtynjala found here: Comparing HaxeFoundation:master...joshtynjala:fix/mac-dot-zero-sdk · HaxeFoundation/hxcpp · GitHub.
  5. Rebuild lime for iOS with lime rebuild ios -clean.

Focus events should start working in iOS builds from this point and the red log message in the console on app start up should be gone.

UIScene lifecycle will soon be required. 
Failure to adopt will result in an assert in the future.

You may want to configure the info.plist then as described here: TN3187: Migrating to the UIKit scene-based life cycle | Apple Developer Documentation

Please note that the version of the SDL submodule may change in Lime and the files may then need changes. This fix was done for SDL 2.30.12 ( GitHub - libsdl-org/SDL at 8236e01a9f758d15927624925c6043f84d8a261f · GitHub ).

It’s definitely not a good solution, it can’t be even submitted as a pull request, because it makes changes to a submodule… I guess the only real fix would be updating the SDL submodule in Lime to version 3.4.0+, that can be hard since there was a lot of changes in SDL v3+ compared to v2.

1 Like