Correctly handle display cutout (#1139)

This commit is contained in:
FooIbar authored and GitHub committed 2024-05-06 14:34:22 +08:00
1 parent 60c6618db1
commit 035fa44523
3 files changed
+22 -58

No files matched your search

@@ -7,12 +7,15 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
import com.hippo.ehviewer.util.isAtLeastP
@Composable
fun ReaderGeneralSetting() = Column(modifier = Modifier.verticalScroll(rememberScrollState()).navigationBarsPadding()) {
@@ -39,11 +42,15 @@ fun ReaderGeneralSetting() = Column(modifier = Modifier.verticalScroll(rememberS
title = stringResource(id = R.string.pref_fullscreen),
field = fullscreen,
)
AnimatedVisibility(visible = fullscreen.value) {
SwitchChoice(
title = stringResource(id = R.string.pref_cutout_short),
field = Settings.cutoutShort.asMutableState(),
)
val view = LocalView.current
val hasDisplayCutout = remember(view) { isAtLeastP && view.rootWindowInsets.displayCutout != null }
if (hasDisplayCutout) {
AnimatedVisibility(visible = fullscreen.value) {
SwitchChoice(
title = stringResource(id = R.string.pref_cutout_short),
field = Settings.cutoutShort.asMutableState(),
)
}
}
SwitchChoice(
title = stringResource(id = R.string.pref_keep_screen_on),
@@ -10,16 +10,14 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.displayCutoutPadding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
@@ -222,10 +220,7 @@ fun SearchBarScreen(
Scaffold(
topBar = {
// Placeholder, fill immutable SearchBar padding
Spacer(
modifier = Modifier.statusBarsPadding().displayCutoutPadding()
.height(SearchBarDefaults.InputFieldHeight + 16.dp),
)
Spacer(modifier = Modifier.statusBarsPadding().height(SearchBarDefaults.InputFieldHeight + 16.dp))
},
floatingActionButton = floatingActionButton,
content = content,
@@ -296,8 +291,7 @@ fun SearchBarScreen(
filter?.invoke()
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = WindowInsets.navigationBars.union(WindowInsets.ime)
.only(WindowInsetsSides.Bottom).asPaddingValues(),
contentPadding = WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom).asPaddingValues(),
) {
// Workaround for prepending before the first item
item {}
@@ -25,7 +25,6 @@ import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
@@ -37,8 +36,6 @@ import android.webkit.MimeTypeMap
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
import androidx.activity.viewModels
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.layout.WindowInsets
@@ -90,7 +87,6 @@ import com.hippo.ehviewer.util.awaitActivityResult
import com.hippo.ehviewer.util.getParcelableCompat
import com.hippo.ehviewer.util.getParcelableExtraCompat
import com.hippo.ehviewer.util.getValue
import com.hippo.ehviewer.util.isAtLeastP
import com.hippo.ehviewer.util.isAtLeastQ
import com.hippo.ehviewer.util.lazyMut
import com.hippo.ehviewer.util.requestPermission
@@ -363,7 +359,7 @@ class ReaderActivity : EhActivity() {
viewer?.destroy()
viewer = ReadingModeType.toViewer(ReaderPreferences.defaultReadingMode().get(), this)
isRtl = viewer is R2LPagerViewer
updateViewerInsets(ReaderPreferences.fullscreen().get())
updateViewerInsets(ReaderPreferences.cutoutShort().get())
binding.viewerContainer.removeAllViews()
setOrientation(ReaderPreferences.defaultOrientationType().get())
binding.viewerContainer.addView(viewer?.getView())
@@ -524,10 +520,6 @@ class ReaderActivity : EhActivity() {
var viewer: BaseViewer? = null
private set
// We don't know if the device has cutout since the insets are not applied yet
@get:ChecksSdkIntAtLeast(Build.VERSION_CODES.P)
val hasCutout = isAtLeastP
private var config: ReaderConfig? = null
private val windowInsetsController by lazy {
@@ -671,18 +663,10 @@ class ReaderActivity : EhActivity() {
/**
* Updates viewer insets depending on fullscreen reader preferences.
*/
fun updateViewerInsets(fullscreen: Boolean) {
fun updateViewerInsets(drawInCutout: Boolean) {
viewer?.getViewForInsets()?.applyInsetter {
if (fullscreen) {
// https://github.com/chrisbanes/insetter/issues/120#issuecomment-1311808030
// Hack to remove insets
type(1 shl 31) {
padding()
}
} else {
type(navigationBars = true, statusBars = true) {
padding()
}
type(navigationBars = true, statusBars = true, displayCutout = !drawInCutout) {
padding()
}
}
}
@@ -751,16 +735,9 @@ class ReaderActivity : EhActivity() {
.onEach { setPageNumberVisibility(it) }
.launchIn(lifecycleScope)
if (hasCutout) {
setCutoutShort(ReaderPreferences.cutoutShort().get())
ReaderPreferences.cutoutShort().changes()
.drop(1)
.onEach {
setCutoutShort(it)
recreate()
}
.launchIn(lifecycleScope)
}
ReaderPreferences.cutoutShort().changes()
.onEach { updateViewerInsets(it) }
.launchIn(lifecycleScope)
ReaderPreferences.keepScreenOn().changes()
.onEach { setKeepScreenOn(it) }
@@ -781,12 +758,6 @@ class ReaderActivity : EhActivity() {
)
}
.launchIn(lifecycleScope)
ReaderPreferences.fullscreen().changes()
.onEach {
updateViewerInsets(it)
}
.launchIn(lifecycleScope)
}
/**
@@ -807,14 +778,6 @@ class ReaderActivity : EhActivity() {
binding.pageNumber.isVisible = visible
}
@RequiresApi(Build.VERSION_CODES.P)
private fun setCutoutShort(enabled: Boolean) {
window.attributes.layoutInDisplayCutoutMode = when (enabled) {
true -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
false -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
}
}
/**
* Sets the keep screen on mode according to [enabled].
*/