From 53f130aba27780a6e734f4565c3b7cd43a1d16ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 2 Feb 2026 19:02:36 +0800 Subject: [PATCH] Fix tablet mode falsely triggered on phones with low DPI --- app/build.gradle.kts | 3 +++ .../main/java/io/nekohasekai/sfa/compose/MainActivity.kt | 8 ++++---- .../io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt | 8 ++++---- .../compose/screen/connections/ConnectionDetailsScreen.kt | 2 +- .../io/nekohasekai/sfa/compose/screen/log/LogScreen.kt | 8 ++++---- .../compose/screen/profileoverride/PerAppProxyScreen.kt | 2 +- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3314e43..87f3128 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -271,6 +271,7 @@ dependencies { "playImplementation"(composeBom23) "playImplementation"("androidx.compose.material3:material3") + "playImplementation"("androidx.compose.material3.adaptive:adaptive") "playImplementation"("androidx.compose.ui:ui") "playImplementation"("androidx.compose.ui:ui-tooling-preview") "playImplementation"("androidx.compose.material:material-icons-extended") @@ -281,6 +282,7 @@ dependencies { "otherImplementation"(composeBom23) "otherImplementation"("androidx.compose.material3:material3") + "otherImplementation"("androidx.compose.material3.adaptive:adaptive") "otherImplementation"("androidx.compose.ui:ui") "otherImplementation"("androidx.compose.ui:ui-tooling-preview") "otherImplementation"("androidx.compose.material:material-icons-extended") @@ -296,6 +298,7 @@ dependencies { "otherLegacyImplementation"(composeBom21) "otherLegacyImplementation"("androidx.compose.material3:material3") + "otherLegacyImplementation"("androidx.compose.material3.adaptive:adaptive") "otherLegacyImplementation"("androidx.compose.ui:ui") "otherLegacyImplementation"("androidx.compose.ui:ui-tooling-preview") "otherLegacyImplementation"("androidx.compose.material:material-icons-extended") diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt b/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt index 0db7e5d..486f7eb 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/MainActivity.kt @@ -3,7 +3,6 @@ package io.nekohasekai.sfa.compose import android.Manifest import android.annotation.SuppressLint import android.content.Intent -import android.content.res.Configuration import android.net.VpnService import android.os.Build import android.os.Bundle @@ -53,6 +52,7 @@ import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton +import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -66,7 +66,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp @@ -79,6 +78,7 @@ import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController +import androidx.window.core.layout.WindowSizeClass import dev.jeziellago.compose.markdowntext.MarkdownText import io.nekohasekai.libbox.Libbox import io.nekohasekai.sfa.Application @@ -279,9 +279,9 @@ class MainActivity : val currentRoute = currentDestination?.route val scope = rememberCoroutineScope() - val configuration = LocalConfiguration.current + val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass val useNavigationRail = - configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE) + windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) // Snackbar state val snackbarHostState = remember { SnackbarHostState() } diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt b/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt index 2e4cdf3..2eddc13 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/component/qr/QRSDialog.kt @@ -1,7 +1,6 @@ package io.nekohasekai.sfa.compose.component.qr import android.content.Intent -import android.content.res.Configuration import android.graphics.Color import android.net.Uri import androidx.compose.foundation.Image @@ -33,6 +32,7 @@ import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Slider import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect @@ -46,12 +46,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties +import androidx.window.core.layout.WindowSizeClass import io.nekohasekai.sfa.R import io.nekohasekai.sfa.qrs.QRSConstants import io.nekohasekai.sfa.qrs.QRSEncoder @@ -60,8 +60,8 @@ import kotlinx.coroutines.delay @Composable fun QRSDialog(profileData: ByteArray, profileName: String, onDismiss: () -> Unit) { val context = LocalContext.current - val configuration = LocalConfiguration.current - val isTablet = configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE) + val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass + val isTablet = windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) val coroutineScope = rememberCoroutineScope() var fps by remember { mutableIntStateOf(QRSConstants.DEFAULT_FPS) } var sliceSize by remember { mutableIntStateOf(QRSConstants.DEFAULT_SLICE_SIZE) } diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/screen/connections/ConnectionDetailsScreen.kt b/app/src/main/java/io/nekohasekai/sfa/compose/screen/connections/ConnectionDetailsScreen.kt index 9786217..fab586e 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/screen/connections/ConnectionDetailsScreen.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/screen/connections/ConnectionDetailsScreen.kt @@ -2,7 +2,6 @@ package io.nekohasekai.sfa.compose.screen.connections import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope @@ -13,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt b/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt index 85770dd..886629b 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/screen/log/LogScreen.kt @@ -2,7 +2,6 @@ package io.nekohasekai.sfa.compose.screen.log import android.content.ClipData import android.content.Intent -import android.content.res.Configuration import android.os.Build import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult @@ -68,6 +67,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar +import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -81,7 +81,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource @@ -91,6 +90,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.content.FileProvider import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.window.core.layout.WindowSizeClass import io.nekohasekai.sfa.Application import io.nekohasekai.sfa.R import io.nekohasekai.sfa.compose.topbar.OverrideTopBar @@ -118,8 +118,8 @@ fun LogScreen( val resolvedViewModel = viewModel ?: viewModel() val uiState by resolvedViewModel.uiState.collectAsState() val context = LocalContext.current - val configuration = LocalConfiguration.current - val isTablet = configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE) + val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass + val isTablet = windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) val listState = rememberLazyListState() val coroutineScope = rememberCoroutineScope() val resolvedTitle = title ?: stringResource(R.string.title_log) diff --git a/app/src/main/java/io/nekohasekai/sfa/compose/screen/profileoverride/PerAppProxyScreen.kt b/app/src/main/java/io/nekohasekai/sfa/compose/screen/profileoverride/PerAppProxyScreen.kt index e3e9cf1..74b8986 100644 --- a/app/src/main/java/io/nekohasekai/sfa/compose/screen/profileoverride/PerAppProxyScreen.kt +++ b/app/src/main/java/io/nekohasekai/sfa/compose/screen/profileoverride/PerAppProxyScreen.kt @@ -3,7 +3,6 @@ package io.nekohasekai.sfa.compose.screen.profileoverride import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.os.Build -import io.nekohasekai.sfa.Application import android.util.Log import android.widget.Toast import androidx.compose.animation.AnimatedVisibility @@ -76,6 +75,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.android.tools.smali.dexlib2.dexbacked.DexBackedDexFile +import io.nekohasekai.sfa.Application import io.nekohasekai.sfa.R import io.nekohasekai.sfa.compose.shared.AppSelectionCard import io.nekohasekai.sfa.compose.shared.PackageCache