winit icon indicating copy to clipboard operation
winit copied to clipboard

Add Foreground and Background events for iOS

Open HackerFoo opened this issue 3 years ago • 6 comments

  • [x] Tested on all platforms changed
  • [ ] Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • [x] Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • [ ] Created or updated an example program if it would help users understand this functionality
  • [ ] Updated feature matrix, if new features were added or implemented

HackerFoo avatar Jan 10 '22 20:01 HackerFoo

Hmm, how does this differ from WindowEvent::Focused?

Also, this is something touching the public API, and will need discussion to figure out if it's relevant for at the very least a few platforms (see also the issues on Android: https://github.com/rust-windowing/raw-window-handle/issues/84).

madsmtm avatar Jan 10 '22 20:01 madsmtm

WindowEvent::Focused is sent in response to becomeKey()/resignKey(), which seems to be for indicating the most recently active window, while WindowEvent::Foreground/Background events indicate transitions in an app's lifecycle:

iOS App Lifecycle

It should probably be sent at the onResume() and onPause() transitions for Android:

Android App Lifecycle

The purpose is to allow the app to switch from and to a low power state, rather than for tracking the user's focus. For iOS in particular, an app may not use the GPU while in the background, or it will be killed by the OS.

HackerFoo avatar Jan 10 '22 22:01 HackerFoo

The implementation looks good, though I must admit I have a hard time grokking the different lifecycle events - maybe we should have some documentation that directly maps winits lifecycle events to Android/iOS lifecycle events, kinda like you just described, just for all of them?

Anyhow, I think these events belong in winit, but it's harder to justify this PR without the Android implementation; could you be persuaded to attempt that?

For iOS in particular, an app may not use the GPU while in the background, or it will be killed by the OS.

Use-cases like these would be useful to have documented!

madsmtm avatar Jan 23 '22 11:01 madsmtm

Sorry, I don't have Android set up right now, and I can't justify putting the time in to properly test it. For someone who has winit running on Android, it probably wouldn't take much time to add Android support for these events.

It would probably also be best to do Android support in a separate PR.

HackerFoo avatar Jan 28 '22 22:01 HackerFoo

I will voice support for this PR. I work for a company planning on releasing a production product using winit on iOS, and we need this functionality to be able to properly handle backgrounding/foregrounding.

ArthurKValladares avatar Apr 26 '22 23:04 ArthurKValladares

Just to join the dots, this recent issue also looks to try and get a clearer understanding of lifecycle event handling within winit: https://github.com/rust-windowing/winit/issues/2185

I've been poking at the Android backend recently, but based on an alternative glue layer than ndk-glue. One thing I'd note re: Android is that technically the current Android backend drives Suspended/Resumed events according to when the OS destroys/creates the application's native window. This is technically not following the lifecycle events and I'm not even sure if it's specified anywhere when Android will destroy and apps window in relation to paused/stop events (so I could imagine it e.g. varies for different versions of Android).

Since winit doesn't have more fine grained lifecycle events, it makes some sense that the backend would trigger a suspend based on when the native window is destroyed / created because it's so important that applications react to that on Android. The trade off though is that we're slightly misleading applications about their real lifecycle state.

The detailed semantics of these different lifecycle stages are notably somewhat OS specific and I wonder what the best way of taking that into account would be. E.g. with the iOS the backend apps will currently be 'suspended' based on applicationWillResignActive which is a kind of early heads up from the OS that the app will probably go into the background soon, but that state doesn't e.g. prohibit redrawing, and the docs just suggest that apps should start to throttle redrawing at that stage. On the other hand; the Android backend will 'suspend' an app when it's native window is destroyed, and at that point it's absolutely critical that the application can not redraw while suspended (the winit backend would actually panic for any window interaction that tries to access the native window). So already Suspended means something different on Android vs iOS.

Something I raised in https://github.com/rust-windowing/winit/issues/2185 that could be relevent here is the question of whether we could get desktop platforms to also report positive edges of these lifecycle states (i.e. Resumed in the case of Suspended/Resumed) since we currently have some portability challenges between desktop and mobile which I think might be partially improved if we could assume that all OSs/platforms will get a Resumed event that can be used as the standard place to initialize graphics state and render surfaces.

rib avatar May 18 '22 13:05 rib

Superseded by https://github.com/rust-windowing/winit/pull/2980

madsmtm avatar Jul 28 '23 22:07 madsmtm