From 468f8acc50de972f5ce30c5aa30243ba4fb953af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Lindstr=C3=B6m?= Date: Wed, 7 Feb 2024 13:16:36 +0200 Subject: [PATCH 1/4] Fresh changes of the display-cutout functionality --- doc/source/buildoptions.rst | 4 ++++ pythonforandroid/bootstraps/common/build/build.py | 2 ++ .../qt/build/templates/AndroidManifest.tmpl.xml | 1 + .../bootstraps/qt/build/templates/strings.tmpl.xml | 8 ++++++++ .../sdl2/build/templates/AndroidManifest.tmpl.xml | 1 + .../bootstraps/sdl2/build/templates/strings.tmpl.xml | 8 ++++++++ .../webview/build/templates/AndroidManifest.tmpl.xml | 1 + .../bootstraps/webview/build/templates/strings.tmpl.xml | 8 ++++++++ 8 files changed, 33 insertions(+) diff --git a/doc/source/buildoptions.rst b/doc/source/buildoptions.rst index 782bd67295..634f506faf 100644 --- a/doc/source/buildoptions.rst +++ b/doc/source/buildoptions.rst @@ -72,6 +72,10 @@ options (this list may not be exhaustive): - ``--permission``: A permission that needs to be declared into the App ``AndroidManifest.xml``. For multiple permissions, add multiple ``--permission`` arguments. ``--home-app`` Gives you the option to set your application as a home app (launcher) on your Android device. + ``--display-cutout``: A display cutout is an area on some devices that extends into the display surface. + It allows for an edge-to-edge experience while providing space for important sensors on the front of the device. + (Available options are ``default``, ``shortEdges``, ``never`` and defaults to ``never``) + `Android documentation `__. .. Note :: ``--permission`` accepts the following syntaxes: diff --git a/pythonforandroid/bootstraps/common/build/build.py b/pythonforandroid/bootstraps/common/build/build.py index 29d16ea9f2..3b98e09dae 100644 --- a/pythonforandroid/bootstraps/common/build/build.py +++ b/pythonforandroid/bootstraps/common/build/build.py @@ -793,6 +793,8 @@ def create_argument_parser(): 'launcher, rather than a single app.')) ap.add_argument('--home-app', dest='home_app', action='store_true', default=False, help=('Turn your application into a home app (launcher)')) + ap.add_argument('--display-cutout', dest='display_cutout', default='never', + help=('Enables display-cutout that renders around the area (notch) on some devices that extends into the display surface')) ap.add_argument('--permission', dest='permissions', action='append', default=[], help='The permissions to give this app.', nargs='+') ap.add_argument('--meta-data', dest='meta_data', action='append', default=[], diff --git a/pythonforandroid/bootstraps/qt/build/templates/AndroidManifest.tmpl.xml b/pythonforandroid/bootstraps/qt/build/templates/AndroidManifest.tmpl.xml index 057794e4ed..8ccff2027a 100644 --- a/pythonforandroid/bootstraps/qt/build/templates/AndroidManifest.tmpl.xml +++ b/pythonforandroid/bootstraps/qt/build/templates/AndroidManifest.tmpl.xml @@ -61,6 +61,7 @@ android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale|uiMode{% if args.min_sdk_version >= 8 %}|uiMode{% endif %}{% if args.min_sdk_version >= 13 %}|screenSize|smallestScreenSize{% endif %}{% if args.min_sdk_version >= 17 %}|layoutDirection{% endif %}{% if args.min_sdk_version >= 24 %}|density{% endif %}" android:screenOrientation="{{ args.manifest_orientation }}" android:exported="true" + android:theme="@style/KivySupportCutout" {% if args.activity_launch_mode %} android:launchMode="{{ args.activity_launch_mode }}" {% endif %} diff --git a/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml b/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml index 41c20ac663..58f5645dae 100644 --- a/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml +++ b/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml @@ -1,5 +1,13 @@ + {{ args.name }} {{ private_version }} {{ args.presplash_color }} diff --git a/pythonforandroid/bootstraps/sdl2/build/templates/AndroidManifest.tmpl.xml b/pythonforandroid/bootstraps/sdl2/build/templates/AndroidManifest.tmpl.xml index a887a53d54..c31bb3f747 100644 --- a/pythonforandroid/bootstraps/sdl2/build/templates/AndroidManifest.tmpl.xml +++ b/pythonforandroid/bootstraps/sdl2/build/templates/AndroidManifest.tmpl.xml @@ -70,6 +70,7 @@ android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale|uiMode{% if args.min_sdk_version >= 8 %}|uiMode{% endif %}{% if args.min_sdk_version >= 13 %}|screenSize|smallestScreenSize{% endif %}{% if args.min_sdk_version >= 17 %}|layoutDirection{% endif %}{% if args.min_sdk_version >= 24 %}|density{% endif %}" android:screenOrientation="{{ args.manifest_orientation }}" android:exported="true" + android:theme="@style/KivySupportCutout" {% if args.activity_launch_mode %} android:launchMode="{{ args.activity_launch_mode }}" {% endif %} diff --git a/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml b/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml index c8025518be..de9a8efdc1 100644 --- a/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml +++ b/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml @@ -1,5 +1,13 @@ + {{ args.name }} {{ private_version }} {{ args.presplash_color }} diff --git a/pythonforandroid/bootstraps/webview/build/templates/AndroidManifest.tmpl.xml b/pythonforandroid/bootstraps/webview/build/templates/AndroidManifest.tmpl.xml index f9e4fa3c61..9b436b1fa4 100644 --- a/pythonforandroid/bootstraps/webview/build/templates/AndroidManifest.tmpl.xml +++ b/pythonforandroid/bootstraps/webview/build/templates/AndroidManifest.tmpl.xml @@ -62,6 +62,7 @@ android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale|uiMode{% if args.min_sdk_version >= 8 %}|uiMode{% endif %}{% if args.min_sdk_version >= 13 %}|screenSize|smallestScreenSize{% endif %}{% if args.min_sdk_version >= 17 %}|layoutDirection{% endif %}{% if args.min_sdk_version >= 24 %}|density{% endif %}" android:screenOrientation="{{ args.manifest_orientation }}" android:exported="true" + android:theme="@style/KivySupportCutout" {% if args.activity_launch_mode %} android:launchMode="{{ args.activity_launch_mode }}" {% endif %} diff --git a/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml b/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml index 41c20ac663..58f5645dae 100644 --- a/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml +++ b/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml @@ -1,5 +1,13 @@ + {{ args.name }} {{ private_version }} {{ args.presplash_color }} From 104af9e1659dab1015d4b9b92f086dea8f032c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Lindstr=C3=B6m?= Date: Wed, 7 Feb 2024 20:21:53 +0200 Subject: [PATCH 2/4] Fine tuning + added tools --- .../bootstraps/common/build/build.py | 3 +- .../qt/build/templates/strings.tmpl.xml | 4 +- .../sdl2/build/templates/strings.tmpl.xml | 4 +- .../webview/build/templates/strings.tmpl.xml | 4 +- .../android/src/android/display_cutout.py | 56 +++++++++++++++++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 pythonforandroid/recipes/android/src/android/display_cutout.py diff --git a/pythonforandroid/bootstraps/common/build/build.py b/pythonforandroid/bootstraps/common/build/build.py index 3b98e09dae..51e0a5fa94 100644 --- a/pythonforandroid/bootstraps/common/build/build.py +++ b/pythonforandroid/bootstraps/common/build/build.py @@ -794,7 +794,8 @@ def create_argument_parser(): ap.add_argument('--home-app', dest='home_app', action='store_true', default=False, help=('Turn your application into a home app (launcher)')) ap.add_argument('--display-cutout', dest='display_cutout', default='never', - help=('Enables display-cutout that renders around the area (notch) on some devices that extends into the display surface')) + help=('Enables display-cutout that renders around the area (notch) on ' + 'some devices that extends into the display surface')) ap.add_argument('--permission', dest='permissions', action='append', default=[], help='The permissions to give this app.', nargs='+') ap.add_argument('--meta-data', dest='meta_data', action='append', default=[], diff --git a/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml b/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml index 58f5645dae..fd15c25f47 100644 --- a/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml +++ b/pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml @@ -1,12 +1,14 @@ {{ args.name }} {{ private_version }} diff --git a/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml b/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml index de9a8efdc1..17e376adbd 100644 --- a/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml +++ b/pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml @@ -1,12 +1,14 @@ {{ args.name }} {{ private_version }} diff --git a/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml b/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml index 58f5645dae..fd15c25f47 100644 --- a/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml +++ b/pythonforandroid/bootstraps/webview/build/templates/strings.tmpl.xml @@ -1,12 +1,14 @@ {{ args.name }} {{ private_version }} diff --git a/pythonforandroid/recipes/android/src/android/display_cutout.py b/pythonforandroid/recipes/android/src/android/display_cutout.py new file mode 100644 index 0000000000..cb51c6461d --- /dev/null +++ b/pythonforandroid/recipes/android/src/android/display_cutout.py @@ -0,0 +1,56 @@ +from jnius import autoclass +from android import mActivity + +__all__ = ('ensure_display_cutout', 'get_cutout_size', 'get_size_of_bar') + + +def _decorview(): + return mActivity.getWindow().getDecorView() + + +def get_cutout_size(): + " Get the size of the front camera " + try: + cutout = _decorview().rootWindowInsets.displayCutout + rect = cutout.boundingRects.get(0) + + return float(rect.width()), float(rect.height()) + + except Exception: + return 0., 0. + + +def ensure_display_cutout(): + """ Ensure display cutout is taking place on newer androids + To be used with on_start with Kivy. + Also needs the decorator run_on_ui_thread + """ + AndroidView = autoclass('android.view.View') + _decorview().setSystemUiVisibility( + AndroidView.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + AndroidView.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + AndroidView.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) + + return True + + +def get_size_of_bar(bar_target=None): + """ Get the size of either statusbar or navigationbar + bar_target = status or navigation and defaults to status + """ + bar_target = bar_target or 'status' + + if bar_target not in ('status', 'navigation'): + raise Exception("bar_target must be 'status' or 'navigation'") + + try: + displayMetrics = autoclass('android.util.DisplayMetrics') + mActivity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics()) + resources = mActivity.getResources() + resourceId = resources.getIdentifier(f'{bar_target}_bar_height', 'dimen', + 'android') + + return float(max(resources.getDimensionPixelSize(resourceId), 0)) + + except Exception: + return 0. From aea52eb03b3ca0d5a75823b317c3f071495acbae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Lindstr=C3=B6m?= Date: Thu, 8 Feb 2024 15:06:21 +0200 Subject: [PATCH 3/4] Updated lib --- .../android/src/android/display_cutout.py | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/pythonforandroid/recipes/android/src/android/display_cutout.py b/pythonforandroid/recipes/android/src/android/display_cutout.py index cb51c6461d..a9a52760ec 100644 --- a/pythonforandroid/recipes/android/src/android/display_cutout.py +++ b/pythonforandroid/recipes/android/src/android/display_cutout.py @@ -1,41 +1,45 @@ from jnius import autoclass -from android import mActivity +from kivy.core.window import Window -__all__ = ('ensure_display_cutout', 'get_cutout_size', 'get_size_of_bar') +from android import mActivity +__all__ = ('get_cutout_pos', 'get_cutout_size', 'get_width_of_bar', + 'get_height_of_bar', 'get_size_of_bar') -def _decorview(): - return mActivity.getWindow().getDecorView() +def _core_cutout(): + decorview = mActivity.getWindow().getDecorView() + cutout = decorview.rootWindowInsets.displayCutout -def get_cutout_size(): - " Get the size of the front camera " - try: - cutout = _decorview().rootWindowInsets.displayCutout - rect = cutout.boundingRects.get(0) + return cutout.boundingRects.get(0) - return float(rect.width()), float(rect.height()) +def get_cutout_pos(): + """ Get position of the display-cutout. + Returns integer for each positions (xy) + """ + try: + cutout = _core_cutout() + return int(cutout.left), Window.height - int(cutout.height()) except Exception: - return 0., 0. + # Doesn't have a camera builtin with the display + return 0, 0 -def ensure_display_cutout(): - """ Ensure display cutout is taking place on newer androids - To be used with on_start with Kivy. - Also needs the decorator run_on_ui_thread +def get_cutout_size(): + """ Get the size (xy) of the front camera. + Returns size with float values """ - AndroidView = autoclass('android.view.View') - _decorview().setSystemUiVisibility( - AndroidView.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | - AndroidView.SYSTEM_UI_FLAG_HIDE_NAVIGATION | - AndroidView.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) - - return True + try: + cutout = _core_cutout() + return float(cutout.width()), float(cutout.height()) + except Exception: + # Doesn't have a camera builtin with the display + return 0., 0. -def get_size_of_bar(bar_target=None): - """ Get the size of either statusbar or navigationbar +def get_height_of_bar(bar_target=None): + """ Get the height of either statusbar or navigationbar bar_target = status or navigation and defaults to status """ bar_target = bar_target or 'status' @@ -51,6 +55,18 @@ def get_size_of_bar(bar_target=None): 'android') return float(max(resources.getDimensionPixelSize(resourceId), 0)) - except Exception: + # Getting the size is not supported on older Androids return 0. + + +def get_width_of_bar(bar_target=None): + " Get the width of the bar " + return Window.width + + +def get_size_of_bar(bar_target): + """ Get the size of either statusbar or navigationbar + bar_target = status or navigation and defaults to status + """ + return get_width_of_bar(), get_height_of_bar(bar_target) From d04768fa274313c21fa2b208e5f00e8a8c945da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Lindstr=C3=B6m?= Date: Fri, 9 Feb 2024 18:19:19 +0200 Subject: [PATCH 4/4] Add missing None for default value while grabbing the sizes --- pythonforandroid/recipes/android/src/android/display_cutout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pythonforandroid/recipes/android/src/android/display_cutout.py b/pythonforandroid/recipes/android/src/android/display_cutout.py index a9a52760ec..dbe5d8a137 100644 --- a/pythonforandroid/recipes/android/src/android/display_cutout.py +++ b/pythonforandroid/recipes/android/src/android/display_cutout.py @@ -65,7 +65,7 @@ def get_width_of_bar(bar_target=None): return Window.width -def get_size_of_bar(bar_target): +def get_size_of_bar(bar_target=None): """ Get the size of either statusbar or navigationbar bar_target = status or navigation and defaults to status """