fix: multiple UI and functionality fixes#1971
Conversation
- Preserve user preferences when following system night mode - Fix key label centering and add line break support for symbol and hint - Add exception handling in user dictionary management - Fix errors in OpenCCDataPlugin - Make AutoScaleTextView respect gravity setting for better visual centering - Preedit no longer occupies full width, allowing clicks below blank area - Fix slide_xxx keys becoming unclickable when swipe distance is disabled in settings
There was a problem hiding this comment.
Pull request overview
This PR addresses a set of UI/layout and functional regressions across the keyboard UI, theme color-scheme selection, user dictionary import/export, and the OpenCC dictionary generation build logic (Fixes #1961).
Changes:
- Ensure OpenCC derived dictionaries are actually generated during Gradle builds by resolving
providers.exec()results. - Improve key label/symbol rendering (better vertical centering, newline support for symbol/hint) and gesture handling when swipe distance is disabled.
- Adjust preedit layout sizing/positioning, AutoScaleTextView alignment behavior, and add more defensive handling in user dictionary export/restore flows.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| build-logic/convention/src/main/kotlin/OpenCCDataPlugin.kt | Forces lazy providers.exec() to execute so generated OpenCC dictionaries are bundled. |
| app/src/main/java/com/osfans/trime/ime/keyboard/KeyView.kt | Adjusts label centering math; adds multiline rendering for symbol/hint text. |
| app/src/main/java/com/osfans/trime/ime/keyboard/GestureFrame.kt | Prevents swipe/slide activation when swipe travel is configured as disabled (0). |
| app/src/main/java/com/osfans/trime/ime/core/InputView.kt | Makes preedit view wrap content and anchors it to start to avoid full-width touch blocking. |
| app/src/main/java/com/osfans/trime/ime/core/AutoScaleTextView.kt | Recomputes transforms on size changes and refactors horizontal translation to respect gravity more consistently. |
| app/src/main/java/com/osfans/trime/data/userdict/UserDictManager.kt | Adds additional exception handling and avoids copying/deleting temp files when export fails. |
| app/src/main/java/com/osfans/trime/data/theme/ColorManager.kt | Enhances scheme selection when following system day/night to better preserve user-selected scheme relationships. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| val lines = text.split("\n") | ||
| val fontMetrics = symbolPaint.fontMetrics | ||
| val lineHeight = fontMetrics.descent - fontMetrics.ascent | ||
| val totalHeight = lineHeight * lines.size | ||
|
|
There was a problem hiding this comment.
drawSymbol() now always does text.split("\n") on every onDraw, which allocates a List<String> (and substrings) per key per frame. Since most symbols/hints are likely single-line, consider a fast-path for texts without \n (keep the old single drawText call) and only split/loop when a line break is actually present, or cache the split result per key/text to avoid per-frame allocations.
| val scaledTextWidth = textWidth * scaleX | ||
| val startX = if (shouldAlignLeft) { | ||
| paddingLeft.toFloat() | ||
| } else { | ||
| paddingLeft.toFloat() + (contentWidth - scaledTextWidth) / 2.0f | ||
| } | ||
| return (startX - textBounds.left) / scaleX | ||
| } |
There was a problem hiding this comment.
calculateTranslateX() divides by scaleX, but scaleX can become 0 (e.g., when contentWidth == 0 in Horizontal/Proportional mode). That would produce Infinity/NaN for translateX and can break drawing. Add a guard for scaleX == 0f (and potentially contentWidth <= 0) to return a safe translation, or clamp scaleX to a small positive value before dividing.
| colorScheme(if (isNightMode) darkSchemeId else lightSchemeId) | ||
| lightSchemeId != null -> | ||
| // 如果只指定了light_scheme,说明是暗色方案 | ||
| if (isNightMode) userScheme else colorScheme(lightSchemeId) | ||
| darkSchemeId != null -> | ||
| // 如果只指定了dark_scheme,说明是亮色方案 | ||
| if (isNightMode) colorScheme(darkSchemeId) else userScheme |
There was a problem hiding this comment.
In followSystemDayNight mode, several branches return colorScheme(...) directly. If light_scheme/dark_scheme points to a non-existent scheme id, colorScheme(...) returns null and the final fallback becomes default/first scheme, potentially overriding the user's selected scheme unexpectedly. Consider falling back to userScheme or defaultModeScheme when the referenced scheme can't be resolved (e.g., colorScheme(id) ?: userScheme).
| colorScheme(if (isNightMode) darkSchemeId else lightSchemeId) | |
| lightSchemeId != null -> | |
| // 如果只指定了light_scheme,说明是暗色方案 | |
| if (isNightMode) userScheme else colorScheme(lightSchemeId) | |
| darkSchemeId != null -> | |
| // 如果只指定了dark_scheme,说明是亮色方案 | |
| if (isNightMode) colorScheme(darkSchemeId) else userScheme | |
| colorScheme(if (isNightMode) darkSchemeId else lightSchemeId) ?: userScheme | |
| lightSchemeId != null -> | |
| // 如果只指定了light_scheme,说明是暗色方案 | |
| if (isNightMode) userScheme else colorScheme(lightSchemeId) ?: userScheme | |
| darkSchemeId != null -> | |
| // 如果只指定了dark_scheme,说明是亮色方案 | |
| if (isNightMode) colorScheme(darkSchemeId) ?: userScheme else userScheme |
Pull request
Issue tracker
Fixes will automatically close the related issues
Fixes #1961
Feature
Describe features of this pull request
Code of conduct
Code style
make sytle-lintBuild pass
make debugManually test
Code Review
Daily build
Login and download artifact at https://github.com/osfans/trime/actions
Additional Info
Previews:



pre