summaryrefslogtreecommitdiffstats
path: root/src/android/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/SoftwareKeyboard.java264
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt117
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt100
-rw-r--r--src/android/app/src/main/jni/applets/software_keyboard.cpp16
-rw-r--r--src/android/app/src/main/res/layout/dialog_edit_text.xml23
6 files changed, 255 insertions, 279 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
index 8304c2aa5..3589e7629 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
@@ -83,22 +83,22 @@ open class EmulationActivity : AppCompatActivity() {
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
- if (event.action == android.view.KeyEvent.ACTION_DOWN) {
- if (keyCode == android.view.KeyEvent.KEYCODE_ENTER) {
+ if (event.action == KeyEvent.ACTION_DOWN) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER) {
// Special case, we do not support multiline input, dismiss the keyboard.
val overlayView: View =
- this.findViewById<View>(R.id.surface_input_overlay)
+ this.findViewById(R.id.surface_input_overlay)
val im =
overlayView.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
- im.hideSoftInputFromWindow(overlayView.windowToken, 0);
+ im.hideSoftInputFromWindow(overlayView.windowToken, 0)
} else {
- val textChar = event.getUnicodeChar();
+ val textChar = event.unicodeChar
if (textChar == 0) {
// No text, button input.
- NativeLibrary.SubmitInlineKeyboardInput(keyCode);
+ NativeLibrary.SubmitInlineKeyboardInput(keyCode)
} else {
// Text submitted.
- NativeLibrary.SubmitInlineKeyboardText(textChar.toChar().toString());
+ NativeLibrary.SubmitInlineKeyboardText(textChar.toChar().toString())
}
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/SoftwareKeyboard.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/SoftwareKeyboard.java
deleted file mode 100644
index 8ad4b1e22..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/SoftwareKeyboard.java
+++ /dev/null
@@ -1,264 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package org.yuzu.yuzu_emu.applets;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.ResultReceiver;
-import android.text.InputFilter;
-import android.text.InputType;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.WindowInsets;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-import androidx.core.view.ViewCompat;
-import androidx.fragment.app.DialogFragment;
-
-import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-
-import org.yuzu.yuzu_emu.YuzuApplication;
-import org.yuzu.yuzu_emu.NativeLibrary;
-import org.yuzu.yuzu_emu.R;
-import org.yuzu.yuzu_emu.activities.EmulationActivity;
-
-import java.util.Objects;
-
-public final class SoftwareKeyboard {
- /// Corresponds to Service::AM::Applets::SwkbdType
- private interface SwkbdType {
- int Normal = 0;
- int NumberPad = 1;
- int Qwerty = 2;
- int Unknown3 = 3;
- int Latin = 4;
- int SimplifiedChinese = 5;
- int TraditionalChinese = 6;
- int Korean = 7;
- };
-
- /// Corresponds to Service::AM::Applets::SwkbdPasswordMode
- private interface SwkbdPasswordMode {
- int Disabled = 0;
- int Enabled = 1;
- };
-
- /// Corresponds to Service::AM::Applets::SwkbdResult
- private interface SwkbdResult {
- int Ok = 0;
- int Cancel = 1;
- };
-
- public static class KeyboardConfig implements java.io.Serializable {
- public String ok_text;
- public String header_text;
- public String sub_text;
- public String guide_text;
- public String initial_text;
- public short left_optional_symbol_key;
- public short right_optional_symbol_key;
- public int max_text_length;
- public int min_text_length;
- public int initial_cursor_position;
- public int type;
- public int password_mode;
- public int text_draw_type;
- public int key_disable_flags;
- public boolean use_blur_background;
- public boolean enable_backspace_button;
- public boolean enable_return_button;
- public boolean disable_cancel_button;
- }
-
- /// Corresponds to Frontend::KeyboardData
- public static class KeyboardData {
- public int result;
- public String text;
-
- private KeyboardData(int result, String text) {
- this.result = result;
- this.text = text;
- }
- }
-
- public static class KeyboardDialogFragment extends DialogFragment {
- static KeyboardDialogFragment newInstance(KeyboardConfig config) {
- KeyboardDialogFragment frag = new KeyboardDialogFragment();
- Bundle args = new Bundle();
- args.putSerializable("config", config);
- frag.setArguments(args);
- return frag;
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity emulationActivity = getActivity();
- assert emulationActivity != null;
-
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- params.leftMargin = params.rightMargin =
- YuzuApplication.getAppContext().getResources().getDimensionPixelSize(
- R.dimen.dialog_margin);
-
- KeyboardConfig config = Objects.requireNonNull(
- (KeyboardConfig) requireArguments().getSerializable("config"));
-
- // Set up the input
- EditText editText = new EditText(YuzuApplication.getAppContext());
- editText.setHint(config.initial_text);
- editText.setSingleLine(!config.enable_return_button);
- editText.setLayoutParams(params);
- editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(config.max_text_length)});
-
- // Handle input type
- int input_type = 0;
- switch (config.type)
- {
- case SwkbdType.Normal:
- case SwkbdType.Qwerty:
- case SwkbdType.Unknown3:
- case SwkbdType.Latin:
- case SwkbdType.SimplifiedChinese:
- case SwkbdType.TraditionalChinese:
- case SwkbdType.Korean:
- default:
- input_type = InputType.TYPE_CLASS_TEXT;
- if (config.password_mode == SwkbdPasswordMode.Enabled)
- {
- input_type |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
- }
- break;
- case SwkbdType.NumberPad:
- input_type = InputType.TYPE_CLASS_NUMBER;
- if (config.password_mode == SwkbdPasswordMode.Enabled)
- {
- input_type |= InputType.TYPE_NUMBER_VARIATION_PASSWORD;
- }
- break;
- }
-
- // Apply input type
- editText.setInputType(input_type);
-
- FrameLayout container = new FrameLayout(emulationActivity);
- container.addView(editText);
-
- String headerText = config.header_text.isEmpty() ? emulationActivity.getString(R.string.software_keyboard) : config.header_text;
- String okText = config.header_text.isEmpty() ? emulationActivity.getString(android.R.string.ok) : config.ok_text;
-
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(emulationActivity)
- .setTitle(headerText)
- .setView(container);
- setCancelable(false);
-
- builder.setPositiveButton(okText, null);
- builder.setNegativeButton(emulationActivity.getString(android.R.string.cancel), null);
-
- final AlertDialog dialog = builder.create();
- dialog.create();
- if (dialog.getButton(DialogInterface.BUTTON_POSITIVE) != null) {
- dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener((view) -> {
- data.result = SwkbdResult.Ok;
- data.text = editText.getText().toString();
- dialog.dismiss();
-
- synchronized (finishLock) {
- finishLock.notifyAll();
- }
- });
- }
- if (dialog.getButton(DialogInterface.BUTTON_NEUTRAL) != null) {
- dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener((view) -> {
- data.result = SwkbdResult.Ok;
- dialog.dismiss();
- synchronized (finishLock) {
- finishLock.notifyAll();
- }
- });
- }
- if (dialog.getButton(DialogInterface.BUTTON_NEGATIVE) != null) {
- dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener((view) -> {
- data.result = SwkbdResult.Cancel;
- dialog.dismiss();
- synchronized (finishLock) {
- finishLock.notifyAll();
- }
- });
- }
-
- return dialog;
- }
- }
-
- private static KeyboardData data;
- private static final Object finishLock = new Object();
-
- private static void ExecuteNormalImpl(KeyboardConfig config) {
- final EmulationActivity emulationActivity = NativeLibrary.sEmulationActivity.get();
-
- data = new KeyboardData(SwkbdResult.Cancel, "");
-
- KeyboardDialogFragment fragment = KeyboardDialogFragment.newInstance(config);
- fragment.show(emulationActivity.getSupportFragmentManager(), "keyboard");
- }
-
- private static void ExecuteInlineImpl(KeyboardConfig config) {
- final EmulationActivity emulationActivity = NativeLibrary.sEmulationActivity.get();
-
- var overlayView = emulationActivity.findViewById(R.id.surface_input_overlay);
- InputMethodManager im = (InputMethodManager)overlayView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED);
-
- // There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
- final Handler handler = new Handler();
- final int delayMs = 500;
- handler.postDelayed(new Runnable() {
- public void run() {
- var insets = ViewCompat.getRootWindowInsets(overlayView);
- var isKeyboardVisible = insets.isVisible(WindowInsets.Type.ime());
- if (isKeyboardVisible) {
- handler.postDelayed(this, delayMs);
- return;
- }
-
- // No longer visible, submit the result.
- NativeLibrary.SubmitInlineKeyboardInput(android.view.KeyEvent.KEYCODE_ENTER);
- }
- }, delayMs);
- }
-
- public static KeyboardData ExecuteNormal(KeyboardConfig config) {
- NativeLibrary.sEmulationActivity.get().runOnUiThread(() -> ExecuteNormalImpl(config));
-
- synchronized (finishLock) {
- try {
- finishLock.wait();
- } catch (Exception ignored) {
- }
- }
-
- return data;
- }
-
- public static void ExecuteInline(KeyboardConfig config) {
- NativeLibrary.sEmulationActivity.get().runOnUiThread(() -> ExecuteInlineImpl(config));
- }
-
- public static void ShowError(String error) {
- NativeLibrary.displayAlertMsg(
- YuzuApplication.getAppContext().getResources().getString(R.string.software_keyboard),
- error, false);
- }
-}
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
new file mode 100644
index 000000000..704109ec0
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard.kt
@@ -0,0 +1,117 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.yuzu.yuzu_emu.applets.keyboard
+
+import android.content.Context
+import android.os.Handler
+import android.os.Looper
+import android.view.KeyEvent
+import android.view.View
+import android.view.WindowInsets
+import android.view.inputmethod.InputMethodManager
+import androidx.core.view.ViewCompat
+import org.yuzu.yuzu_emu.NativeLibrary
+import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.applets.keyboard.ui.KeyboardDialogFragment
+import java.io.Serializable
+
+object SoftwareKeyboard {
+ lateinit var data: KeyboardData
+ val dataLock = Object()
+
+ private fun executeNormalImpl(config: KeyboardConfig) {
+ val emulationActivity = NativeLibrary.sEmulationActivity.get()
+ data = KeyboardData(SwkbdResult.Cancel.ordinal, "")
+ val fragment = KeyboardDialogFragment.newInstance(config)
+ fragment.show(emulationActivity!!.supportFragmentManager, KeyboardDialogFragment.TAG)
+ }
+
+ private fun executeInlineImpl(config: KeyboardConfig) {
+ val emulationActivity = NativeLibrary.sEmulationActivity.get()
+
+ val overlayView = emulationActivity!!.findViewById<View>(R.id.surface_input_overlay)
+ val im =
+ overlayView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED)
+
+ // There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
+ val handler = Handler(Looper.myLooper()!!)
+ val delayMs = 500
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ val insets = ViewCompat.getRootWindowInsets(overlayView)
+ val isKeyboardVisible = insets!!.isVisible(WindowInsets.Type.ime())
+ if (isKeyboardVisible) {
+ handler.postDelayed(this, delayMs.toLong())
+ return
+ }
+
+ // No longer visible, submit the result.
+ NativeLibrary.SubmitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
+ }
+ }, delayMs.toLong())
+ }
+
+ @JvmStatic
+ fun executeNormal(config: KeyboardConfig): KeyboardData {
+ NativeLibrary.sEmulationActivity.get()!!.runOnUiThread { executeNormalImpl(config) }
+ synchronized(dataLock) {
+ dataLock.wait()
+ }
+ return data
+ }
+
+ @JvmStatic
+ fun executeInline(config: KeyboardConfig) {
+ NativeLibrary.sEmulationActivity.get()!!.runOnUiThread { executeInlineImpl(config) }
+ }
+
+ // Corresponds to Service::AM::Applets::SwkbdType
+ enum class SwkbdType {
+ Normal,
+ NumberPad,
+ Qwerty,
+ Unknown3,
+ Latin,
+ SimplifiedChinese,
+ TraditionalChinese,
+ Korean
+ }
+
+ // Corresponds to Service::AM::Applets::SwkbdPasswordMode
+ enum class SwkbdPasswordMode {
+ Disabled,
+ Enabled
+ }
+
+ // Corresponds to Service::AM::Applets::SwkbdResult
+ enum class SwkbdResult {
+ Ok,
+ Cancel
+ }
+
+ data class KeyboardConfig(
+ var ok_text: String? = null,
+ var header_text: String? = null,
+ var sub_text: String? = null,
+ var guide_text: String? = null,
+ var initial_text: String? = null,
+ var left_optional_symbol_key: Short = 0,
+ var right_optional_symbol_key: Short = 0,
+ var max_text_length: Int = 0,
+ var min_text_length: Int = 0,
+ var initial_cursor_position: Int = 0,
+ var type: Int = 0,
+ var password_mode: Int = 0,
+ var text_draw_type: Int = 0,
+ var key_disable_flags: Int = 0,
+ var use_blur_background: Boolean = false,
+ var enable_backspace_button: Boolean = false,
+ var enable_return_button: Boolean = false,
+ var disable_cancel_button: Boolean = false
+ ) : Serializable
+
+ // Corresponds to Frontend::KeyboardData
+ data class KeyboardData(var result: Int, var text: String)
+}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt
new file mode 100644
index 000000000..2428bd261
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt
@@ -0,0 +1,100 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.yuzu.yuzu_emu.applets.keyboard.ui
+
+import android.app.Dialog
+import android.content.DialogInterface
+import android.os.Bundle
+import android.text.InputFilter
+import android.text.InputType
+import androidx.fragment.app.DialogFragment
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.applets.keyboard.SoftwareKeyboard
+import org.yuzu.yuzu_emu.applets.keyboard.SoftwareKeyboard.KeyboardConfig
+import org.yuzu.yuzu_emu.databinding.DialogEditTextBinding
+import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable
+
+class KeyboardDialogFragment : DialogFragment() {
+ private lateinit var binding: DialogEditTextBinding
+ private lateinit var config: KeyboardConfig
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ binding = DialogEditTextBinding.inflate(layoutInflater)
+ config = requireArguments().serializable(CONFIG)!!
+
+ // Set up the input
+ binding.editText.hint = config.initial_text
+ binding.editText.isSingleLine = !config.enable_return_button
+ binding.editText.filters =
+ arrayOf<InputFilter>(InputFilter.LengthFilter(config.max_text_length))
+
+ // Handle input type
+ var inputType: Int
+ when (config.type) {
+ SoftwareKeyboard.SwkbdType.Normal.ordinal,
+ SoftwareKeyboard.SwkbdType.Qwerty.ordinal,
+ SoftwareKeyboard.SwkbdType.Unknown3.ordinal,
+ SoftwareKeyboard.SwkbdType.Latin.ordinal,
+ SoftwareKeyboard.SwkbdType.SimplifiedChinese.ordinal,
+ SoftwareKeyboard.SwkbdType.TraditionalChinese.ordinal,
+ SoftwareKeyboard.SwkbdType.Korean.ordinal -> {
+ inputType = InputType.TYPE_CLASS_TEXT
+ if (config.password_mode == SoftwareKeyboard.SwkbdPasswordMode.Enabled.ordinal) {
+ inputType = inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
+ }
+ }
+ SoftwareKeyboard.SwkbdType.NumberPad.ordinal -> {
+ inputType = InputType.TYPE_CLASS_NUMBER
+ if (config.password_mode == SoftwareKeyboard.SwkbdPasswordMode.Enabled.ordinal) {
+ inputType = inputType or InputType.TYPE_NUMBER_VARIATION_PASSWORD
+ }
+ }
+ else -> {
+ inputType = InputType.TYPE_CLASS_TEXT
+ if (config.password_mode == SoftwareKeyboard.SwkbdPasswordMode.Enabled.ordinal) {
+ inputType = inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
+ }
+ }
+ }
+ binding.editText.inputType = inputType
+
+ val headerText =
+ config.header_text!!.ifEmpty { resources.getString(R.string.software_keyboard) }
+ val okText =
+ if (config.header_text!!.isEmpty()) resources.getString(android.R.string.ok) else config.ok_text!!
+
+ return MaterialAlertDialogBuilder(requireContext())
+ .setTitle(headerText)
+ .setView(binding.root)
+ .setPositiveButton(okText) { _, _ ->
+ SoftwareKeyboard.data.result = SoftwareKeyboard.SwkbdResult.Ok.ordinal
+ SoftwareKeyboard.data.text = binding.editText.text.toString()
+ }
+ .setNegativeButton(resources.getString(android.R.string.cancel)) { _, _ ->
+ SoftwareKeyboard.data.result = SoftwareKeyboard.SwkbdResult.Cancel.ordinal
+ }
+ .create()
+ }
+
+ override fun onDismiss(dialog: DialogInterface) {
+ super.onDismiss(dialog)
+ synchronized(SoftwareKeyboard.dataLock) {
+ SoftwareKeyboard.dataLock.notifyAll()
+ }
+ }
+
+ companion object {
+ const val TAG = "KeyboardDialogFragment"
+ const val CONFIG = "keyboard_config"
+
+ fun newInstance(config: KeyboardConfig?): KeyboardDialogFragment {
+ val frag = KeyboardDialogFragment()
+ val args = Bundle()
+ args.putSerializable(CONFIG, config)
+ frag.arguments = args
+ return frag
+ }
+ }
+}
diff --git a/src/android/app/src/main/jni/applets/software_keyboard.cpp b/src/android/app/src/main/jni/applets/software_keyboard.cpp
index 278137b4c..c6fffbbab 100644
--- a/src/android/app/src/main/jni/applets/software_keyboard.cpp
+++ b/src/android/app/src/main/jni/applets/software_keyboard.cpp
@@ -253,19 +253,19 @@ void AndroidKeyboard::SubmitNormalText(const ResultData& data) const {
void InitJNI(JNIEnv* env) {
s_software_keyboard_class = reinterpret_cast<jclass>(
- env->NewGlobalRef(env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard")));
+ env->NewGlobalRef(env->FindClass("org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard")));
s_keyboard_config_class = reinterpret_cast<jclass>(env->NewGlobalRef(
- env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig")));
+ env->FindClass("org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig")));
s_keyboard_data_class = reinterpret_cast<jclass>(env->NewGlobalRef(
- env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardData")));
+ env->FindClass("org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardData")));
s_swkbd_execute_normal = env->GetStaticMethodID(
- s_software_keyboard_class, "ExecuteNormal",
- "(Lorg/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig;)Lorg/yuzu/yuzu_emu/"
- "applets/SoftwareKeyboard$KeyboardData;");
+ s_software_keyboard_class, "executeNormal",
+ "(Lorg/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)Lorg/yuzu/yuzu_emu/"
+ "applets/keyboard/SoftwareKeyboard$KeyboardData;");
s_swkbd_execute_inline =
- env->GetStaticMethodID(s_software_keyboard_class, "ExecuteInline",
- "(Lorg/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig;)V");
+ env->GetStaticMethodID(s_software_keyboard_class, "executeInline",
+ "(Lorg/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)V");
}
void CleanupJNI(JNIEnv* env) {
diff --git a/src/android/app/src/main/res/layout/dialog_edit_text.xml b/src/android/app/src/main/res/layout/dialog_edit_text.xml
new file mode 100644
index 000000000..58b905d71
--- /dev/null
+++ b/src/android/app/src/main/res/layout/dialog_edit_text.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/edit_text_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="24dp"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/edit_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="none" />
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>