Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Foreground and Background events for iOS #2144

Closed

Conversation

HackerFoo
Copy link
Contributor

  • Tested on all platforms changed
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • 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 HackerFoo changed the title add Foreground and Background events Add Foreground and Background events for iOS Jan 10, 2022
@madsmtm
Copy link
Member

madsmtm commented Jan 10, 2022

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: rust-windowing/raw-window-handle#84).

@madsmtm madsmtm added the C - needs discussion Direction must be ironed out label Jan 10, 2022
@HackerFoo
Copy link
Contributor Author

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.

@madsmtm
Copy link
Member

madsmtm commented Jan 23, 2022

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!

@HackerFoo
Copy link
Contributor Author

HackerFoo commented Jan 28, 2022

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.

@ArthurKValladares
Copy link
Contributor

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.

@rib
Copy link
Contributor

rib commented May 18, 2022

Just to join the dots, this recent issue also looks to try and get a clearer understanding of lifecycle event handling within winit: #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 #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.

@madsmtm
Copy link
Member

madsmtm commented Jul 28, 2023

Superseded by #2980

@madsmtm madsmtm closed this Jul 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C - needs discussion Direction must be ironed out DS - ios
Development

Successfully merging this pull request may close these issues.

5 participants