diff --git a/app/shared/pages/episode-play/common/EpisodePage.kt b/app/shared/pages/episode-play/common/EpisodePage.kt index f1f79db74b..b104b6d677 100644 --- a/app/shared/pages/episode-play/common/EpisodePage.kt +++ b/app/shared/pages/episode-play/common/EpisodePage.kt @@ -285,6 +285,10 @@ private fun EpisodeVideo( context.setRequestFullScreen(true) } }, + onExitFullscreen = { + context.setRequestFullScreen(false) + vm.isFullscreen = false + }, danmakuEnabled = { danmakuEnabled }, setDanmakuEnabled = { vm.launchInBackground { danmaku.setEnabled(it) } }, danmakuEditor = { diff --git a/app/shared/pages/episode-play/common/EpisodeVideo.kt b/app/shared/pages/episode-play/common/EpisodeVideo.kt index 8328aeced2..9d635c77bc 100644 --- a/app/shared/pages/episode-play/common/EpisodeVideo.kt +++ b/app/shared/pages/episode-play/common/EpisodeVideo.kt @@ -68,6 +68,7 @@ internal fun EpisodeVideoImpl( videoLoadingState: () -> VideoLoadingState, danmakuConfig: () -> DanmakuConfig, onClickFullScreen: () -> Unit, + onExitFullscreen: () -> Unit, danmakuEnabled: () -> Boolean, setDanmakuEnabled: (enabled: Boolean) -> Unit, danmakuEditor: @Composable (RowScope.() -> Unit), @@ -159,7 +160,8 @@ internal fun EpisodeVideoImpl( }, onToggleFullscreen = { onClickFullScreen() - } + }, + onExitFullscreen = onExitFullscreen, ) }, floatingMessage = { diff --git a/app/shared/video-player/common/ui/guesture/GestureLock.kt b/app/shared/video-player/common/ui/guesture/GestureLock.kt index 8f9ae215c9..ccb83bbfee 100644 --- a/app/shared/video-player/common/ui/guesture/GestureLock.kt +++ b/app/shared/video-player/common/ui/guesture/GestureLock.kt @@ -128,6 +128,7 @@ fun LockableVideoGestureHost( modifier: Modifier = Modifier, onTogglePauseResume: () -> Unit = {}, onToggleFullscreen: () -> Unit = {}, + onExitFullscreen: () -> Unit = {}, ) { if (locked) { LockedScreenGestureHost(controllerVisible, setControllerVisible, modifier) @@ -145,6 +146,7 @@ fun LockableVideoGestureHost( }, onTogglePauseResume = onTogglePauseResume, onToggleFullscreen = onToggleFullscreen, + onExitFullscreen = onExitFullscreen, ) } } diff --git a/app/shared/video-player/common/ui/guesture/VideoGestureHost.kt b/app/shared/video-player/common/ui/guesture/VideoGestureHost.kt index 1884c58d55..643f5bc53a 100644 --- a/app/shared/video-player/common/ui/guesture/VideoGestureHost.kt +++ b/app/shared/video-player/common/ui/guesture/VideoGestureHost.kt @@ -57,6 +57,7 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.coerceAtLeast import androidx.compose.ui.unit.dp @@ -358,6 +359,7 @@ enum class GestureFamily( val keyboardUpDownForVolume: Boolean = true, val keyboardLeftRightToSeek: Boolean = true, val mouseHoverForController: Boolean = true, + val escToExitFullscreen: Boolean = true, ) { TOUCH( clickToPauseResume = false, @@ -392,6 +394,7 @@ fun VideoGestureHost( onToggleControllerVisibility: (setVisible: Boolean?) -> Unit = {}, onTogglePauseResume: () -> Unit = {}, onToggleFullscreen: () -> Unit = {}, + onExitFullscreen: () -> Unit = {}, ) { val onTogglePauseResumeState by rememberUpdatedState(onTogglePauseResume) val onToggleControllerVisibilityState by rememberUpdatedState(onToggleControllerVisibility) @@ -424,9 +427,12 @@ fun VideoGestureHost( val indicatorTasker = rememberUiMonoTasker() val focusRequester = remember { FocusRequester() } + val manager = LocalFocusManager.current + val keyboardFocus = remember { FocusRequester() } // focus 了才能用键盘快捷键 Box( modifier + .focusRequester(keyboardFocus) .padding(top = 60.dp) .ifThen(family.swipeToSeek) { swipeToSeek(seekerState, Orientation.Horizontal) @@ -460,12 +466,21 @@ fun VideoGestureHost( val scope = rememberUiMonoTasker() onPointerEventMultiplatform(PointerEventType.Move) { events -> onToggleControllerVisibilityState(true) + keyboardFocus.requestFocus() scope.launch { delay(3000) onToggleControllerVisibilityState(false) } } } + .ifThen(family.escToExitFullscreen) { + onKey(ComposeKey.Escape) { + if (needWorkaroundForFocusManager) { + manager.clearFocus() + } + onExitFullscreen() + } + } .fillMaxSize() ) { Box( @@ -473,7 +488,7 @@ fun VideoGestureHost( .ifThen(needWorkaroundForFocusManager) { onFocusEvent { if (it.hasFocus) { - focusRequester.requestFocus() // 随便转移走就行 + focusRequester.requestFocus() } } } @@ -493,6 +508,9 @@ fun VideoGestureHost( }, onDoubleClick = remember(family, onToggleFullscreen) { { + if (needWorkaroundForFocusManager) { + manager.clearFocus() + } if (family.doubleClickToFullscreen) { onToggleFullscreen() }