vc=29: fullscreen overlay controls respect display cutout + status bar

In portrait fullscreen, the camera notch / cutout was eating the top
overlay buttons — SB pill, Speed, Headphones, Videocam, Share, PiP,
Minimize. Tappable area sat under the cutout shadow; presses dropped.

Wrapped the overlay layer (SB pill + control Row) in a Box with
windowInsetsPadding(WindowInsets.safeDrawing). safeDrawing is the
union of system bars + display cutouts + IME, so this single modifier
covers both portrait (notch at top) and landscape (cutout at side)
without per-orientation logic. The PlayerView itself still uses
fillMaxSize with no inset padding — video stays full-bleed and reads
as immersive; only the touch-targets respect the safe area.
This commit is contained in:
Sulkta 2026-05-25 11:54:45 -07:00
parent 9d0f8cc741
commit bb29a76c2a
2 changed files with 17 additions and 2 deletions

View file

@ -55,6 +55,6 @@ const val NEWPIPE_APPLICATION_ID_NEW = "net.newpipe.app"
// vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via // vc=19 / 0.1.0-AE — rust pipeline cutover. Extraction via
// strawcore-core (Sulkta-OSS/strawcore) via the UniFFI wrapper; no // strawcore-core (Sulkta-OSS/strawcore) via the UniFFI wrapper; no
// NewPipeExtractor in the runtime path. // NewPipeExtractor in the runtime path.
const val STRAW_VERSION_CODE = 28 const val STRAW_VERSION_CODE = 29
const val STRAW_VERSION_NAME = "0.1.0-AN" const val STRAW_VERSION_NAME = "0.1.0-AO"
const val STRAW_APPLICATION_ID = "com.sulkta.straw" const val STRAW_APPLICATION_ID = "com.sulkta.straw"

View file

@ -27,9 +27,12 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.filled.KeyboardArrowDown
@ -153,6 +156,8 @@ fun PlayerScreen(
) )
else -> { else -> {
// Video surface — bleeds full-screen including under any
// display cutout / camera notch. Looks more immersive.
AndroidView( AndroidView(
factory = { ctx -> factory = { ctx ->
PlayerView(ctx).apply { PlayerView(ctx).apply {
@ -164,6 +169,15 @@ fun PlayerScreen(
onRelease = { it.player = null }, onRelease = { it.player = null },
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) )
// Overlay controls layer — sits inside the safe area so
// buttons don't get eaten by the notch in portrait or by
// a side cutout in landscape. SafeDrawing covers system
// bars + display cutouts in one go.
Box(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing),
) {
Box( Box(
modifier = Modifier modifier = Modifier
.align(Alignment.TopStart) .align(Alignment.TopStart)
@ -231,6 +245,7 @@ fun PlayerScreen(
onMinimize() onMinimize()
} }
} }
} // close safe-area overlay Box
if (showSpeedDialog) { if (showSpeedDialog) {
SpeedPickerDialog( SpeedPickerDialog(