Platform metrics¶
A small process-wide store for values only the screen host can observe:
safe-area insets, viewport size, and keyboard height. The host publishes
them as the platform reports changes, and the Dimensions, PixelRatio,
and Keyboard modules read them on demand.
Everything here is in layout units, points on iOS and
density-independent pixels on Android, so the values add directly to
other layout-unit values without conversion. Most app code reaches this
indirectly, through
use_safe_area_insets and
use_window_dimensions.
Platform-level metrics shared between screen hosts and view handlers.
The screen host (pythonnative.hosts) is the only place that knows
about native window/safe-area state because it is the only piece of
code that holds a reference to the native UIViewController
(iOS) or Activity (Android). Native view handlers, however, need
that state to size themselves correctly:
- A bottom tab bar must claim both its visible 49 pt / 56 dp content height and the bottom safe-area inset so its background reaches the edge of the screen and the home indicator / gesture bar does not draw on top of the labels.
- A future safe-area-aware container can read the same values instead of asking each native view for window metrics.
Rather than threading those values through every
the backend's intrinsic measurement
call signature, the screen host writes them here and handlers read
them on demand. Values are in dp on Android and pt on iOS,
i.e., the same "layout units" the layout engine uses on each
platform, so handlers can add them to other layout-unit values
without further conversion. On iOS the screen host consumes the top
safe-area inset by positioning the root view below it, then publishes
top=0 here; Android publishes the raw system-bar insets because
the host view normally remains full-screen.
Example
from pythonnative.platform_metrics import ( ... get_safe_area_insets, set_safe_area_insets, ... ) set_safe_area_insets(top=44.0, left=0.0, bottom=34.0, right=0.0) get_safe_area_insets().bottom 34.0
Classes:
| Name | Description |
|---|---|
SafeAreaInsets |
Safe-area insets in layout units (pt on iOS, dp on Android). |
WindowDimensions |
Viewport size in layout units (pt on iOS, dp on Android) plus its density. |
Functions:
| Name | Description |
|---|---|
subscribe |
Register callback to fire whenever any metric changes. |
set_safe_area_insets |
Publish the current safe-area insets. |
get_safe_area_insets |
Return the current safe-area insets. |
reset_safe_area_insets |
Reset the insets back to |
set_window_dimensions |
Publish the viewport size in layout units. |
get_window_dimensions |
Return the current viewport size, or |
reset_window_dimensions |
Reset window dimensions back to |
set_screen_dimensions |
Publish the physical screen size in layout units. |
get_screen_dimensions |
Return the physical screen size, or the window size before a host publishes one. |
reset_screen_dimensions |
Reset screen dimensions back to |
set_keyboard_height |
Publish the on-screen keyboard height in layout units. |
get_keyboard_height |
Return the current on-screen keyboard height, or |
reset_keyboard_height |
Reset the keyboard height back to |
ios_tab_bar_height |
Return the iOS tab-bar intrinsic height in points. |
Attributes:
| Name | Type | Description |
|---|---|---|
IOS_TAB_BAR_BASE_HEIGHT_PT |
float
|
UIKit HIG tab-bar content height in points. |
IOS_TAB_BAR_BASE_HEIGHT_PT
module-attribute
¶
IOS_TAB_BAR_BASE_HEIGHT_PT: float = 49.0
UIKit HIG tab-bar content height in points.
The total bar reaches IOS_TAB_BAR_BASE_HEIGHT_PT +
safe_area_insets.bottom so the pill background can extend over the
home indicator. Apple's HIG places the tab bar flush with the screen
edge and lets UIKit render its own internal padding for the home
indicator.
SafeAreaInsets
¶
WindowDimensions
¶
Bases: NamedTuple
Viewport size in layout units (pt on iOS, dp on Android) plus its density.
Attributes:
| Name | Type | Description |
|---|---|---|
width |
float
|
Width in layout units. |
height |
float
|
Height in layout units. |
scale |
float
|
Physical pixels per layout unit ( |
font_scale |
float
|
The user's text-size multiplier (Dynamic Type /
|
subscribe
¶
Register callback to fire whenever any metric changes.
Returns an unsubscribe function. Hooks pass a state setter so a component re-renders whenever the platform reports a new value. Threadsafe: multiple subscribers may register/unregister concurrently.
set_safe_area_insets
¶
Publish the current safe-area insets.
Called by the platform-specific screen host whenever it learns a
new value (e.g., on first layout, on rotation, on multitasking
split-view changes). Negative inputs are clamped to 0.0 so
handlers don't have to defend against bad data from native
callers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
top
|
float
|
Distance in layout units from the top of the host container to the safe area (status bar / dynamic island / navigation bar). |
required |
left
|
float
|
Inset from the left edge. |
required |
bottom
|
float
|
Inset from the bottom edge (home indicator / gesture bar). |
required |
right
|
float
|
Inset from the right edge. |
required |
get_safe_area_insets
¶
get_safe_area_insets() -> SafeAreaInsets
Return the current safe-area insets.
The default value is (0, 0, 0, 0); handlers should still
function correctly in a unit-test environment where no
screen host has published insets.
reset_safe_area_insets
¶
Reset the insets back to (0, 0, 0, 0).
Intended for unit tests that need a clean slate between cases.
Production code should use
set_safe_area_insets
instead.
set_window_dimensions
¶
set_window_dimensions(
width: float,
height: float,
*,
scale: Optional[float] = None,
font_scale: Optional[float] = None
) -> None
Publish the viewport size in layout units.
Called by the screen host on initial layout, rotation, and split-
view changes. Notifies subscribers (and therefore re-renders
components using use_window_dimensions) only when a value
actually changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
float
|
Viewport width in layout units. |
required |
height
|
float
|
Viewport height in layout units. |
required |
scale
|
Optional[float]
|
Pixels per layout unit. |
None
|
font_scale
|
Optional[float]
|
Text-size multiplier. |
None
|
get_window_dimensions
¶
get_window_dimensions() -> WindowDimensions
Return the current viewport size, or (0, 0, 1, 1) before first layout.
reset_window_dimensions
¶
Reset window dimensions back to (0, 0, 1, 1). Intended for tests.
set_screen_dimensions
¶
set_screen_dimensions(
width: float,
height: float,
*,
scale: Optional[float] = None,
font_scale: Optional[float] = None
) -> None
Publish the physical screen size in layout units.
The screen is the whole display (UIScreen.main.bounds /
DisplayMetrics), as opposed to the window the app occupies in
split view or with a keyboard showing. Hosts that can't tell the two
apart publish the window size here. Notifies subscribers only when a
value actually changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
float
|
Screen width in layout units. |
required |
height
|
float
|
Screen height in layout units. |
required |
scale
|
Optional[float]
|
Pixels per layout unit; |
None
|
font_scale
|
Optional[float]
|
Text-size multiplier; |
None
|
get_screen_dimensions
¶
get_screen_dimensions() -> WindowDimensions
Return the physical screen size, or the window size before a host publishes one.
reset_screen_dimensions
¶
Reset screen dimensions back to (0, 0, 1, 1). Intended for tests.
set_keyboard_height
¶
set_keyboard_height(height: float) -> None
Publish the on-screen keyboard height in layout units.
Negative inputs are clamped to 0.0. Notifies subscribers only
when the value actually changes.
get_keyboard_height
¶
get_keyboard_height() -> float
Return the current on-screen keyboard height, or 0.0 if hidden.
reset_keyboard_height
¶
Reset the keyboard height back to 0.0. Intended for tests.
ios_tab_bar_height
¶
ios_tab_bar_height() -> float
Return the iOS tab-bar intrinsic height in points.
Equal to IOS_TAB_BAR_BASE_HEIGHT_PT + safe_area_insets.bottom
so the bar reaches the home indicator. The iOS screen host
deliberately extends the root view past the bottom safe area for
this very reason; the tab bar absorbs the inset and UIKit
renders the pill with internal padding for the home indicator.
The Swift TabBarManager applies the same formula natively;
this Python copy keeps the layout engine's expectations testable
off device.
Next steps¶
- See the backend that ships these values natively in Native views.
- See the ops that position a view once it's measured in Mutation ops.
- See the other Python-side registry the native layer talks to in Events.
- Use the hooks that wrap these in Hooks.