0
0
mirror of https://github.com/florisboard/florisboard.git synced 2024-09-19 19:42:20 +02:00

Remove systemuicontroller and switch to view apis (#2486)

This commit is contained in:
Lars Mühlbauer 2024-06-01 12:27:06 +02:00 committed by GitHub
parent 4c0c3f52e7
commit f116e20829
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 12 additions and 138 deletions

View File

@ -174,7 +174,6 @@ tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach
}
dependencies {
implementation(libs.accompanist.systemuicontroller)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.activity.ktx)
implementation(libs.androidx.autofill)

View File

@ -273,6 +273,7 @@ class FlorisImeService : LifecycleInputMethodService() {
override fun onCreate() {
super.onCreate()
FlorisImeServiceReference = WeakReference(this)
WindowCompat.setDecorFitsSystemWindows(window.window!!, false)
subtypeManager.activeSubtypeFlow.collectLatestIn(lifecycleScope) { subtype ->
val config = Configuration(resources.configuration)
config.setLocale(subtype.primaryLocale)

View File

@ -20,19 +20,13 @@ import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.inputmethodservice.InputMethodService
import android.view.View
import android.view.Window
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.google.accompanist.systemuicontroller.SystemUiController
import dev.patrickgold.florisboard.ime.theme.FlorisImeTheme
import dev.patrickgold.florisboard.ime.theme.FlorisImeUi
import dev.patrickgold.florisboard.lib.android.AndroidVersion
@ -41,143 +35,25 @@ import dev.patrickgold.florisboard.lib.snygg.ui.solidColor
@Composable
fun SystemUiIme() {
val systemUiController = rememberFlorisSystemUiController()
val useDarkIcons = !FlorisImeTheme.config.isNightTheme
val context = LocalContext.current
val view = LocalView.current
val backgroundColor = FlorisImeTheme.style.get(FlorisImeUi.SystemNavBar).background.solidColor(context)
val window = view.context.findWindow()!!
val windowInsetsController = WindowInsetsControllerCompat(window, view)
SideEffect {
systemUiController.setStatusBarColor(
color = backgroundColor,
darkIcons = useDarkIcons,
)
if (AndroidVersion.ATLEAST_API26_O) {
systemUiController.setNavigationBarColor(
color = backgroundColor,
darkIcons = useDarkIcons,
navigationBarContrastEnforced = true,
)
window.navigationBarColor = backgroundColor.toArgb()
windowInsetsController.isAppearanceLightNavigationBars = useDarkIcons
if (AndroidVersion.ATLEAST_API29_Q) window.isNavigationBarContrastEnforced = true
}
}
}
@Composable
private fun rememberFlorisSystemUiController(): SystemUiController {
val view = LocalView.current
return remember(view) { FlorisSystemUiController(view) }
}
/**
* Custom SystemUiController adapted so it works within an InputMethodService context as well.
*
* Original source:
* https://github.com/google/accompanist/blob/main/systemuicontroller/src/main/java/com/google/accompanist/systemuicontroller/SystemUiController.kt
*
* Changed:
* - findWindow() method recognizes input method service classes as well
* - Window insets controller is constructed directly, bypassing ViewCompat (as this ignores service classes as well)
* - API checks use FlorisBoard's [AndroidVersion] utils
*/
private class FlorisSystemUiController(
private val view: View,
) : SystemUiController {
private val window = view.context.findWindow()!!
private val windowInsetsController = WindowInsetsControllerCompat(window, view)
override var systemBarsBehavior: Int
get() = windowInsetsController.systemBarsBehavior
set(value) {
windowInsetsController.systemBarsBehavior = value
}
override fun setStatusBarColor(
color: Color,
darkIcons: Boolean,
transformColorForLightContent: (Color) -> Color
) {
statusBarDarkContentEnabled = darkIcons
window.statusBarColor = when {
darkIcons && !windowInsetsController.isAppearanceLightStatusBars -> {
// If we're set to use dark icons, but our windowInsetsController call didn't
// succeed (usually due to API level), we instead transform the color to maintain
// contrast
transformColorForLightContent(color)
}
else -> color
}.toArgb()
}
override fun setNavigationBarColor(
color: Color,
darkIcons: Boolean,
navigationBarContrastEnforced: Boolean,
transformColorForLightContent: (Color) -> Color
) {
navigationBarDarkContentEnabled = darkIcons
isNavigationBarContrastEnforced = navigationBarContrastEnforced
window.navigationBarColor = when {
darkIcons && !windowInsetsController.isAppearanceLightNavigationBars -> {
// If we're set to use dark icons, but our windowInsetsController call didn't
// succeed (usually due to API level), we instead transform the color to maintain
// contrast
transformColorForLightContent(color)
}
else -> color
}.toArgb()
}
override var isStatusBarVisible: Boolean
get() {
return ViewCompat.getRootWindowInsets(view)
?.isVisible(WindowInsetsCompat.Type.statusBars()) == true
}
set(value) {
if (value) {
windowInsetsController.show(WindowInsetsCompat.Type.statusBars())
} else {
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
}
}
override var isNavigationBarVisible: Boolean
get() {
return ViewCompat.getRootWindowInsets(view)
?.isVisible(WindowInsetsCompat.Type.navigationBars()) == true
}
set(value) {
if (value) {
windowInsetsController.show(WindowInsetsCompat.Type.navigationBars())
} else {
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
}
}
override var statusBarDarkContentEnabled: Boolean
get() = windowInsetsController.isAppearanceLightStatusBars
set(value) {
windowInsetsController.isAppearanceLightStatusBars = value
}
override var navigationBarDarkContentEnabled: Boolean
get() = windowInsetsController.isAppearanceLightNavigationBars
set(value) {
windowInsetsController.isAppearanceLightNavigationBars = value
}
override var isNavigationBarContrastEnforced: Boolean
get() = AndroidVersion.ATLEAST_API29_Q && window.isNavigationBarContrastEnforced
set(value) {
if (AndroidVersion.ATLEAST_API29_Q) {
window.isNavigationBarContrastEnforced = value
}
}
private tailrec fun Context.findWindow(): Window? {
val context = this
if (context is Activity) return context.window
if (context is InputMethodService) return context.window?.window
return if (context is ContextWrapper) context.findWindow() else null
}
tailrec fun Context.findWindow(): Window? {
val context = this
if (context is Activity) return context.window
if (context is InputMethodService) return context.window?.window
return if (context is ContextWrapper) context.findWindow() else null
}

View File

@ -1,6 +1,5 @@
[versions]
# Main
accompanist = "0.34.0"
android-gradle-plugin = "8.3.1"
androidx-activity = "1.8.2"
androidx-autofill = "1.1.0"
@ -38,7 +37,6 @@ kotest-extensions-roboelectric = "0.5.0"
[libraries]
# Main
accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "androidx-activity" }
androidx-autofill = { module = "androidx.autofill:autofill", version.ref = "androidx-autofill" }