Skip to content

fix(android): a screen's bg-* doesn't reach the edges in landscape - #528

Merged
simonhamp merged 3 commits into
NativePHP:mainfrom
SRWieZ:fix/android-screen-bg-fills-safe-areas
Oct 26, 2026
Merged

simonhamp merged 3 commits into
NativePHP:mainfrom
SRWieZ:fix/android-screen-bg-fills-safe-areas

Conversation

@SRWieZ

@SRWieZ SRWieZ commented Oct 3, 2026

Copy link
Copy Markdown
Member

What's wrong

On Android in landscape, a screen's background colour (bg-*) doesn't reach the edges. The strip beside the camera and the strip behind the navigation buttons keep the app theme's colour instead. iOS already fills them with the screen's colour (#477).

Before After
before after

Why

Android shrinks the screen by those strips, and the space left behind shows the container's default colour.

What this does

The screen's background (bg-*, or its dark-mode variant) is also painted behind those strips. Screens without a background don't change. It covers both layouts (normal and tabs) through one small helper. Android only.

How to reproduce

Open this screen on Android and rotate to landscape.

// routes/mobile.php
Route::native('/repro/screen-background', \App\NativeComponents\ScreenBackground::class);
// app/NativeComponents/ScreenBackground.php
namespace App\NativeComponents;

use Illuminate\View\View;
use Native\Mobile\Edge\NativeComponent;

class ScreenBackground extends NativeComponent
{
    public function render(): View
    {
        return view('native.screen-background');
    }
}
{{-- resources/views/native/screen-background.blade.php --}}
<native:column class="w-full h-full bg-zinc-900 items-center justify-center">
    <native:top-bar title="Background" />
    <native:text class="text-[17] text-white">Rotate to landscape</native:text>
</native:column>

Tested on an Android 16 emulator (stack layout).

In landscape the root renderers inset each screen by the Scaffold
padding, so the strips beside the camera cutout and behind the
navigation bar showed the Scaffold's default colour instead of the
screen's own background. A shared screenBackground() modifier now paints
the screen's flat background (bg-*, or its dark variant) behind that
padding, in both the stack and the tabs renderer — iOS fills the safe
areas with the screen background since NativePHP#477.
@simonhamp

Copy link
Copy Markdown
Member

How does it behave with backgrounds that have transparency e.g. bg-red-500/50?

@simonhamp

Copy link
Copy Markdown
Member

And can you fix the conflicts?

Preserve the outgoing-level node cache and directional navigation transitions while painting screen backgrounds before safe-area padding. Keep both the screen-background helper and upstream top-bar image glyph, including accessibility behavior.
@SRWieZ

SRWieZ commented Oct 23, 2026

Copy link
Copy Markdown
Member Author

done!

@simonhamp

Copy link
Copy Markdown
Member

Sorry @SRWieZ, there's more 😬

Keep the chrome scroll controller and composition-local provider while painting the cached screen background before safe-area padding. Preserve upstream toolbar labels, image glyphs and accessibility behavior.
@SRWieZ

SRWieZ commented Oct 26, 2026

Copy link
Copy Markdown
Member Author

done!

@simonhamp
simonhamp merged commit 8828e20 into NativePHP:main Oct 26, 2026
5 checks passed
gwleuverink added a commit that referenced this pull request Nov 2, 2026
Covers mobile PRs #525, #527, #528, #560, #605, #608, #609, #611, #613, #614, #615, #616, #617, #619, #621, #622, #623, #624, #625, #626, #627, #628, #629, #632, #633, #634, #635 and #636, and the commits on main without a PR: 4082538 (bounded()'s docblock), 49528ba (the Android logging fix from a fork), b23aba9, 2a773cc and b9316b6 (security policy, issue template and README links). Main b107ed9..767a7c8, 33 commits, 4.6.1 among them.

Ported to core on branch sync/mobile-main-2026-11-01, which this merge needs: #608 (scrollVirtualListTo()), #625 with 4082538 (snap points on a gesture area), #621 (:context-menu on a pressable, matched through core's ConvertsToElement as :menu is), #617's farewell frame through a hook, and #614's ValidatesInput and FieldErrors, which move to core. The old names of those two resolve to core's through the alias shim.

Kept on this branch: #616 in full. EVENT_SYSTEM_BACK sits on NativeComponent next to EVENT_HOT_RELOAD and EVENT_SHUTDOWN, the router half is in NativeRouter, and InteractsWithAppShell's back button handler checks the constant, as main's runLoop() does. #617's element types: NativeComponent answers core's typesClosedInFarewellFrame() hook with bottom_sheet and modal. BroadcastsGlobally extends core's marker and #609's DispatchableFromNative.

Removed again in the merge: HasVirtualListWindow, GestureArea and Pressable (main changed them, core has them), and ValidatesInput and FieldErrors (main added them, core has them). Main's import of the old dispatcher name came out of DispatchEventFromAppController, where it clashed with core's.

Adapted for the extraction: BroadcastsGloballyNamesTest expects DispatchableFromNative among the old marker's interfaces, as #609 makes it.

#609 is merged as main has it and is not ported.

Needs NativePHP/core#18.

Tests, all on PHP 8.4.27, with dev dependencies updated for #628 (Laravel 12.70.2, Pest 3.8.7): mobile on this merge against the core sync branch (445049b), 2,467 passed, 4 risky, 4 skipped. PHPStan clean. Mobile main (767a7c8), 2,412 passed, 4 risky, 4 skipped. Desktop main (fd40580) against the core sync branch, test:php 2,240 passed, as against core main. Desktop #57 (977a2af), 2,245 passed against the earlier core sync head (59c73fc), which differs only by the constant moved to mobile; not rerun.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants