Fix CandidatesView position when CursorAnchorInfo is invalid on API 35+

This commit is contained in:
Rocka 2026-04-30 23:44:32 +08:00
parent 762683f6bd
commit 9ea5b01c65
No known key found for this signature in database
GPG Key ID: 28031158FFDD6853
2 changed files with 17 additions and 13 deletions

View File

@ -192,6 +192,21 @@ class CandidatesView(
updatePosition()
}
/**
* Anchor candidates view to bottom-left corner, takes navbar bottom insets into consideration.
* Should only be used when [CursorAnchorInfo][android.view.inputmethod.CursorAnchorInfo] is invalid
*/
fun updateCursorAnchor(@Size(2) parent: FloatArray) {
val (parentWidth, parentHeight) = parent
val bottom = parentHeight - bottomInsets
anchorPosition[0] = 0f
anchorPosition[1] = bottom
anchorPosition[2] = bottom
parentSize[0] = parentWidth
parentSize[1] = parentHeight
updatePosition()
}
init {
// invisible by default
visibility = INVISIBLE

View File

@ -765,7 +765,7 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
}
// anchor CandidatesView to bottom-left corner in case InputConnection does not
// support monitoring CursorAnchorInfo
workaroundNullCursorAnchorInfo()
candidatesView?.updateCursorAnchor(contentSize)
}
}
}
@ -805,17 +805,6 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
private val anchorPosition = floatArrayOf(0f, 0f, 0f, 0f)
/**
* anchor candidates view to bottom-left corner, only works if [decorLocationUpdated]
*/
private fun workaroundNullCursorAnchorInfo() {
anchorPosition[0] = 0f
anchorPosition[1] = contentSize[1]
anchorPosition[2] = 0f
anchorPosition[3] = contentSize[1]
candidatesView?.updateCursorAnchor(anchorPosition, contentSize)
}
override fun onUpdateCursorAnchorInfo(info: CursorAnchorInfo) {
val bounds = info.getCharacterBounds(0)
if (bounds != null) {
@ -838,7 +827,7 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
}
if (anchorPosition.any(Float::isNaN)) {
// anchor candidates view to bottom-left corner in case CursorAnchorInfo is invalid
workaroundNullCursorAnchorInfo()
candidatesView?.updateCursorAnchor(contentSize)
return
}
// params of `Matrix.mapPoints` must be [x0, y0, x1, y1]