fix: compute status bar color based on wallpaper color (#344)

* fix: compute status bar color based on wallpaper color

* docs: update changelog

* fix: check fragment status after animation ends

* fix: handle some edge cases

* build: update jitpack url

Refs: https://github.com/FossifyOrg/Launcher/issues/278
This commit is contained in:
Naveen Singh
2026-01-30 16:08:57 +05:30
committed by GitHub
parent 134550ad2d
commit bb4bdcbda4
4 changed files with 97 additions and 9 deletions

View File

@@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support for custom fonts
### Fixed
- Fixed invisible status bar icons on home screen ([#278])
## [1.7.0] - 2025-12-16
### Changed
- Updated translations
@@ -108,6 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#230]: https://github.com/FossifyOrg/Launcher/issues/230
[#234]: https://github.com/FossifyOrg/Launcher/issues/234
[#277]: https://github.com/FossifyOrg/Launcher/issues/277
[#278]: https://github.com/FossifyOrg/Launcher/issues/278
[#282]: https://github.com/FossifyOrg/Launcher/issues/282
[Unreleased]: https://github.com/FossifyOrg/Launcher/compare/1.7.0...HEAD

View File

@@ -2,6 +2,8 @@ package org.fossify.home.activities
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.WallpaperManager
import android.app.WallpaperManager.OnColorsChangedListener
import android.app.admin.DevicePolicyManager
import android.app.role.RoleManager
import android.appwidget.AppWidgetHost
@@ -37,7 +39,6 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable
import androidx.core.net.toUri
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.WindowCompat
import androidx.core.view.isVisible
import androidx.core.view.iterator
import androidx.viewbinding.ViewBinding
@@ -47,6 +48,7 @@ import org.fossify.commons.extensions.beVisible
import org.fossify.commons.extensions.getContrastColor
import org.fossify.commons.extensions.getPopupMenuTheme
import org.fossify.commons.extensions.getProperBackgroundColor
import org.fossify.commons.extensions.insetsController
import org.fossify.commons.extensions.isPackageInstalled
import org.fossify.commons.extensions.onGlobalLayout
import org.fossify.commons.extensions.performHapticFeedback
@@ -57,6 +59,7 @@ import org.fossify.commons.extensions.toast
import org.fossify.commons.extensions.viewBinding
import org.fossify.commons.helpers.DARK_GREY
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.helpers.isOreoMr1Plus
import org.fossify.commons.helpers.isQPlus
import org.fossify.home.BuildConfig
import org.fossify.home.R
@@ -75,6 +78,7 @@ import org.fossify.home.extensions.launchApp
import org.fossify.home.extensions.launchAppInfo
import org.fossify.home.extensions.launchersDB
import org.fossify.home.extensions.roleManager
import org.fossify.home.extensions.supportsDarkText
import org.fossify.home.extensions.uninstallApp
import org.fossify.home.fragments.MyFragment
import org.fossify.home.helpers.ITEM_TYPE_FOLDER
@@ -117,6 +121,9 @@ class MainActivity : SimpleActivity(), FlingListener {
((shortcutId: String, label: String, icon: Drawable) -> Unit)? = null
private var wasJustPaused: Boolean = false
private var wallpaperColorChangeListener: OnColorsChangedListener? = null
private var wallpaperSupportsDarkText: Boolean? = null
private lateinit var mDetector: GestureDetectorCompat
private val binding by viewBinding(ActivityMainBinding::inflate)
@@ -173,6 +180,40 @@ class MainActivity : SimpleActivity(), FlingListener {
if (!isDefaultLauncher()) {
requestHomeRole()
}
setupWallpaperColorListener()
}
private fun setupWallpaperColorListener() {
if (isOreoMr1Plus()) {
val wallpaperManager = WallpaperManager.getInstance(this)
wallpaperColorChangeListener = OnColorsChangedListener { colors, which ->
if (which and WallpaperManager.FLAG_SYSTEM != 0) {
wallpaperSupportsDarkText = colors?.supportsDarkText() ?: run {
refreshWallpaperSupportsDarkText()
wallpaperSupportsDarkText
}
if (!isAllAppsFragmentExpanded() && !isWidgetsFragmentExpanded()) {
runOnUiThread {
updateStatusBarIcons()
}
}
}
}
wallpaperManager.addOnColorsChangedListener(
wallpaperColorChangeListener!!,
Handler(Looper.getMainLooper())
)
refreshWallpaperSupportsDarkText()
}
}
private fun refreshWallpaperSupportsDarkText() {
if (!isOreoMr1Plus()) return
wallpaperSupportsDarkText = WallpaperManager.getInstance(this)
.getWallpaperColors(WallpaperManager.FLAG_SYSTEM)
?.supportsDarkText()
}
override fun onNewIntent(intent: Intent) {
@@ -209,6 +250,14 @@ class MainActivity : SimpleActivity(), FlingListener {
override fun onResume() {
super.onResume()
wasJustPaused = false
refreshWallpaperSupportsDarkText()
Handler(Looper.getMainLooper()).postDelayed({
if (isAllAppsFragmentExpanded() || isWidgetsFragmentExpanded()) {
updateStatusBarIcons(getProperBackgroundColor())
} else {
updateStatusBarIcons()
}
}, ANIMATION_DURATION)
with(binding.mainHolder) {
onGlobalLayout {
@@ -257,6 +306,14 @@ class MainActivity : SimpleActivity(), FlingListener {
wasJustPaused = false
}
override fun onDestroy() {
super.onDestroy()
if (isOreoMr1Plus() && wallpaperColorChangeListener != null) {
WallpaperManager.getInstance(this)
.removeOnColorsChangedListener(wallpaperColorChangeListener!!)
}
}
override fun onPause() {
super.onPause()
wasJustPaused = true
@@ -598,7 +655,7 @@ class MainActivity : SimpleActivity(), FlingListener {
}
Handler(Looper.getMainLooper()).postDelayed({
updateStatusBarIcons()
updateStatusBarIcons(getProperBackgroundColor())
}, animationDuration)
}
@@ -611,7 +668,7 @@ class MainActivity : SimpleActivity(), FlingListener {
window.navigationBarColor = Color.TRANSPARENT
binding.homeScreenGrid.root.fragmentCollapsed()
updateStatusBarIcons(Color.TRANSPARENT)
updateStatusBarIcons()
Handler(Looper.getMainLooper()).postDelayed({
if (fragment is AllAppsFragmentBinding) {
fragment.allAppsGrid.scrollToPosition(0)
@@ -676,7 +733,7 @@ class MainActivity : SimpleActivity(), FlingListener {
binding.allAppsFragment.allAppsGrid.scrollToPosition(0)
binding.allAppsFragment.root.touchDownY = -1
binding.homeScreenGrid.root.fragmentCollapsed()
updateStatusBarIcons(Color.TRANSPARENT)
updateStatusBarIcons()
}
if (delayed) {
Handler(Looper.getMainLooper()).postDelayed(close, APP_DRAWER_CLOSE_DELAY)
@@ -693,7 +750,7 @@ class MainActivity : SimpleActivity(), FlingListener {
binding.widgetsFragment.widgetsList.scrollToPosition(0)
binding.widgetsFragment.root.touchDownY = -1
binding.homeScreenGrid.root.fragmentCollapsed()
updateStatusBarIcons(Color.TRANSPARENT)
updateStatusBarIcons()
}
if (delayed) {
Handler(Looper.getMainLooper()).postDelayed(close, APP_DRAWER_CLOSE_DELAY)
@@ -1263,9 +1320,19 @@ class MainActivity : SimpleActivity(), FlingListener {
}
}
private fun updateStatusBarIcons(backgroundColor: Int = getProperBackgroundColor()) {
WindowCompat.getInsetsController(window, binding.root).isAppearanceLightStatusBars =
backgroundColor.getContrastColor() == DARK_GREY
private fun updateStatusBarIcons(backgroundColor: Int? = null) {
val isLightBackground = when {
backgroundColor != null -> backgroundColor.getContrastColor() == DARK_GREY
wallpaperSupportsDarkText != null -> wallpaperSupportsDarkText!!
else -> {
refreshWallpaperSupportsDarkText()
wallpaperSupportsDarkText ?: false
}
}
window.insetsController().apply {
isAppearanceLightStatusBars = isLightBackground
isAppearanceLightNavigationBars = isLightBackground
}
}
// taken from https://gist.github.com/maxjvh/a6ab15cbba9c82a5065d

View File

@@ -0,0 +1,17 @@
package org.fossify.home.extensions
import android.app.WallpaperColors
import android.os.Build
import androidx.annotation.RequiresApi
import org.fossify.commons.extensions.getContrastColor
import org.fossify.commons.helpers.DARK_GREY
import org.fossify.commons.helpers.isSPlus
@RequiresApi(Build.VERSION_CODES.O_MR1)
fun WallpaperColors.supportsDarkText(): Boolean {
return if (isSPlus()) {
(colorHints and WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0
} else {
primaryColor.toArgb().getContrastColor() == DARK_GREY
}
}

View File

@@ -10,7 +10,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { setUrl("https://jitpack.io") }
maven { setUrl("https://www.jitpack.io") }
mavenLocal()
}
}