You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
v1.8.172 shipped seven selectable glide-trail themes. Five are time-driven
(RAINBOW, FIRE, AURORA, GALAXY, NEON) — colour is computed against the
current timeMillis as the finger draws. RAINBOW and NEON carry enough
high-frequency hue/brightness modulation to be relevant for users with
photosensitive epilepsy.
The reduced-motion gate already shipped in v1.8.172 — TextKeyboardLayout.kt
lines 177-178 read Settings.Global.ANIMATOR_DURATION_SCALE and set
`glideShowTrail = glideShowTrailPref && !reducedMotion`. When the user has
Developer Options -> "Animator duration scale" -> Animations off (or sets
the per-app Android-14+ motion preference where supported), the trail does
not draw at all regardless of theme. So users with photosensitivity
concerns have a single system-level switch that fully removes the trail
surface; they do not need to navigate Settings -> Gestures to pick a
less-animated theme.
This release makes that disclosure canonical and discoverable.
docs/ACCESSIBILITY.md adds a new "Glide trail themes and photosensitivity"
section with:
- Per-theme animation-rate table (hue°/ms and rad/ms) so an accessibility
reviewer can reason about the surface without reading Kotlin source:
ACCENT/ICE = 0 (no time-driven effect)
RAINBOW = 0.2 hue°/ms (~3 Hz at typical gesture lengths)
AURORA = 0.06 hue°/ms (slow shimmer)
FIRE = 0.003 rad/ms (~0.5 Hz visible flicker, hot tail only)
GALAXY = 0.0004 rad/ms (sub-Hz drift)
NEON = 0.015 rad/ms (~2.4 Hz pulse, whole-trail brightness)
- WCAG 2.3 / 2.3.2 framing (3 flashes/sec of red-saturated content over
>25% of central visual field). SwiftFloris's stroke is ~110% of a key
radius — well under the 25% visual-field cap.
- The reduced-motion guarantee citing the specific file and lines so the
gate is auditable. The Snygg engine's parallel motion gate for
KeyPopupElement accent rings and smartbar transitions is mentioned for
completeness.
- User-facing guidance: Developer Options -> "Animator duration scale" ->
Animations off is the kill-switch.
- Follow-up note: a Settings -> Gestures inline ⓘ tooltip would be useful
polish; tracked as Workstream 10 follow-up rather than blocking the
disclosure.
Out of scope (separate slice): Compose tooltip / ⓘ icon next to each
animated theme in the picker. Adding it would require new Compose UI
(TooltipBox) and Crowdin'd strings.xml entries. The doc-side disclosure
is sufficient for the per-PR-scope-discipline rule (AGENTS.md hard rule #6)
and the system-level kill-switch already handles the load-bearing case.
Closes RESEARCH_FEATURE_PLAN.md EI4.
Verification:
- grep -n "ANIMATOR_DURATION_SCALE" TextKeyboardLayout.kt -> gate at lines
172 + 177; the !reducedMotion guard pre-dates this disclosure
- bash scripts/check-fastlane-metadata.sh -> OK (versionCode 1982)
- bash scripts/check-repo-hygiene.sh -> OK
- Doc-only slice; no code changes; gradle gates deferred to maintainer host
v1.8.172 shipped seven selectable glide-trail themes (Accent, Rainbow, Fire, Ice, Aurora, Galaxy, Neon). Five of them are time-driven — their per-segment colour is computed against the current `timeMillis`, so the trail animates as the finger draws it. `RAINBOW`, `NEON`, and `FIRE` carry enough high-frequency colour or brightness modulation to be relevant for users with photosensitive epilepsy. WCAG 2.3 / 2.3.2 sets the floor at three flashes per second of red-saturated content over more than 25% of the central visual field; SwiftFloris's trail is well under the 25%-visual-field cap (thin stroke at most ~110% of a key radius), but the maintainer cannot audit every user's hardware and ambient conditions, so the disclosure is worth making explicit.
13
+
14
+
The reduced-motion gate already shipped in v1.8.172 — `TextKeyboardLayout.kt:177-178` reads `Settings.Global.ANIMATOR_DURATION_SCALE` once per recomposition and computes `val glideShowTrail = glideShowTrailPref && !reducedMotion`. When `ANIMATOR_DURATION_SCALE == 0f` (Developer Options → "Animator duration scale" → Animations off), the trail does not draw at all, regardless of which theme is selected. So users with photosensitivity concerns have a single system-level switch that fully removes the trail surface; they do not need to navigate into Settings → Gestures to pick a less-animated theme.
15
+
16
+
This release documents both facts in `docs/ACCESSIBILITY.md` so the disclosure is canonical and discoverable.
17
+
18
+
### Changes
19
+
20
+
- **`docs/ACCESSIBILITY.md`** — new section "Glide trail themes and photosensitivity" between the Android 16 migration content and the existing "Other a11y contracts" section. Covers:
21
+
- A table of per-theme animation rates (hue°/ms or rad/ms) so an accessibility reviewer can reason about the surface without reading the Kotlin source:
22
+
- `ACCENT` / `ICE`: 0 (no time-driven effect)
23
+
- `RAINBOW`: 0.2 hue°/ms (~3 Hz at typical gesture lengths)
24
+
- `AURORA`: 0.06 hue°/ms (slow shimmer)
25
+
- `FIRE`: 0.003 rad/ms (~0.5 Hz visible flicker on the hot tail only)
26
+
- `GALAXY`: 0.0004 rad/ms (sub-Hz drift)
27
+
- `NEON`: 0.015 rad/ms (~2.4 Hz pulse across the whole trail)
28
+
- The WCAG 2.3.2 framing (three flashes per second of red-saturated content over 25% of the visual field) plus the visual-field bound that SwiftFloris's stroke comfortably stays under.
29
+
- The reduced-motion guarantee, citing the specific file and lines (`TextKeyboardLayout.kt:177-178`) so the gate is auditable. The Snygg engine's parallel reduced-motion gate for `KeyPopupElement` accent rings and smartbar transitions is mentioned for completeness — the glide trail inherits the same contract.
30
+
- User-facing recommendation: turn on Developer Options → "Animator duration scale" → Animations off (or the Android-14+ per-app motion preference where available).
31
+
- Follow-up tracker: a future Settings → Gestures → "Trail theme" picker could grow a small "ⓘ" tooltip beside `RAINBOW`/`AURORA`/`NEON`/`FIRE`/`GALAXY` noting the animation rate. Tracked as a Workstream 10 polish slice; this doc serves as the canonical reference until the tooltip lands.
32
+
33
+
### What is intentionally not done in this slice
34
+
35
+
- **Settings → Gestures inline tooltip / ⓘ icon.** Adding per-theme tooltips would require new Compose UI (a `Popup` or `TooltipBox`) and additional `strings.xml` entries that Crowdin would need to translate. Doc-only disclosure is sufficient for the per-PR-scope-discipline (`AGENTS.md` hard rule #6), and the existing reduced-motion gate already handles the load-bearing case (photosensitivity-concerned users have a system-level kill-switch).
36
+
- **Code change to gate animations per-theme.** The whole trail rendering path is already gated off; per-theme animation gating would be wasted complexity.
37
+
38
+
### Verification
39
+
40
+
- `grep -n "ANIMATOR_DURATION_SCALE" app/src/main/kotlin/dev/patrickgold/florisboard/ime/text/keyboard/TextKeyboardLayout.kt` returns the gate at lines 172 + 177 (Verified).
41
+
- `bash scripts/check-repo-hygiene.sh` → OK.
42
+
- `bash scripts/check-fastlane-metadata.sh` → OK (versionCode 1982).
43
+
- Doc-only slice; gradle gates deferred to maintainer host per `CLAUDE.md`.
**SwiftFloris** is a privacy-first Android keyboard, forked from FlorisBoard and pushed toward SwiftKey-class multilingual typing without the cloud. It ships under Apache-2.0, holds no `INTERNET` permission, and binds zero accounts.
v1.8.182 — accessibility: photosensitivity disclosure for glide-trail themes.
2
+
3
+
docs/ACCESSIBILITY.md now documents the animation rates of the v1.8.172 glide-trail themes (RAINBOW, AURORA, NEON, FIRE, GALAXY) and re-affirms the reduced-motion guarantee: ANIMATOR_DURATION_SCALE = 0 disables the trail entirely. Recommends Developer Options "Animations off" for photosensitive users.
4
+
5
+
No code changes; the reduced-motion gate was already wired since v1.8.172.
0 commit comments