feat: virtual button appearance control for fullscreen; building abi matrix control

This commit is contained in:
Miuzarte
2026-03-19 10:16:38 +08:00
parent 41d07b4582
commit c0c4ae1d23
7 changed files with 61 additions and 10 deletions

View File

@@ -3,6 +3,14 @@ plugins {
alias(libs.plugins.compose.compiler) alias(libs.plugins.compose.compiler)
} }
val defaultAbiList = listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
val configuredAbiList = (project.findProperty("abiList") as String?)
?.split(",")
?.map { it.trim() }
?.filter { it.isNotEmpty() }
?.ifEmpty { null }
?: defaultAbiList
android { android {
namespace = "io.github.miuzarte.scrcpyforandroid" namespace = "io.github.miuzarte.scrcpyforandroid"
compileSdk { compileSdk {
@@ -19,7 +27,8 @@ android {
versionName = "0.0.1" versionName = "0.0.1"
ndk { ndk {
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64") abiFilters.clear()
abiFilters += configuredAbiList
} }
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -29,7 +38,7 @@ android {
abi { abi {
isEnable = true isEnable = true
reset() reset()
include("armeabi-v7a", "arm64-v8a", "x86", "x86_64") include(*configuredAbiList.toTypedArray())
isUniversalApk = true isUniversalApk = true
} }
} }

View File

@@ -63,6 +63,7 @@ object AppDefaults {
const val DefaultMonetEnabled = false const val DefaultMonetEnabled = false
const val DefaultFullscreenDebugInfoEnabled = false const val DefaultFullscreenDebugInfoEnabled = false
const val DefaultShowFullscreenVirtualButtons = true
const val DefaultDevicePreviewCardHeightDp = 320 const val DefaultDevicePreviewCardHeightDp = 320
const val DefaultKeepScreenOnWhenStreamingEnabled = false const val DefaultKeepScreenOnWhenStreamingEnabled = false
const val DefaultVirtualButtonsOutside = "more,home,back" const val DefaultVirtualButtonsOutside = "more,home,back"

View File

@@ -7,6 +7,7 @@ object AppPreferenceKeys {
const val ThemeBaseIndex = "theme_base_index" const val ThemeBaseIndex = "theme_base_index"
const val MonetEnabled = "monet_enabled" const val MonetEnabled = "monet_enabled"
const val FullscreenDebugInfoEnabled = "fullscreen_debug_info_enabled" const val FullscreenDebugInfoEnabled = "fullscreen_debug_info_enabled"
const val ShowFullscreenVirtualButtons = "show_fullscreen_virtual_buttons"
const val DevicePreviewCardHeightDp = "device_preview_card_height_dp" const val DevicePreviewCardHeightDp = "device_preview_card_height_dp"
const val KeepScreenOnWhenStreamingEnabled = "keep_screen_on_when_streaming_enabled" const val KeepScreenOnWhenStreamingEnabled = "keep_screen_on_when_streaming_enabled"
const val VirtualButtonsOutside = "virtual_buttons_outside" const val VirtualButtonsOutside = "virtual_buttons_outside"

View File

@@ -41,6 +41,7 @@ fun FullscreenControlPage(
virtualButtonsOutside: List<String>, virtualButtonsOutside: List<String>,
virtualButtonsInMore: List<String>, virtualButtonsInMore: List<String>,
showDebugInfo: Boolean, showDebugInfo: Boolean,
showVirtualButtons: Boolean,
onDismiss: () -> Unit, onDismiss: () -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@@ -150,14 +151,16 @@ fun FullscreenControlPage(
}, },
) )
bar.Fullscreen( if (showVirtualButtons) {
modifier = Modifier.align(Alignment.BottomCenter), bar.Fullscreen(
onPressHaptic = { haptics.press() }, modifier = Modifier.align(Alignment.BottomCenter),
onConfirmHaptic = { haptics.confirm() }, onPressHaptic = { haptics.press() },
onAction = { action -> onConfirmHaptic = { haptics.confirm() },
action.keycode?.let(::sendKeycode) onAction = { action ->
}, action.keycode?.let(::sendKeycode)
) },
)
}
} }
} }
} }

View File

