From 36c8b253e846b31c4e5fc08e38a374138fd1226f Mon Sep 17 00:00:00 2001 From: WhiredPlanck Date: Sat, 25 Jan 2025 22:53:25 +0800 Subject: [PATCH 1/5] Make CandidatesView touchable --- .../fcitx5/android/input/CandidatesView.kt | 8 +++ .../android/input/TouchEventReceiverWindow.kt | 50 +++++++++++++++++++ .../candidates/floating/PagedCandidatesUi.kt | 5 ++ 3 files changed, 63 insertions(+) create mode 100644 app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt index 77b1475cc..3d36794da 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt @@ -16,6 +16,7 @@ import androidx.annotation.Size import org.fcitx.fcitx5.android.R import org.fcitx.fcitx5.android.core.FcitxEvent import org.fcitx.fcitx5.android.daemon.FcitxConnection +import org.fcitx.fcitx5.android.daemon.launchOnReady import org.fcitx.fcitx5.android.data.prefs.AppPrefs import org.fcitx.fcitx5.android.data.theme.Theme import org.fcitx.fcitx5.android.input.candidates.floating.PagedCandidatesUi @@ -73,6 +74,8 @@ class CandidatesView( true } + private val touchEventReceiverWindow = TouchEventReceiverWindow(this) + private val setupTextView: TextView.() -> Unit = { textSize = fontSize.toFloat() val v = dp(itemPaddingVertical) @@ -84,6 +87,9 @@ class CandidatesView( private val candidatesUi = PagedCandidatesUi(ctx, theme, setupTextView).apply { root.viewTreeObserver.addOnGlobalLayoutListener(layoutListener) + onCandidateClick = { index -> + fcitx.launchOnReady { it.select(index) } + } } private var bottomInsets = 0 @@ -114,8 +120,10 @@ class CandidatesView( preeditUi.update(inputPanel) preeditUi.root.visibility = if (preeditUi.visible) VISIBLE else GONE candidatesUi.update(paged, orientation) + touchEventReceiverWindow.showup() visibility = VISIBLE } else { + touchEventReceiverWindow.dismiss() visibility = GONE } } diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt new file mode 100644 index 000000000..346535999 --- /dev/null +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt @@ -0,0 +1,50 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * SPDX-FileCopyrightText: Copyright 2025 Fcitx5 for Android Contributors + */ + +package org.fcitx.fcitx5.android.input + +import android.annotation.SuppressLint +import android.view.Gravity +import android.view.MotionEvent +import android.view.View +import android.widget.PopupWindow + +class TouchEventReceiverWindow( + private val contentView: View +) { + private val ctx = contentView.context + + private val window = PopupWindow(object : View(ctx) { + @SuppressLint("ClickableViewAccessibility") + override fun onTouchEvent(event: MotionEvent?): Boolean { + return contentView.dispatchTouchEvent(event) + } + }) + + private var isWindowShowing = false + + fun showup() { + isWindowShowing = true + val location = intArrayOf(0, 0) + contentView.getLocationInWindow(location) + val (x, y) = location + val width = contentView.width + val height = contentView.height + if (window.isShowing) { + window.update(x, y, width, height) + } else { + window.width = width + window.height = height + window.showAtLocation(contentView, Gravity.NO_GRAVITY, x, y) + } + } + + fun dismiss() { + if (isWindowShowing) { + isWindowShowing = false + window.dismiss() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt index 56b2c9115..e935f26d6 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt @@ -36,6 +36,8 @@ class PagedCandidatesUi( class Pagination(override val ui: PaginationUi) : UiHolder(ui) } + var onCandidateClick: ((Int) -> Unit)? = null + private val candidatesAdapter = object : RecyclerView.Adapter() { override fun getItemCount() = data.candidates.size + (if (data.hasPrev || data.hasNext) 1 else 0) @@ -59,6 +61,9 @@ class PagedCandidatesUi( is UiHolder.Candidate -> { val candidate = data.candidates[position] holder.ui.update(candidate, active = position == data.cursorIndex) + holder.ui.root.setOnClickListener { + onCandidateClick?.invoke(position) + } } is UiHolder.Pagination -> { holder.ui.update(data) From c114975faf2cc0dca384812f913011e14c3e79b1 Mon Sep 17 00:00:00 2001 From: Rocka Date: Mon, 27 Jan 2025 22:08:43 +0800 Subject: [PATCH 2/5] Update touchEventReceiverWindow's position after CandidatesView's --- .../java/org/fcitx/fcitx5/android/input/CandidatesView.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt index 3d36794da..93610b624 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt @@ -120,7 +120,6 @@ class CandidatesView( preeditUi.update(inputPanel) preeditUi.root.visibility = if (preeditUi.visible) VISIBLE else GONE candidatesUi.update(paged, orientation) - touchEventReceiverWindow.showup() visibility = VISIBLE } else { touchEventReceiverWindow.dismiss() @@ -149,6 +148,8 @@ class CandidatesView( } translationY = if (bottom + selfHeight > parentHeight - bottomInsets) top - selfHeight else bottom + // update touchEventReceiverWindow's position after CandidatesView's + touchEventReceiverWindow.showup() shouldUpdatePosition = false } @@ -201,6 +202,7 @@ class CandidatesView( override fun onDetachedFromWindow() { viewTreeObserver.removeOnPreDrawListener(preDrawListener) candidatesUi.root.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener) + touchEventReceiverWindow.dismiss() super.onDetachedFromWindow() } } From 6d2b52329f3dee7328174c43d5964e321c75e481 Mon Sep 17 00:00:00 2001 From: Rocka Date: Mon, 27 Jan 2025 22:09:25 +0800 Subject: [PATCH 3/5] Disable animations --- .../fcitx5/android/input/TouchEventReceiverWindow.kt | 11 +++++++---- .../input/candidates/floating/PagedCandidatesUi.kt | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt index 346535999..8a5e30d7c 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/TouchEventReceiverWindow.kt @@ -21,15 +21,18 @@ class TouchEventReceiverWindow( override fun onTouchEvent(event: MotionEvent?): Boolean { return contentView.dispatchTouchEvent(event) } - }) + }).apply { + // disable animation + animationStyle = 0 + } private var isWindowShowing = false + private val cachedLocation = intArrayOf(0, 0) + fun showup() { isWindowShowing = true - val location = intArrayOf(0, 0) - contentView.getLocationInWindow(location) - val (x, y) = location + val (x, y) = cachedLocation.also { contentView.getLocationInWindow(it) } val width = contentView.width val height = contentView.height if (window.isShowing) { diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt index e935f26d6..2af27b18a 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt @@ -84,6 +84,7 @@ class PagedCandidatesUi( isFocusable = false adapter = candidatesAdapter layoutManager = candidatesLayoutManager + overScrollMode = View.OVER_SCROLL_NEVER } @SuppressLint("NotifyDataSetChanged") From 5c2c36042c492e7583de8eea01ae883085b4cf3f Mon Sep 17 00:00:00 2001 From: Rocka Date: Mon, 27 Jan 2025 22:10:12 +0800 Subject: [PATCH 4/5] Make pagination icons clickable --- .../cpp/androidfrontend/androidfrontend.cpp | 26 ++++++++++++++++ .../cpp/androidfrontend/androidfrontend.h | 2 ++ .../androidfrontend/androidfrontend_public.h | 3 ++ app/src/main/cpp/native-lib.cpp | 11 +++++++ .../org/fcitx/fcitx5/android/core/Fcitx.kt | 30 +++++++++++++++++-- .../org/fcitx/fcitx5/android/core/FcitxAPI.kt | 1 + .../fcitx5/android/input/CandidatesView.kt | 9 +++--- .../candidates/floating/PagedCandidatesUi.kt | 16 +++++++--- .../input/candidates/floating/PaginationUi.kt | 5 ++-- 9 files changed, 90 insertions(+), 13 deletions(-) diff --git a/app/src/main/cpp/androidfrontend/androidfrontend.cpp b/app/src/main/cpp/androidfrontend/androidfrontend.cpp index e6b7951a6..d101cb328 100644 --- a/app/src/main/cpp/androidfrontend/androidfrontend.cpp +++ b/app/src/main/cpp/androidfrontend/androidfrontend.cpp @@ -237,6 +237,27 @@ class AndroidInputContext : public InputContextV2 { } } + void offsetCandidatePage(int delta) { + if (delta == 0) { + return; + } + const auto &list = inputPanel().candidateList(); + if (!list) { + return; + } + const auto &pageable = list->toPageable(); + if (!pageable) { + return; + } + if (delta > 0 && pageable->hasNext()) { + pageable->next(); + updateUserInterface(UserInterfaceComponent::InputPanel); + } else if (delta < 0 && pageable->hasPrev()) { + pageable->prev(); + updateUserInterface(UserInterfaceComponent::InputPanel); + } + } + private: AndroidFrontend *frontend_; int uid_; @@ -419,6 +440,11 @@ void AndroidFrontend::updatePagedCandidate(const PagedCandidateEntity &paged) { pagedCandidateCallback(paged); } +void AndroidFrontend::offsetCandidatePage(int delta) { + if (!activeIC_) return; + activeIC_->offsetCandidatePage(delta); +} + void AndroidFrontend::setCommitStringCallback(const CommitStringCallback &callback) { commitStringCallback = callback; } diff --git a/app/src/main/cpp/androidfrontend/androidfrontend.h b/app/src/main/cpp/androidfrontend/androidfrontend.h index 9934ef8e7..9b9db800b 100644 --- a/app/src/main/cpp/androidfrontend/androidfrontend.h +++ b/app/src/main/cpp/androidfrontend/androidfrontend.h @@ -47,6 +47,7 @@ class AndroidFrontend : public AddonInstance { void deleteSurrounding(const int before, const int after); void showToast(const std::string &s); void setCandidatePagingMode(const int mode); + void offsetCandidatePage(int delta); void setCandidateListCallback(const CandidateListCallback &callback); void setCommitStringCallback(const CommitStringCallback &callback); void setPreeditCallback(const ClientPreeditCallback &callback); @@ -74,6 +75,7 @@ class AndroidFrontend : public AddonInstance { FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, triggerCandidateAction); FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, showToast); FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setCandidatePagingMode); + FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, offsetCandidatePage); FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setCandidateListCallback); FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setCommitStringCallback); FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setPreeditCallback); diff --git a/app/src/main/cpp/androidfrontend/androidfrontend_public.h b/app/src/main/cpp/androidfrontend/androidfrontend_public.h index d144c9873..69bcbbdd5 100644 --- a/app/src/main/cpp/androidfrontend/androidfrontend_public.h +++ b/app/src/main/cpp/androidfrontend/androidfrontend_public.h @@ -68,6 +68,9 @@ FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, showToast, FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setCandidatePagingMode, void(const int)) +FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, offsetCandidatePage, + void(int)) + FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setCandidateListCallback, void(const CandidateListCallback &)) diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp index decf4ccf9..fb66925d2 100644 --- a/app/src/main/cpp/native-lib.cpp +++ b/app/src/main/cpp/native-lib.cpp @@ -429,6 +429,10 @@ class Fcitx { return p_frontend->call(mode); } + void offsetCandidatePage(int delta) { + return p_frontend->call(delta); + } + void save() { p_instance->save(); } @@ -1068,6 +1072,13 @@ Java_org_fcitx_fcitx5_android_core_Fcitx_setFcitxCandidatePagingMode(JNIEnv *env Fcitx::Instance().setCandidatePagingMode(mode); } +extern "C" +JNIEXPORT void JNICALL +Java_org_fcitx_fcitx5_android_core_Fcitx_offsetFcitxCandidatePage(JNIEnv *env, jclass clazz, jint delta) { + RETURN_IF_NOT_RUNNING + Fcitx::Instance().offsetCandidatePage(delta); +} + extern "C" JNIEXPORT void JNICALL Java_org_fcitx_fcitx5_android_core_Fcitx_loopOnce(JNIEnv *env, jclass clazz) { diff --git a/app/src/main/java/org/fcitx/fcitx5/android/core/Fcitx.kt b/app/src/main/java/org/fcitx/fcitx5/android/core/Fcitx.kt index c92b96de7..54aa7a084 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/core/Fcitx.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/core/Fcitx.kt @@ -73,7 +73,13 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner { override suspend fun save() = withFcitxContext { saveFcitxState() } override suspend fun reloadConfig() = withFcitxContext { reloadFcitxConfig() } - override suspend fun sendKey(key: String, states: UInt, code: Int, up: Boolean, timestamp: Int) = + override suspend fun sendKey( + key: String, + states: UInt, + code: Int, + up: Boolean, + timestamp: Int + ) = withFcitxContext { sendKeyToFcitxString(key, states.toInt(), code, up, timestamp) } override suspend fun sendKey(c: Char, states: UInt, code: Int, up: Boolean, timestamp: Int) = @@ -82,7 +88,13 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner { override suspend fun sendKey(sym: Int, states: UInt, code: Int, up: Boolean, timestamp: Int) = withFcitxContext { sendKeySymToFcitx(sym, states.toInt(), code, up, timestamp) } - override suspend fun sendKey(sym: KeySym, states: KeyStates, code: Int, up: Boolean, timestamp: Int) = + override suspend fun sendKey( + sym: KeySym, + states: KeyStates, + code: Int, + up: Boolean, + timestamp: Int + ) = withFcitxContext { sendKeySymToFcitx(sym.sym, states.toInt(), code, up, timestamp) } override suspend fun select(idx: Int): Boolean = withFcitxContext { selectCandidate(idx) } @@ -172,6 +184,9 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner { override suspend fun setCandidatePagingMode(mode: Int) = withFcitxContext { setFcitxCandidatePagingMode(mode) } + override suspend fun offsetCandidatePage(delta: Int) = + withFcitxContext { offsetFcitxCandidatePage(delta) } + init { if (lifecycle.currentState != FcitxLifecycle.State.STOPPED) throw IllegalAccessException("Fcitx5 has already been created!") @@ -233,7 +248,13 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner { external fun reloadFcitxConfig() @JvmStatic - external fun sendKeyToFcitxString(key: String, state: Int, code: Int, up: Boolean, timestamp: Int) + external fun sendKeyToFcitxString( + key: String, + state: Int, + code: Int, + up: Boolean, + timestamp: Int + ) @JvmStatic external fun sendKeyToFcitxChar(c: Char, state: Int, code: Int, up: Boolean, timestamp: Int) @@ -343,6 +364,9 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner { @JvmStatic external fun setFcitxCandidatePagingMode(mode: Int) + @JvmStatic + external fun offsetFcitxCandidatePage(delta: Int) + @JvmStatic external fun loopOnce() diff --git a/app/src/main/java/org/fcitx/fcitx5/android/core/FcitxAPI.kt b/app/src/main/java/org/fcitx/fcitx5/android/core/FcitxAPI.kt index 4c3e55c8f..b6fd8ce8e 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/core/FcitxAPI.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/core/FcitxAPI.kt @@ -103,5 +103,6 @@ interface FcitxAPI { suspend fun triggerCandidateAction(idx: Int, actionIdx: Int) suspend fun setCandidatePagingMode(mode: Int) + suspend fun offsetCandidatePage(delta: Int) } \ No newline at end of file diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt index 93610b624..9a47af029 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/CandidatesView.kt @@ -85,11 +85,12 @@ class CandidatesView( private val preeditUi = PreeditUi(ctx, theme, setupTextView) - private val candidatesUi = PagedCandidatesUi(ctx, theme, setupTextView).apply { + private val candidatesUi = PagedCandidatesUi(ctx, theme, setupTextView, + onCandidateClick = { index -> fcitx.launchOnReady { it.select(index) } }, + onPrevPage = { fcitx.launchOnReady { it.offsetCandidatePage(-1) } }, + onNextPage = { fcitx.launchOnReady { it.offsetCandidatePage(1) } } + ).apply { root.viewTreeObserver.addOnGlobalLayoutListener(layoutListener) - onCandidateClick = { index -> - fcitx.launchOnReady { it.select(index) } - } } private var bottomInsets = 0 diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt index 2af27b18a..6fe623387 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PagedCandidatesUi.kt @@ -7,6 +7,7 @@ package org.fcitx.fcitx5.android.input.candidates.floating import android.annotation.SuppressLint import android.content.Context +import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.core.view.updateLayoutParams @@ -24,7 +25,10 @@ import splitties.views.dsl.recyclerview.recyclerView class PagedCandidatesUi( override val ctx: Context, val theme: Theme, - private val setupTextView: TextView.() -> Unit + private val setupTextView: TextView.() -> Unit, + private val onCandidateClick: (Int) -> Unit, + private val onPrevPage: () -> Unit, + private val onNextPage: () -> Unit ) : Ui { private var data = FcitxEvent.PagedCandidateEvent.Data.Empty @@ -36,8 +40,6 @@ class PagedCandidatesUi( class Pagination(override val ui: PaginationUi) : UiHolder(ui) } - var onCandidateClick: ((Int) -> Unit)? = null - private val candidatesAdapter = object : RecyclerView.Adapter() { override fun getItemCount() = data.candidates.size + (if (data.hasPrev || data.hasNext) 1 else 0) @@ -52,6 +54,12 @@ class PagedCandidatesUi( ui.root.layoutParams = FlexboxLayoutManager.LayoutParams(wrap, wrap).apply { flexGrow = 1f } + ui.prevIcon.setOnClickListener { + onPrevPage.invoke() + } + ui.nextIcon.setOnClickListener { + onNextPage.invoke() + } } } } @@ -62,7 +70,7 @@ class PagedCandidatesUi( val candidate = data.candidates[position] holder.ui.update(candidate, active = position == data.cursorIndex) holder.ui.root.setOnClickListener { - onCandidateClick?.invoke(position) + onCandidateClick.invoke(position) } } is UiHolder.Pagination -> { diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PaginationUi.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PaginationUi.kt index 665552c56..44bc9b7ce 100644 --- a/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PaginationUi.kt +++ b/app/src/main/java/org/fcitx/fcitx5/android/input/candidates/floating/PaginationUi.kt @@ -31,10 +31,11 @@ class PaginationUi(override val ctx: Context, val theme: Theme) : Ui { imageTintList = ColorStateList.valueOf(theme.keyTextColor) imageDrawable = drawable(icon) scaleType = ImageView.ScaleType.CENTER_CROP + isClickable = true } - private val prevIcon = createIcon(R.drawable.ic_baseline_arrow_prev_24) - private val nextIcon = createIcon(R.drawable.ic_baseline_arrow_next_24) + val prevIcon = createIcon(R.drawable.ic_baseline_arrow_prev_24) + val nextIcon = createIcon(R.drawable.ic_baseline_arrow_next_24) private val disabledAlpha = styledFloat(android.R.attr.disabledAlpha) From 792e828b9134522c082bca0249a153ce48f40665 Mon Sep 17 00:00:00 2001 From: Rocka Date: Mon, 27 Jan 2025 22:27:34 +0800 Subject: [PATCH 5/5] Fix selecting paged candidate --- .../cpp/androidfrontend/androidfrontend.cpp | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/androidfrontend/androidfrontend.cpp b/app/src/main/cpp/androidfrontend/androidfrontend.cpp index d101cb328..81fa44063 100644 --- a/app/src/main/cpp/androidfrontend/androidfrontend.cpp +++ b/app/src/main/cpp/androidfrontend/androidfrontend.cpp @@ -131,7 +131,7 @@ class AndroidInputContext : public InputContextV2 { frontend_->updatePagedCandidate(paged); } - bool selectCandidate(int idx) { + bool selectCandidateBulk(int idx) { const auto &list = inputPanel().candidateList(); if (!list) { return false; @@ -150,6 +150,20 @@ class AndroidInputContext : public InputContextV2 { return true; } + bool selectCandidatePaged(int idx) { + const auto &list = inputPanel().candidateList(); + if (!list) { + return false; + } + try { + list->candidate(idx).select(this); + } catch (const std::invalid_argument &e) { + FCITX_WARN() << "selectCandidate index out of range"; + return false; + } + return true; + } + std::vector getCandidates(const int offset, const int limit) { std::vector candidates; const auto &list = inputPanel().candidateList(); @@ -349,7 +363,11 @@ void AndroidFrontend::releaseInputContext(const int uid) { bool AndroidFrontend::selectCandidate(int idx) { if (!activeIC_) return false; - return activeIC_->selectCandidate(idx); + if (pagingMode_) { + return activeIC_->selectCandidatePaged(idx); + } else { + return activeIC_->selectCandidateBulk(idx); + } } std::vector AndroidFrontend::getCandidateActions(const int idx) { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy