diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt index 5b28c04219..e0d2dfd4eb 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt @@ -20,6 +20,7 @@ import java.io.Serializable import org.yuzu.yuzu_emu.NativeLibrary import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.applets.keyboard.ui.KeyboardDialogFragment +import org.yuzu.yuzu_emu.overlay.InputOverlay @Keep object SoftwareKeyboard { @@ -37,6 +38,7 @@ object SoftwareKeyboard { val emulationActivity = NativeLibrary.sEmulationActivity.get() val overlayView = emulationActivity!!.findViewById(R.id.surface_input_overlay) + (overlayView as? InputOverlay)?.resetImeBuffer(config.initial_text ?: "") overlayView.requestFocus() val im = overlayView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt index 7ff9c78923..94cfdbde42 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt @@ -19,6 +19,7 @@ import android.os.Handler import android.os.Looper import android.text.Editable import android.text.InputType +import android.text.Selection import android.util.AttributeSet import android.view.HapticFeedbackConstants import android.view.KeyEvent @@ -57,6 +58,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : private val overlayDpads: MutableSet = HashSet() private val overlayJoysticks: MutableSet = HashSet() private val imeEditable = Editable.Factory.getInstance().newEditable("") + private var pendingInitialText: String = "" private var inEditMode = false private var gamelessMode = false @@ -85,15 +87,24 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : override fun onCheckIsTextEditor(): Boolean = true + fun resetImeBuffer(initialText: String = "") { + pendingInitialText = initialText + } + override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection { imeEditable.clear() + if (pendingInitialText.isNotEmpty()) { + imeEditable.append(pendingInitialText) + } + pendingInitialText = "" + Selection.setSelection(imeEditable, imeEditable.length) outAttrs.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI or EditorInfo.IME_ACTION_DONE - outAttrs.initialSelStart = 0 - outAttrs.initialSelEnd = 0 + outAttrs.initialSelStart = imeEditable.length + outAttrs.initialSelEnd = imeEditable.length return object : BaseInputConnection(this, true) { override fun getEditable(): Editable = imeEditable diff --git a/src/common/android/applets/software_keyboard.cpp b/src/common/android/applets/software_keyboard.cpp index 8967811bd3..73b6d9be07 100644 --- a/src/common/android/applets/software_keyboard.cpp +++ b/src/common/android/applets/software_keyboard.cpp @@ -109,6 +109,7 @@ void AndroidKeyboard::InitializeKeyboard( } parameters = std::move(initialize_parameters); + m_current_text = parameters.initial_text; LOG_INFO(Frontend, "\nKeyboardInitializeParameters:" @@ -185,9 +186,13 @@ void AndroidKeyboard::ShowInlineKeyboard( // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber. m_is_inline_active = true; - std::thread([&] { + // Pass m_current_text as initial_text so Kotlin receives any text set via InlineTextChanged + // before this call (e.g. game pre-fills the field in the same Calc request as appear). + std::thread([&, current_text = m_current_text] { + Core::Frontend::KeyboardInitializeParameters p = parameters; + p.initial_text = current_text; GetEnvForThread()->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_execute_inline, - ToJKeyboardParams(parameters)); + ToJKeyboardParams(p)); }).join(); } @@ -207,6 +212,8 @@ void AndroidKeyboard::InlineTextChanged( "\ncursor_position={}", Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position); + m_current_text = text_parameters.input_text; + submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, text_parameters.input_text, text_parameters.cursor_position); } diff --git a/src/common/android/applets/software_keyboard.h b/src/common/android/applets/software_keyboard.h index 9fd09d27c5..7b194cd227 100644 --- a/src/common/android/applets/software_keyboard.h +++ b/src/common/android/applets/software_keyboard.h @@ -57,7 +57,7 @@ private: private: mutable bool m_is_inline_active{}; - std::u16string m_current_text; + mutable std::u16string m_current_text; }; // Should be called in JNI_Load