feat: fullscreen compatibility mode

This commit is contained in:
Miuzarte
2026-04-26 13:57:14 +08:00
parent 63e161ac7c
commit f7703edd22
6 changed files with 93 additions and 15 deletions

View File

@@ -2,6 +2,10 @@
~~什么我居然开始写更新日志了~~
## 0.2.8
- 新增: 全屏兼容模式
## 0.2.7
- 新增: 日志框隐藏

View File

@@ -56,8 +56,8 @@ android {
applicationId = "io.github.miuzarte.scrcpyforandroid"
minSdk = 26
targetSdk = 37
versionCode = 23
versionName = "0.2.7"
versionCode = 24
versionName = "0.2.8"
externalNativeBuild {
cmake {

View File

@@ -133,6 +133,7 @@ internal fun DeviceTabScreen(
bottomInnerPadding: Dp,
onOpenReorderDevices: () -> Unit,
onPreviewGestureLockChanged: (Boolean) -> Unit = {},
onOpenFullscreenCompat: () -> Unit = {},
) {
val navigator = LocalRootNavigator.current
var showThreePointMenu by rememberSaveable { mutableStateOf(false) }
@@ -249,6 +250,7 @@ internal fun DeviceTabScreen(
bottomInnerPadding = bottomInnerPadding,
twoPaneSideToggleRequest = twoPaneSideToggleRequest,
onPreviewGestureLockChanged = onPreviewGestureLockChanged,
onOpenFullscreenCompat = onOpenFullscreenCompat,
onCompactTopAppBarChanged = ::setTopAppBarCompact,
onTwoPaneSideActionChanged = ::setTwoPaneSideAction,
)
@@ -266,6 +268,7 @@ internal fun DeviceTabPage(
bottomInnerPadding: Dp,
twoPaneSideToggleRequest: Int = 0,
onPreviewGestureLockChanged: (Boolean) -> Unit = {},
onOpenFullscreenCompat: () -> Unit = {},
onCompactTopAppBarChanged: (Boolean) -> Unit = {},
onTwoPaneSideActionChanged: (Boolean, Boolean) -> Unit = { _, _ -> },
) {
@@ -738,6 +741,14 @@ internal fun DeviceTabPage(
}
}
fun openFullscreenControl() {
if (asBundle.fullscreenCompatibilityMode) {
onOpenFullscreenCompat()
} else {
context.startActivity(StreamActivity.createIntent(context))
}
}
suspend fun startScrcpySession(
openFullscreen: Boolean = false,
startAppOverride: String? = null,
@@ -768,7 +779,7 @@ internal fun DeviceTabPage(
resolvedOptions.video &&
resolvedOptions.videoPlayback
) withContext(Dispatchers.Main) {
context.startActivity(StreamActivity.createIntent(context))
openFullscreenControl()
}
if (resolvedOptions.disableScreensaver)
AppScreenOn.acquire()
@@ -1201,9 +1212,7 @@ internal fun DeviceTabPage(
sessionInfo = sessionInfo,
onDisconnect = { adbCallbacks.onDisconnectCurrent(currentTarget) },
showFullscreenAction = false,
onOpenFullscreen = {
context.startActivity(StreamActivity.createIntent(context))
},
onOpenFullscreen = ::openFullscreenControl,
)
}
@@ -1216,9 +1225,7 @@ internal fun DeviceTabPage(
modifier = modifier,
sessionInfo = sessionInfo,
previewHeightDp = asBundle.devicePreviewCardHeightDp.coerceAtLeast(120),
onOpenFullscreen = {
context.startActivity(StreamActivity.createIntent(context))
},
onOpenFullscreen = ::openFullscreenControl,
directControlEnabled = directControlEnabled,
onInjectTouch = { action, pointerId, x, y, pressure, actionButton, buttons ->
val session = sessionInfo
@@ -1319,9 +1326,7 @@ internal fun DeviceTabPage(
sessionInfo = sessionInfo,
onDisconnect = { adbCallbacks.onDisconnectCurrent(currentTarget) },
showFullscreenAction = canShowPreviewControls,
onOpenFullscreen = {
context.startActivity(StreamActivity.createIntent(context))
},
onOpenFullscreen = ::openFullscreenControl,
reverseSideActions = asBundle.deviceTwoPaneConfigOnRight,
)
}

View File

@@ -2,6 +2,7 @@ package io.github.miuzarte.scrcpyforandroid.pages
import android.app.Activity
import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.SystemClock
import android.provider.OpenableColumns
@@ -50,6 +51,9 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberDecoratedNavEntries
@@ -149,6 +153,7 @@ sealed interface RootScreen : NavKey {
data object Advanced : RootScreen
data object About : RootScreen
data object VirtualButtonOrder : RootScreen
data object FullscreenControl : RootScreen // compatibility mode
data class ScrcpyOptionRecord(val profileId: String) : RootScreen
}
@@ -384,8 +389,10 @@ fun MainScreen() {
}
// Derived flags
val canNavigateBack = rootBackStack.size > 1
|| selectedTabIndex != MainBottomTabDestination.Devices.ordinal
val isFullscreenControlRoute = currentRootScreen is RootScreen.FullscreenControl
val canNavigateBack = !isFullscreenControlRoute &&
(rootBackStack.size > 1
|| selectedTabIndex != MainBottomTabDestination.Devices.ordinal)
fun navigateToTab(tab: MainBottomTabDestination) {
val targetIndex = tab.ordinal
@@ -574,6 +581,9 @@ fun MainScreen() {
onPreviewGestureLockChanged = { locked ->
devicePreviewGestureLock = locked
},
onOpenFullscreenCompat = {
rootNavigator.push(RootScreen.FullscreenControl)
},
)
MainBottomTabDestination.Terminal -> TerminalScreen(
@@ -667,6 +677,49 @@ fun MainScreen() {
)
}
entry(RootScreen.FullscreenControl) {
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(currentSession) {
if (currentSession == null) rootNavigator.pop()
}
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_STOP) {
rootNavigator.pop()
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
DisposableEffect(activity) {
onDispose {
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
}
}
FullscreenControlScreen(
scrcpy = scrcpy,
onBack = rootNavigator.pop,
isInPip = false,
onVideoSizeChanged = { width, height ->
activity?.requestedOrientation =
if (width >= height) {
if (asBundle.fullscreenControlIgnoreSystemRotationLock)
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
else
ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
} else {
if (asBundle.fullscreenControlIgnoreSystemRotationLock)
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
else
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
}
},
onVideoBoundsInWindowChanged = {},
)
}
entry<RootScreen.ScrcpyOptionRecord> { route ->
RecordPreferencesScreen(
scrollBehavior = advancedPageScrollBehavior,
@@ -674,7 +727,6 @@ fun MainScreen() {
scrcpy = scrcpy,
)
}
}
val rootEntries = rememberDecoratedNavEntries(

View File

@@ -631,6 +631,16 @@ fun SettingsPage(
)
}
}
SwitchPreference(
title = "全屏兼容模式",
summary = "启用后全屏控制页不再跨 Activity会导致画中画不可用",
checked = asBundle.fullscreenCompatibilityMode,
onCheckedChange = {
asBundle = asBundle.copy(
fullscreenCompatibilityMode = it
)
},
)
}
}

View File

@@ -164,6 +164,10 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") {
intPreferencesKey("fullscreen_floating_button_ring_alpha_percent"),
100,
)
val FULLSCREEN_COMPATIBILITY_MODE = Pair(
booleanPreferencesKey("fullscreen_compatibility_mode"),
false,
)
val FULLSCREEN_FLOATING_BUTTON_X_FRACTION = Pair(
floatPreferencesKey("fullscreen_floating_button_x_fraction"),
@@ -304,6 +308,7 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") {
val fullscreenFloatingButtonSizeDp: Int,
val fullscreenFloatingButtonBackgroundAlphaPercent: Int,
val fullscreenFloatingButtonRingAlphaPercent: Int,
val fullscreenCompatibilityMode: Boolean,
val fullscreenFloatingButtonXFraction: Float,
val fullscreenFloatingButtonYFraction: Float,
@@ -366,6 +371,7 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") {
bundleField(FULLSCREEN_FLOATING_BUTTON_SIZE_DP) { it.fullscreenFloatingButtonSizeDp },
bundleField(FULLSCREEN_FLOATING_BUTTON_BACKGROUND_ALPHA_PERCENT) { it.fullscreenFloatingButtonBackgroundAlphaPercent },
bundleField(FULLSCREEN_FLOATING_BUTTON_RING_ALPHA_PERCENT) { it.fullscreenFloatingButtonRingAlphaPercent },
bundleField(FULLSCREEN_COMPATIBILITY_MODE) { it.fullscreenCompatibilityMode },
bundleField(FULLSCREEN_FLOATING_BUTTON_X_FRACTION) { it.fullscreenFloatingButtonXFraction },
bundleField(FULLSCREEN_FLOATING_BUTTON_Y_FRACTION) { it.fullscreenFloatingButtonYFraction },
@@ -432,6 +438,7 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") {
preferences.read(FULLSCREEN_FLOATING_BUTTON_BACKGROUND_ALPHA_PERCENT),
fullscreenFloatingButtonRingAlphaPercent =
preferences.read(FULLSCREEN_FLOATING_BUTTON_RING_ALPHA_PERCENT),
fullscreenCompatibilityMode = preferences.read(FULLSCREEN_COMPATIBILITY_MODE),
fullscreenFloatingButtonXFraction = preferences.read(FULLSCREEN_FLOATING_BUTTON_X_FRACTION),
fullscreenFloatingButtonYFraction = preferences.read(FULLSCREEN_FLOATING_BUTTON_Y_FRACTION),