@@ -113,6 +113,9 @@ fun MainPage() {
var themeBaseIndex by rememberSaveable { mutableIntStateOf(initialSettings.themeBaseIndex) } var themeBaseIndex by rememberSaveable { mutableIntStateOf(initialSettings.themeBaseIndex) }
var monetEnabled by rememberSaveable { mutableStateOf(initialSettings.monetEnabled) } var monetEnabled by rememberSaveable { mutableStateOf(initialSettings.monetEnabled) }
var fullscreenDebugInfoEnabled by rememberSaveable { mutableStateOf(initialSettings.fullscreenDebugInfoEnabled) } var fullscreenDebugInfoEnabled by rememberSaveable { mutableStateOf(initialSettings.fullscreenDebugInfoEnabled) }
var showFullscreenVirtualButtons by rememberSaveable {
mutableStateOf(initialSettings.showFullscreenVirtualButtons)
}
var keepScreenOnWhenStreamingEnabled by rememberSaveable { var keepScreenOnWhenStreamingEnabled by rememberSaveable {
mutableStateOf(initialSettings.keepScreenOnWhenStreamingEnabled) mutableStateOf(initialSettings.keepScreenOnWhenStreamingEnabled)
} }
@@ -178,6 +181,7 @@ fun MainPage() {
themeBaseIndex, themeBaseIndex,
monetEnabled, monetEnabled,
fullscreenDebugInfoEnabled, fullscreenDebugInfoEnabled,
showFullscreenVirtualButtons,
keepScreenOnWhenStreamingEnabled, keepScreenOnWhenStreamingEnabled,
virtualButtonsOutside, virtualButtonsOutside,
virtualButtonsInMore, virtualButtonsInMore,
@@ -195,6 +199,7 @@ fun MainPage() {
themeBaseIndex = themeBaseIndex, themeBaseIndex = themeBaseIndex,
monetEnabled = monetEnabled, monetEnabled = monetEnabled,
fullscreenDebugInfoEnabled = fullscreenDebugInfoEnabled, fullscreenDebugInfoEnabled = fullscreenDebugInfoEnabled,
showFullscreenVirtualButtons = showFullscreenVirtualButtons,
keepScreenOnWhenStreamingEnabled = keepScreenOnWhenStreamingEnabled, keepScreenOnWhenStreamingEnabled = keepScreenOnWhenStreamingEnabled,
virtualButtonsOutside = VirtualButtonActions.encodeStoredIds(virtualButtonsOutside), virtualButtonsOutside = VirtualButtonActions.encodeStoredIds(virtualButtonsOutside),
virtualButtonsInMore = VirtualButtonActions.encodeStoredIds(virtualButtonsInMore), virtualButtonsInMore = VirtualButtonActions.encodeStoredIds(virtualButtonsInMore),
@@ -467,10 +472,14 @@ fun MainPage() {
onMonetEnabledChange = { monetEnabled = it }, onMonetEnabledChange = { monetEnabled = it },
fullscreenDebugInfoEnabled = fullscreenDebugInfoEnabled, fullscreenDebugInfoEnabled = fullscreenDebugInfoEnabled,
onFullscreenDebugInfoEnabledChange = { fullscreenDebugInfoEnabled = it }, onFullscreenDebugInfoEnabledChange = { fullscreenDebugInfoEnabled = it },
showFullscreenVirtualButtons = showFullscreenVirtualButtons,
onShowFullscreenVirtualButtonsChange = { showFullscreenVirtualButtons = it },
keepScreenOnWhenStreamingEnabled = keepScreenOnWhenStreamingEnabled, keepScreenOnWhenStreamingEnabled = keepScreenOnWhenStreamingEnabled,
onKeepScreenOnWhenStreamingEnabledChange = { onKeepScreenOnWhenStreamingEnabledChange = {
keepScreenOnWhenStreamingEnabled = it keepScreenOnWhenStreamingEnabled = it
}, },
onOpenReorderDevices = { openReorderDevicesAction?.invoke() },
onOpenVirtualButtonOrder = { rootBackStack.add(RootScreen.VirtualButtonOrder) },
devicePreviewCardHeightDp = devicePreviewCardHeightDp, devicePreviewCardHeightDp = devicePreviewCardHeightDp,
onDevicePreviewCardHeightDpChange = { onDevicePreviewCardHeightDpChange = {
devicePreviewCardHeightDp = it.coerceAtLeast(120) devicePreviewCardHeightDp = it.coerceAtLeast(120)
@@ -635,6 +644,7 @@ fun MainPage() {
virtualButtonsOutside = virtualButtonsOutside, virtualButtonsOutside = virtualButtonsOutside,
virtualButtonsInMore = virtualButtonsInMore, virtualButtonsInMore = virtualButtonsInMore,
showDebugInfo = fullscreenDebugInfoEnabled, showDebugInfo = fullscreenDebugInfoEnabled,
showVirtualButtons = showFullscreenVirtualButtons,
onDismiss = { popRoot() }, onDismiss = { popRoot() },
) )
} }

View File

@@ -22,6 +22,7 @@ import top.yukonga.miuix.kmp.basic.IconButton
import top.yukonga.miuix.kmp.basic.ScrollBehavior import top.yukonga.miuix.kmp.basic.ScrollBehavior
import top.yukonga.miuix.kmp.basic.Text import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TextField import top.yukonga.miuix.kmp.basic.TextField
import top.yukonga.miuix.kmp.extra.SuperArrow
import top.yukonga.miuix.kmp.extra.SuperDropdown import top.yukonga.miuix.kmp.extra.SuperDropdown
import top.yukonga.miuix.kmp.extra.SuperSwitch import top.yukonga.miuix.kmp.extra.SuperSwitch
import top.yukonga.miuix.kmp.theme.ColorSchemeMode import top.yukonga.miuix.kmp.theme.ColorSchemeMode
@@ -60,8 +61,12 @@ fun SettingsScreen(
onMonetEnabledChange: (Boolean) -> Unit, onMonetEnabledChange: (Boolean) -> Unit,
fullscreenDebugInfoEnabled: Boolean, fullscreenDebugInfoEnabled: Boolean,
onFullscreenDebugInfoEnabledChange: (Boolean) -> Unit, onFullscreenDebugInfoEnabledChange: (Boolean) -> Unit,
showFullscreenVirtualButtons: Boolean,
onShowFullscreenVirtualButtonsChange: (Boolean) -> Unit,
keepScreenOnWhenStreamingEnabled: Boolean, keepScreenOnWhenStreamingEnabled: Boolean,
onKeepScreenOnWhenStreamingEnabledChange: (Boolean) -> Unit, onKeepScreenOnWhenStreamingEnabledChange: (Boolean) -> Unit,
onOpenReorderDevices: () -> Unit,
onOpenVirtualButtonOrder: () -> Unit,
devicePreviewCardHeightDp: Int, devicePreviewCardHeightDp: Int,
onDevicePreviewCardHeightDpChange: (Int) -> Unit, onDevicePreviewCardHeightDpChange: (Int) -> Unit,
customServerUri: String?, customServerUri: String?,
@@ -106,6 +111,12 @@ fun SettingsScreen(
checked = fullscreenDebugInfoEnabled, checked = fullscreenDebugInfoEnabled,
onCheckedChange = onFullscreenDebugInfoEnabledChange, onCheckedChange = onFullscreenDebugInfoEnabledChange,
) )
SuperSwitch(
title = "全屏显示虚拟按钮",
summary = "在全屏模式底部显示返回/主页等虚拟按钮",
checked = showFullscreenVirtualButtons,
onCheckedChange = onShowFullscreenVirtualButtonsChange,
)
SuperSwitch( SuperSwitch(
title = "投屏时不允许息屏", title = "投屏时不允许息屏",
summary = "Scrcpy 启动后保持本机常亮,避免锁屏导致 ADB 断开", summary = "Scrcpy 启动后保持本机常亮,避免锁屏导致 ADB 断开",
@@ -128,6 +139,16 @@ fun SettingsScreen(
raw.toIntOrNull()?.let { onDevicePreviewCardHeightDpChange(it.coerceAtLeast(120)) } raw.toIntOrNull()?.let { onDevicePreviewCardHeightDpChange(it.coerceAtLeast(120)) }
}, },
) )
SuperArrow(
title = "调整设备排序",
summary = "调整设备页快捷设备列表顺序",
onClick = onOpenReorderDevices,
)
SuperArrow(
title = "虚拟按钮排序",
summary = "调整底部虚拟按钮与更多菜单顺序",
onClick = onOpenVirtualButtonOrder,
)
} }
SectionSmallTitle(text = "scrcpy-server") SectionSmallTitle(text = "scrcpy-server")

