Seven fixes: double tap, the dock over Today View, icons after a theme change, the wallpaper smear, the Preview bar, a way back in Settings, and a cheaper background - #81
Conversation
Each empty cell takes its own taps, and since More rows made those cells cover most of a page, a double tap on empty space never reached the page's Double Tap action. Empty cells run it themselves now. Only empty cells outside jiggle mode, so a tap on an app or folder isn't held back waiting for a second one.
Unfolded and upright, the dock bar sat over Today View's widgets and Edit button. Like iPhone, it now fades and slides away as you swipe to Today View, following the swipe inside the layer so nothing recomposes, and leaves once you're there so it can't take Today's taps. It comes back on Home. Today View's search field also reads its label in your language.
Folio kept an app's icon until its package, the screen density, language or dark mode changed. A theme like Good Lock's Theme Park swaps icons without any of those, so the old icons stayed. The icon cache now also follows Android's count of theme and overlay changes, which folding and rotating don't touch, and Icons & Side Bar has Refresh Icons for anything that still slips through (in English and Chinese).
Unfolded and upright, Settings shows its list beside the page only when there's room. Without it, a top-level page had just the sidebar button, which doesn't read as a way back. It now shows the sidebar button and "‹ Folio" together. With the list on screen, or in three columns, there is still only Done.
#35) Switching Background to Android wallpaper rebuilt the screen with recreate(), which keeps the old window. When that window had first been made opaque (Folio's own background, the default), it stayed opaque to the screen even after asking for the wallpaper: the wallpaper never showed, and each frame of a swipe was drawn over the last, leaving copies of pages and icons behind. A fresh start of the app always looked right, which is why it came and went. The switch now starts the screen again with a new window, saving the choice on its own first so the new window is built from it. Folio also draws its own background whenever the window isn't really showing the wallpaper, so the worst case is the dunes, never a smear, and rebuilds the window once if the two ever disagree. The setup step that keeps your wallpaper takes the same path. Reproduced on a Fold8 every time (fresh install, switch, swipe) and gone after this change.
Before Folio is the Home app, the Preview bar sits above the page dots, and the space kept for them was a guess (88dp). Unfolded and sideways, the bar is taller than that and sat over the bottom of the App Library's panel. The controls are measured now, and Home, the App Library and the dock keep clear of them with a small gap. As the Home app nothing moves: the space stays 44dp unless the dots are taller, so no one's automatic rows shrink.
Folio's dunes never move, but during a swipe everything above them does, so Android redrew the whole background every frame: a full-screen gradient, three dunes and 29 anti-aliased strokes. It's drawn once into its own layer now and reused, one texture copy a frame. Measured on a Fold8 (unfolded, 120 Hz, 20 swipes, twice each): GPU time per frame median 7.0 to 4.6-4.9 ms, 90th percentile 9.7 to 6.9-7.5 ms.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8cb8344572
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| init { launcherApps.registerCallback(callback); refresh(); FolioSettingsBridge.liveModel = java.lang.ref.WeakReference(this) } | ||
|
|
||
| /** Settings › Refresh Icons: for a theme app that changes icons without telling launchers (#19). */ | ||
| fun reloadIcons() { iconsStale = true; IconPacks.clear(); refresh() } |
There was a problem hiding this comment.
Invalidate composed icon-pack results on refresh
When an icon pack is active, this clears IconPacks and reloads each AppEntry, but AppIcon retains its already-produced PackLookup because that state is keyed only by look.pack and app.id; both remain unchanged. Consequently, tapping the new Refresh Icons action continues drawing the old pack bitmap until the composable is recreated or the pack selection changes. Clear-style glyphs have the same problem and are not cleared at all. Include an observable icon revision in those producer keys and clear the related derived caches.
Useful? React with 👍 / 👎.
| getSharedPreferences(SettingKeys.PREFS, 0).edit { putBoolean(SettingKeys.SYSTEM_WALLPAPER, system) } | ||
| if (system && !showsWallpaper) { startAgain(); return } |
There was a problem hiding this comment.
Preserve an unsaved wallpaper choice across restart
If the user selects Android wallpaper while the initial app refresh/migration is still running, LauncherModel.setSystemWallpaper(true) cannot persist the JSON state because persist() returns while needsMigration is true. This restart then destroys that model; the replacement model decodes systemWallpaper=false from the unchanged JSON, so DuneWallpaper covers the newly themed window and the next refresh writes false back over this standalone preference. The separately saved value must also seed the replacement LauncherState, or the restart must wait until the state itself is durable.
Useful? React with 👍 / 👎.
| startActivity(android.content.Intent(intent).addFlags( | ||
| android.content.Intent.FLAG_ACTIVITY_NEW_TASK or android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK)) |
There was a problem hiding this comment.
Carry the Settings destination into the new task
When Android wallpaper is enabled from Settings opened through Home's in-app Customize path, the activity's intent is still the ordinary HOME intent; the open sheet and customizationPage exist only in Compose state. Starting that cloned intent with CLEAR_TASK destroys those values, and the replacement activity lands on Home rather than reopening Settings as the comment claims. Preserve the Settings destination/page in the replacement intent or another durable state before clearing the task.
Useful? React with 👍 / 👎.
What this changes
Seven fixes for problems people reported or hit on the Fold8, no new features.
those cells cover most of a page, so the page's Double Tap action never saw the second tap. Empty cells run it
themselves now, only outside jiggle mode, so a tap on an app or folder isn't held back waiting for a second one.
iPhone, it now fades and slides away as you swipe there and leaves, so it can't take Today's taps, and comes back on
Home. It follows the swipe inside
graphicsLayer, so nothing recomposes (PRF-7).dark mode changed, and Good Lock's Theme Park changes none of those. The icon cache now also follows Android's count
of theme and overlay changes (which folding and rotating don't touch), and Icons & Side Bar has Refresh Icons
for anything that still slips through (English and Chinese).
recreate(), which keeps the old window; a window first made opaque stayed opaque to the compositor, so thewallpaper never showed and every frame of a swipe drew over the last. The switch starts the screen again with a new
window, saving the choice first, and Folio draws its own background whenever the window isn't really showing the
wallpaper.
bar was a guessed 88dp; unfolded sideways the bar is taller and sat on the panel. The controls are measured now. As
the Home app nothing moves: it stays 44dp unless the dots are taller, so no one's automatic rows shrink.
only the sidebar button, which doesn't read as a way back. It now shows the sidebar button and "‹ Folio" together;
with the list on screen, or in three columns, there is still only Done.
swipe everything above them does, so Android redrew the whole background every frame (a gradient, three dunes and 29
anti-aliased strokes). It's drawn once into its own layer now. Measured on a Fold8, unfolded, 120 Hz,
fastbuild,20 swipes twice each: GPU per frame median 7.0 → 4.6–4.9 ms, p90 9.7 → 6.9–7.5 ms.
How I checked it
Galaxy Z Fold8, Android 17, on a side-by-side build (
com.mccal.folio.fix067), never over the daily Folio:Inner screen upright and sideways, and the cover screen: double tap on empty space, the dock leaving and returning
on Today View, Refresh Icons, "‹ Folio", and the App Library clear of the Preview bar.
fold 7 issue #12/UI issues and apps Ghosting and overlapping. #35 reproduced every time before the fix (fresh install, switch Background to Android wallpaper, swipe) and gone
after it, twice.
Frame numbers from
dumpsys gfxinfo framestatson thefastbuild, and a Perfetto trace for the background work.Regression tests:
IconRefreshTestcovers the theme-change detection (App icons don't update if the "default" icons are changed by the system #19). The other six are UI and windowbehaviour checked by hand on the phone; they don't have regression tests yet (TST-2).
./gradlew :app:testDebugUnitTest :app:lintDebugpasses (639 tests, lint 0 errors, merged with current main)Screenshots don't show personal info
No new themes in
themes/No GPL code and nothing that needs root
Follows the Folio Standards; rule IDs it touches: ADP-10, INT-4, PRF-1, PRF-2, PRF-7, TST-2
An AI agent helped
Notes for the maintainer
pull request per fix.
scopes to contributions from outside the maintainer, and his standing rule is no AI attribution in his repositories.
Flagging it so the two can be reconciled rather than silently ignored.