Skip to content

Add support for display cutouts in manifest and add methods to retrieve data #2969

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

Merged
merged 4 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/source/buildoptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://developer.android.com/develop/ui/views/layout/display-cutout>`__.

.. Note ::
``--permission`` accepts the following syntaxes:
Expand Down
3 changes: 3 additions & 0 deletions pythonforandroid/bootstraps/common/build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,9 @@ 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=[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}
Expand Down
10 changes: 10 additions & 0 deletions pythonforandroid/bootstraps/qt/build/templates/strings.tmpl.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="KivySupportCutout">
<item name="android:windowNoTitle">true</item>
<!-- Display cutout is an area on some devices that extends into the display surface -->
{% if args.display_cutout != 'never'%}
<item name="android:windowLayoutInDisplayCutoutMode">{{ args.display_cutout }}</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowFullscreen">true</item>
{% endif %}
</style>
<string name="app_name">{{ args.name }}</string>
<string name="private_version">{{ private_version }}</string>
<string name="presplash_color">{{ args.presplash_color }}</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}
Expand Down
10 changes: 10 additions & 0 deletions pythonforandroid/bootstraps/sdl2/build/templates/strings.tmpl.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="KivySupportCutout">
<item name="android:windowNoTitle">true</item>
<!-- Display cutout is an area on some devices that extends into the display surface -->
{% if args.display_cutout != 'never'%}
<item name="android:windowLayoutInDisplayCutoutMode">{{ args.display_cutout }}</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowFullscreen">true</item>
{% endif %}
</style>
<string name="app_name">{{ args.name }}</string>
<string name="private_version">{{ private_version }}</string>
<string name="presplash_color">{{ args.presplash_color }}</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="KivySupportCutout">
<item name="android:windowNoTitle">true</item>
<!-- Display cutout is an area on some devices that extends into the display surface -->
{% if args.display_cutout != 'never'%}
<item name="android:windowLayoutInDisplayCutoutMode">{{ args.display_cutout }}</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowFullscreen">true</item>
{% endif %}
</style>
<string name="app_name">{{ args.name }}</string>
<string name="private_version">{{ private_version }}</string>
<string name="presplash_color">{{ args.presplash_color }}</string>
Expand Down
72 changes: 72 additions & 0 deletions pythonforandroid/recipes/android/src/android/display_cutout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from jnius import autoclass
from kivy.core.window import Window

from android import mActivity

__all__ = ('get_cutout_pos', 'get_cutout_size', 'get_width_of_bar',
'get_height_of_bar', 'get_size_of_bar')


def _core_cutout():
decorview = mActivity.getWindow().getDecorView()
cutout = decorview.rootWindowInsets.displayCutout

return cutout.boundingRects.get(0)


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:
# Doesn't have a camera builtin with the display
return 0, 0


def get_cutout_size():
""" Get the size (xy) of the front camera.
Returns size with float values
"""
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_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'

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:
# 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=None):
""" 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)