From 035fa445234fbbe0e65936216eb74cdc9124098d Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Mon, 6 May 2024 14:34:22 +0800 Subject: [PATCH] Correctly handle display cutout (#1139) --- .../ui/reader/ReaderGeneralSetting.kt | 17 +++++-- .../ehviewer/ui/screen/SearchBarScreen.kt | 12 ++--- .../tachiyomi/ui/reader/ReaderActivity.kt | 51 +++---------------- 3 files changed, 22 insertions(+), 58 deletions(-) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderGeneralSetting.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderGeneralSetting.kt index d7f79d36c..8d40eed2d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderGeneralSetting.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/ReaderGeneralSetting.kt @@ -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), diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt index 2e51db37e..f4515ee7a 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/SearchBarScreen.kt @@ -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 {} diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 95aa28349..999033b55 100644 --- a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -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]. */