View File

@@ -9,6 +9,7 @@ internal data class MainSettings(
val themeBaseIndex: Int = AppDefaults.DefaultThemeBaseIndex, val themeBaseIndex: Int = AppDefaults.DefaultThemeBaseIndex,
val monetEnabled: Boolean = AppDefaults.DefaultMonetEnabled, val monetEnabled: Boolean = AppDefaults.DefaultMonetEnabled,
val fullscreenDebugInfoEnabled: Boolean = AppDefaults.DefaultFullscreenDebugInfoEnabled, val fullscreenDebugInfoEnabled: Boolean = AppDefaults.DefaultFullscreenDebugInfoEnabled,
val showFullscreenVirtualButtons: Boolean = AppDefaults.DefaultShowFullscreenVirtualButtons,
val devicePreviewCardHeightDp: Int = AppDefaults.DefaultDevicePreviewCardHeightDp, val devicePreviewCardHeightDp: Int = AppDefaults.DefaultDevicePreviewCardHeightDp,
val keepScreenOnWhenStreamingEnabled: Boolean = AppDefaults.DefaultKeepScreenOnWhenStreamingEnabled, val keepScreenOnWhenStreamingEnabled: Boolean = AppDefaults.DefaultKeepScreenOnWhenStreamingEnabled,
val virtualButtonsOutside: String = AppDefaults.DefaultVirtualButtonsOutside, val virtualButtonsOutside: String = AppDefaults.DefaultVirtualButtonsOutside,
@@ -70,6 +71,10 @@ internal fun loadMainSettings(context: Context): MainSettings {
AppPreferenceKeys.FullscreenDebugInfoEnabled, AppPreferenceKeys.FullscreenDebugInfoEnabled,
AppDefaults.DefaultFullscreenDebugInfoEnabled, AppDefaults.DefaultFullscreenDebugInfoEnabled,
), ),
showFullscreenVirtualButtons = prefs.getBoolean(
AppPreferenceKeys.ShowFullscreenVirtualButtons,
AppDefaults.DefaultShowFullscreenVirtualButtons,
),
devicePreviewCardHeightDp = prefs.getInt( devicePreviewCardHeightDp = prefs.getInt(
AppPreferenceKeys.DevicePreviewCardHeightDp, AppPreferenceKeys.DevicePreviewCardHeightDp,
AppDefaults.DefaultDevicePreviewCardHeightDp, AppDefaults.DefaultDevicePreviewCardHeightDp,
@@ -108,6 +113,7 @@ internal fun saveMainSettings(context: Context, settings: MainSettings) {
putInt(AppPreferenceKeys.ThemeBaseIndex, settings.themeBaseIndex) putInt(AppPreferenceKeys.ThemeBaseIndex, settings.themeBaseIndex)
.putBoolean(AppPreferenceKeys.MonetEnabled, settings.monetEnabled) .putBoolean(AppPreferenceKeys.MonetEnabled, settings.monetEnabled)
.putBoolean(AppPreferenceKeys.FullscreenDebugInfoEnabled, settings.fullscreenDebugInfoEnabled) .putBoolean(AppPreferenceKeys.FullscreenDebugInfoEnabled, settings.fullscreenDebugInfoEnabled)
.putBoolean(AppPreferenceKeys.ShowFullscreenVirtualButtons, settings.showFullscreenVirtualButtons)
.putInt(AppPreferenceKeys.DevicePreviewCardHeightDp, settings.devicePreviewCardHeightDp.coerceAtLeast(120)) .putInt(AppPreferenceKeys.DevicePreviewCardHeightDp, settings.devicePreviewCardHeightDp.coerceAtLeast(120))
.putBoolean(AppPreferenceKeys.KeepScreenOnWhenStreamingEnabled, settings.keepScreenOnWhenStreamingEnabled) .putBoolean(AppPreferenceKeys.KeepScreenOnWhenStreamingEnabled, settings.keepScreenOnWhenStreamingEnabled)
.putString(AppPreferenceKeys.VirtualButtonsOutside, settings.virtualButtonsOutside) .putString(AppPreferenceKeys.VirtualButtonsOutside, settings.virtualButtonsOutside)