beeware / briefcase-android-gradle-template

A template for generating Android Gradle projects with Briefcase
MIT License
18 stars 19 forks source link

Added support for detecting app focus events. #69

Closed proneon267 closed 5 months ago

proneon267 commented 10 months ago

Added support for detecting app focus events through: onWindowFocusChanged https://developer.android.com/reference/android/view/ViewTreeObserver.OnWindowFocusChangeListener#onWindowFocusChanged(boolean)

This PR relates to the PR: https://github.com/beeware/toga/pull/2096

PR Checklist:

mhsmith commented 10 months ago

As it says at https://developer.android.com/reference/android/app/Activity#onWindowFocusChanged(boolean):

a foreground activity will have window focus... unless it has displayed other dialogs or popups that take input focus, in which case the activity itself will not have focus when the other windows have it.

So I think onPause and onResume would be more appropriate here.

mhsmith commented 10 months ago

Also, now that I remind myself of how this works, there's no need to add any methods to IPythonApp, because MainActivity doesn't use it anymore. Instead, MainActivity.userCode should be altered to check whether each method exists on the Python object before trying to call it.

proneon267 commented 10 months ago

So I think onPause and onResume would be more appropriate here.

These events are only triggered when the app state changes between [visible to user] and [not visible to user].

They do not take the input focus into account when the app is [visible to user but not receiving inputs] or [visible to user and receiving inputs].

Hence, onPause and onResume will be best suited for handlers like: on_background[not visible to user] and on_foreground[visible to user].

onWindowFocusChanged is the only event that is consistently triggered when the focus is:

Moreover, as per: https://source.android.com/docs/core/display/multi_display/multi-resume , multiple apps can be in Resumed state, and onPause event is not triggered when the input focus changes between apps in multi-app mode. So, properly detecting focus is not possible with onPause and onResume.

Although, I do agree with you that onPause and onResume will be needed to be used as popups and other dialogs will take away input focus. I am trying out a few things and will let you know the results when I will get a consistent behavior.

proneon267 commented 10 months ago

According to: https://developer.android.com/reference/android/app/Activity#onWindowFocusChanged(boolean)

Starting with Build.VERSION_CODES.Q there can be multiple resumed activities at the same time in multi-window mode, so resumed state does not guarantee window focus even if there are no overlays above.

Hence, I have chosen: onTopResumedActivityChanged https://developer.android.com/reference/android/app/Activity#onTopResumedActivityChanged(boolean) This works better than onWindowFocusChanged and ignores focus gained by dialogs and popups from the same app.

On platform versions prior to Build.VERSION_CODES.Q, I have implemented the feature with onPause and onResume.