diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml
index 47a98367..77304b86 100644
--- a/.idea/dictionaries/project.xml
+++ b/.idea/dictionaries/project.xml
@@ -4,11 +4,13 @@
androidfrontend
androidkeyboard
androidnotification
+ anthy
berberman
bopomofo
constraintlayout
cout
customphrase
+ dianbaoma
endl
fcitx
fmtlib
@@ -29,6 +31,7 @@
libintl
libthai
ljava
+ mozc
nihaoshijie
orphis
pkgdatadir
@@ -45,7 +48,10 @@
stringutils
unfocus
unikey
+ wbpy
+ zhengma
zhuyin
+ ziranma
zlib
diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/FcitxInputMethodService.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/FcitxInputMethodService.kt
index d1ad9a10..81db65e9 100644
--- a/app/src/main/java/org/fcitx/fcitx5/android/input/FcitxInputMethodService.kt
+++ b/app/src/main/java/org/fcitx/fcitx5/android/input/FcitxInputMethodService.kt
@@ -107,6 +107,11 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
setCandidatePagingMode(if (isVirtualKeyboard) 0 else 1)
}
currentInputConnection?.monitorCursorAnchor(!isVirtualKeyboard)
+ if (isVirtualKeyboard) {
+ hideStatusIcon()
+ } else {
+ showStatusIcon(StatusIconMapping.fromEntry(fcitx.runImmediately { inputMethodEntryCached }))
+ }
window.window?.let {
navbarMgr.evaluate(it, isVirtualKeyboard)
}
@@ -312,6 +317,9 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
// [^1]: notify system that input method subtype has changed
switchInputMethod(InputMethodUtil.componentName, subtype)
}
+ if (inputDeviceMgr.evaluateOnInputMethodActivate()) {
+ showStatusIcon(StatusIconMapping.fromEntry(event.data))
+ }
}
is FcitxEvent.SwitchInputMethodEvent -> {
val (reason) = event.data
@@ -767,6 +775,7 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
// support monitoring CursorAnchorInfo
candidatesView?.updateCursorAnchor(contentSize)
}
+ showStatusIcon(StatusIconMapping.fromEntry(fcitx.runImmediately { inputMethodEntryCached }))
}
}
@@ -1032,6 +1041,7 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
postFcitxJob {
focusOutIn()
}
+ hideStatusIcon()
showingDialog?.dismiss()
}
diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/InputDeviceManager.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/InputDeviceManager.kt
index 38b7f007..4b99a22b 100644
--- a/app/src/main/java/org/fcitx/fcitx5/android/input/InputDeviceManager.kt
+++ b/app/src/main/java/org/fcitx/fcitx5/android/input/InputDeviceManager.kt
@@ -142,6 +142,15 @@ class InputDeviceManager(private val onChange: (Boolean) -> Unit) {
return !isVirtualKeyboard && !startedInputView
}
+ /**
+ * Should be called whenever active input method changes,
+ * eg. focus in/out, editor capability flag changes, user presses the shortcut, and so on...
+ * @return should update status icon for this change
+ */
+ fun evaluateOnInputMethodActivate(): Boolean {
+ return startedInputView && !isVirtualKeyboard
+ }
+
fun onFinishInputView() {
startedInputView = false
}
diff --git a/app/src/main/java/org/fcitx/fcitx5/android/input/StatusIconMapping.kt b/app/src/main/java/org/fcitx/fcitx5/android/input/StatusIconMapping.kt
new file mode 100644
index 00000000..19bced8f
--- /dev/null
+++ b/app/src/main/java/org/fcitx/fcitx5/android/input/StatusIconMapping.kt
@@ -0,0 +1,59 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * SPDX-FileCopyrightText: Copyright 2025 Fcitx5 for Android Contributors
+ */
+
+package org.fcitx.fcitx5.android.input
+
+import androidx.annotation.DrawableRes
+import org.fcitx.fcitx5.android.R
+import org.fcitx.fcitx5.android.core.InputMethodEntry
+
+object StatusIconMapping {
+ @DrawableRes
+ fun fromEntry(entry: InputMethodEntry): Int {
+ if (entry.subMode.icon.isNotEmpty()) {
+ when (entry.subMode.icon) {
+ "fcitx_mozc_direct" -> return R.drawable.ic_status_latin_direct
+ "fcitx_mozc_hiragana" -> return R.drawable.ic_status_hiragana
+ "fcitx_mozc_katakana_full" -> return R.drawable.ic_status_katakana
+ "fcitx_mozc_alpha_half" -> return R.drawable.ic_status_latin_half_underscore
+ "fcitx_mozc_alpha_full" -> return R.drawable.ic_status_latin_wide
+ "fcitx_mozc_katakana_half" -> return R.drawable.ic_status_katakana_half_underscore
+ }
+ }
+ if (entry.subMode.label.isNotEmpty()) {
+ when (entry.subMode.label) {
+ "あ" -> return R.drawable.ic_status_hiragana
+ "ア" -> return R.drawable.ic_status_katakana
+ "ア" -> return R.drawable.ic_status_katakana_half
+ "A" -> return R.drawable.ic_status_latin_wide
+ "A" -> return R.drawable.ic_status_latin_direct
+ }
+ }
+ when (entry.icon) {
+ "fcitx-pinyin" -> return R.drawable.ic_status_pinyin
+ "fcitx-shuangpin" -> return R.drawable.ic_status_shuangpin
+ "fcitx-wubi", "fcitx-wbpy" -> return R.drawable.ic_status_wubi
+ "fcitx-cangjie" -> return R.drawable.ic_status_cangjie
+ "fcitx-ziranma" -> return R.drawable.ic_status_ziranma
+ "fcitx-dianbaoma" -> return R.drawable.ic_status_dianbaoma
+ "fcitx-zhengma", "fcitx_zhengma" -> return R.drawable.ic_status_zhengma
+ "fcitx-jyutping", "fcitx_jyutping_table" -> return R.drawable.ic_status_jyutping
+ "fcitx-chewing" -> return R.drawable.ic_status_chewing
+ "fcitx-rime" -> return R.drawable.ic_status_rime
+ "fcitx_rime_latin" -> R.drawable.ic_status_latin_direct
+ "fcitx_rime_disable" -> R.drawable.ic_status_disabled
+ }
+ when (entry.languageCode) {
+ "en", "en_US" -> return R.drawable.ic_status_en
+ "zh", "zh_CN", "zh_TW", "zh_HK" -> return R.drawable.ic_status_zh
+ "ja" -> return R.drawable.ic_status_hiragana
+ "ko" -> return R.drawable.ic_status_hangul
+ "si" -> return R.drawable.ic_status_sayura
+ "th" -> return R.drawable.ic_status_thai
+ "vi" -> return R.drawable.ic_status_vi
+ }
+ return R.drawable.ic_baseline_keyboard_24
+ }
+}
diff --git a/app/src/main/res/drawable/ic_status_cangjie.xml b/app/src/main/res/drawable/ic_status_cangjie.xml
new file mode 100644
index 00000000..6ab243d9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_cangjie.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_chewing.xml b/app/src/main/res/drawable/ic_status_chewing.xml
new file mode 100644
index 00000000..7185eac9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_chewing.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_dianbaoma.xml b/app/src/main/res/drawable/ic_status_dianbaoma.xml
new file mode 100644
index 00000000..92fc6093
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_dianbaoma.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_disabled.xml b/app/src/main/res/drawable/ic_status_disabled.xml
new file mode 100644
index 00000000..2577ee7e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_disabled.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_status_en.xml b/app/src/main/res/drawable/ic_status_en.xml
new file mode 100644
index 00000000..7f866dd0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_en.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_hangul.xml b/app/src/main/res/drawable/ic_status_hangul.xml
new file mode 100644
index 00000000..93a51c25
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_hangul.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_hiragana.xml b/app/src/main/res/drawable/ic_status_hiragana.xml
new file mode 100644
index 00000000..d809405a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_hiragana.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_jyutping.xml b/app/src/main/res/drawable/ic_status_jyutping.xml
new file mode 100644
index 00000000..adec6e1a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_jyutping.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_katakana.xml b/app/src/main/res/drawable/ic_status_katakana.xml
new file mode 100644
index 00000000..9b5c736b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_katakana.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_katakana_half.xml b/app/src/main/res/drawable/ic_status_katakana_half.xml
new file mode 100644
index 00000000..4d259b9c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_katakana_half.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_katakana_half_underscore.xml b/app/src/main/res/drawable/ic_status_katakana_half_underscore.xml
new file mode 100644
index 00000000..255daba3
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_katakana_half_underscore.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_latin_direct.xml b/app/src/main/res/drawable/ic_status_latin_direct.xml
new file mode 100644
index 00000000..973d50a1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_latin_direct.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_latin_half_underscore.xml b/app/src/main/res/drawable/ic_status_latin_half_underscore.xml
new file mode 100644
index 00000000..36032bb8
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_latin_half_underscore.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_latin_wide.xml b/app/src/main/res/drawable/ic_status_latin_wide.xml
new file mode 100644
index 00000000..f5e99281
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_latin_wide.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_pinyin.xml b/app/src/main/res/drawable/ic_status_pinyin.xml
new file mode 100644
index 00000000..ea91c113
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_pinyin.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_rime.xml b/app/src/main/res/drawable/ic_status_rime.xml
new file mode 100644
index 00000000..4347385b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_rime.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_sayura.xml b/app/src/main/res/drawable/ic_status_sayura.xml
new file mode 100644
index 00000000..99496259
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_sayura.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_shuangpin.xml b/app/src/main/res/drawable/ic_status_shuangpin.xml
new file mode 100644
index 00000000..cf8cb8a0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_shuangpin.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_thai.xml b/app/src/main/res/drawable/ic_status_thai.xml
new file mode 100644
index 00000000..494487ea
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_thai.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_vi.xml b/app/src/main/res/drawable/ic_status_vi.xml
new file mode 100644
index 00000000..ef7230a9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_vi.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_wubi.xml b/app/src/main/res/drawable/ic_status_wubi.xml
new file mode 100644
index 00000000..443dcc98
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_wubi.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_zh.xml b/app/src/main/res/drawable/ic_status_zh.xml
new file mode 100644
index 00000000..4e3072e7
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_zh.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_zhengma.xml b/app/src/main/res/drawable/ic_status_zhengma.xml
new file mode 100644
index 00000000..7e8fc008
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_zhengma.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_status_ziranma.xml b/app/src/main/res/drawable/ic_status_ziranma.xml
new file mode 100644
index 00000000..62fc814b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_status_ziranma.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c98470cf..d19fe469 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -317,4 +317,5 @@
Hide unsupported Emojis
Enable stroke for key border
Preferred voice input
+ EditText Playground