fix(player): opening key-up no longer clicks the freshly focused pause button

The key-down that opens the overlay is consumed by the activity, but its
key-up arrived after the play button grabbed focus and clicked it —
instant pause right after the overlay appeared. The overlay now swallows
select-releases whose press it never saw.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
be-nj
2026-08-26 00:32:22 +02:00
parent d98f277ec4
commit 11a8056ce2
2 changed files with 24 additions and 4 deletions

View File

@@ -12,8 +12,8 @@ android {
applicationId = "dev.castarr.tv"
minSdk = 26
targetSdk = 35
versionCode = 11
versionName = "0.6.0"
versionCode = 12
versionName = "0.6.1"
}
// Release signing from environment (see ~/.keys/castarr-release.env on the

View File

@@ -17,7 +17,10 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -26,8 +29,12 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
@@ -97,14 +104,27 @@ private fun formatClock(millis: Long): String =
private fun Overlay(state: AppState) {
val playFocus = remember { FocusRequester() }
LaunchedEffect(Unit) { playFocus.requestFocus() }
// The key-UP of the very press that opened this overlay arrives after
// the play button grabbed focus and would click it (instant pause).
// Swallow select-releases whose press the overlay never saw.
var sawSelectDown by remember { mutableStateOf(false) }
Box(
Modifier
.fillMaxSize()
// Any key while the overlay is open keeps it open a while longer.
.onPreviewKeyEvent {
.onPreviewKeyEvent { event ->
state.pingOverlay()
val select = event.key == Key.DirectionCenter ||
event.key == Key.Enter || event.key == Key.NumPadEnter
when {
select && event.type == KeyEventType.KeyDown -> {
sawSelectDown = true
false
}
select && event.type == KeyEventType.KeyUp && !sawSelectDown -> true
else -> false
}
},
) {
Box(