diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d430044..d148e714 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Pressing enter in app drawer launches the first app in search results ([#331]) +### Fixed +- Prevent duplicated widget rendering on the home screen ([#320]) + ## [1.9.0] - 2026-02-02 ### Added - Option to hide app labels ([#55]) diff --git a/app/src/main/kotlin/org/fossify/home/activities/MainActivity.kt b/app/src/main/kotlin/org/fossify/home/activities/MainActivity.kt index 98c8f6db..b79de779 100644 --- a/app/src/main/kotlin/org/fossify/home/activities/MainActivity.kt +++ b/app/src/main/kotlin/org/fossify/home/activities/MainActivity.kt @@ -132,6 +132,9 @@ class MainActivity : SimpleActivity(), FlingListener { private const val ANIMATION_DURATION = 150L private const val APP_DRAWER_CLOSE_DELAY = 300L private const val APP_DRAWER_STATE = "app_drawer_state" + // TODO: remove before PR merge, but needed to be able to reproduce bug of issue-320 + private const val ACTION_DEBUG_FORCE_WIDGET_FIRST_DRAW = + "org.fossify.home.action.DEBUG_FORCE_WIDGET_FIRST_DRAW" } override fun onCreate(savedInstanceState: Bundle?) { @@ -500,6 +503,13 @@ class MainActivity : SimpleActivity(), FlingListener { } private fun handleIntentAction(intent: Intent) { + // TODO: remove before PR merge, but needed to be able to reproduce bug of issue-320 + if (BuildConfig.DEBUG && intent.action == ACTION_DEBUG_FORCE_WIDGET_FIRST_DRAW) { + binding.homeScreenGrid.root.debugForceWidgetFirstDraw() + toast("Debug: forced widget first draw") + return + } + if (intent.action == LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT) { val launcherApps = applicationContext.getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps diff --git a/app/src/main/kotlin/org/fossify/home/views/HomeScreenGrid.kt b/app/src/main/kotlin/org/fossify/home/views/HomeScreenGrid.kt index 6fcf9a40..2010cd36 100644 --- a/app/src/main/kotlin/org/fossify/home/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/org/fossify/home/views/HomeScreenGrid.kt @@ -260,6 +260,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : } } + // TODO: remove before PR merge, but needed to be able to reproduce bug of issue-320 + fun debugForceWidgetFirstDraw() { + isFirstDraw = true + redrawGrid() + } + fun resizeGrid(newRowCount: Int, newColumnCount: Int) { if (columnCount != newColumnCount || rowCount != newRowCount) { rowCount = newRowCount @@ -1130,6 +1136,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : appWidgetProviderInfo: AppWidgetProviderInfo, item: HomeScreenGridItem, ) { + if (reuseExistingWidgetViewIfPresent(item)) { + return + } + // we have to pass the base context here, else there will be errors with the themes val widgetView = appWidgetHost.createView( (context as MainActivity).baseContext, @@ -1194,6 +1204,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : return Size(widgetWidth, widgetHeight) } + private fun reuseExistingWidgetViewIfPresent(item: HomeScreenGridItem): Boolean { + val existingWidgetView = widgetViews.firstOrNull { it.tag == item.widgetId } ?: return false + updateWidgetPositionAndSize(existingWidgetView, item) + return true + } + private fun calculateWidgetPos(topLeft: Point): Point { val cell = cells[topLeft]!! return Point( @@ -1293,6 +1309,10 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : gridItems .filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() } .forEach { item -> + if (reuseExistingWidgetViewIfPresent(item)) { + return@forEach + } + val providerInfo = item.providerInfo ?: appWidgetManager!!.installedProviders .firstOrNull { it.provider.className == item.className } @@ -2470,4 +2490,3 @@ private class AnimatedGridPager( } } } -