diff --git a/CHANGELOG.md b/CHANGELOG.md index e5c08a2..ef667c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ~~什么我居然开始写更新日志了~~ +## 0.2.8 + +- 新增: 全屏兼容模式 + ## 0.2.7 - 新增: 日志框隐藏 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a05112b..3cd09b6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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 { diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/DeviceTabScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/DeviceTabScreen.kt index 37d08ca..2caa50c 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/DeviceTabScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/DeviceTabScreen.kt @@ -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, ) } diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt index 64c4146..cccbfc6 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt @@ -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 { route -> RecordPreferencesScreen( scrollBehavior = advancedPageScrollBehavior, @@ -674,7 +727,6 @@ fun MainScreen() { scrcpy = scrcpy, ) } - } val rootEntries = rememberDecoratedNavEntries( diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt index 01b1e3c..5e5aad0 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt @@ -631,6 +631,16 @@ fun SettingsPage( ) } } + SwitchPreference( + title = "全屏兼容模式", + summary = "启用后全屏控制页不再跨 Activity,会导致画中画不可用", + checked = asBundle.fullscreenCompatibilityMode, + onCheckedChange = { + asBundle = asBundle.copy( + fullscreenCompatibilityMode = it + ) + }, + ) } } diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt index 1dff42a..2932f04 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt @@ -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),