summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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() {
83 } 83 }
84 84
85 override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { 85 override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
86 if (event.action == android.view.KeyEvent.ACTION_DOWN) { 86 if (event.action == KeyEvent.ACTION_DOWN) {
87 if (keyCode == android.view.KeyEvent.KEYCODE_ENTER) { 87 if (keyCode == KeyEvent.KEYCODE_ENTER) {
88 // Special case, we do not support multiline input, dismiss the keyboard. 88 // Special case, we do not support multiline input, dismiss the keyboard.
89 val overlayView: View = 89 val overlayView: View =
90 this.findViewById<View>(R.id.surface_input_overlay) 90 this.findViewById(R.id.surface_input_overlay)
91 val im = 91 val im =
92 overlayView.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager 92 overlayView.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
93 im.hideSoftInputFromWindow(overlayView.windowToken, 0); 93 im.hideSoftInputFromWindow(overlayView.windowToken, 0)
94 } else { 94 } else {
95 val textChar = event.getUnicodeChar(); 95 val textChar = event.unicodeChar
96 if (textChar == 0) { 96 if (textChar == 0) {
97 // No text, button input. 97 // No text, button input.
98 NativeLibrary.SubmitInlineKeyboardInput(keyCode); 98 NativeLibrary.SubmitInlineKeyboardInput(keyCode)
99 } else { 99 } else {
100 // Text submitted. 100 // Text submitted.
101 NativeLibrary.SubmitInlineKeyboardText(textChar.toChar().toString()); 101 NativeLibrary.SubmitInlineKeyboardText(textChar.toChar().toString())
102 } 102 }
103 } 103 }
104 } 104 }
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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.applets;
5
6import android.app.Activity;
7import android.app.Dialog;
8import android.content.Context;
9import android.content.DialogInterface;
10import android.graphics.Rect;
11import android.os.Bundle;
12import android.os.Handler;
13import android.os.ResultReceiver;
14import android.text.InputFilter;
15import android.text.InputType;
16import android.view.ViewGroup;
17import android.view.ViewTreeObserver;
18import android.view.WindowInsets;
19import android.view.inputmethod.InputMethodManager;
20import android.widget.EditText;
21import android.widget.FrameLayout;
22
23import androidx.annotation.NonNull;
24import androidx.appcompat.app.AlertDialog;
25import androidx.core.view.ViewCompat;
26import androidx.fragment.app.DialogFragment;
27
28import com.google.android.material.dialog.MaterialAlertDialogBuilder;
29
30import org.yuzu.yuzu_emu.YuzuApplication;
31import org.yuzu.yuzu_emu.NativeLibrary;
32import org.yuzu.yuzu_emu.R;
33import org.yuzu.yuzu_emu.activities.EmulationActivity;
34
35import java.util.Objects;
36
37public final class SoftwareKeyboard {
38 /// Corresponds to Service::AM::Applets::SwkbdType
39 private interface SwkbdType {
40 int Normal = 0;
41 int NumberPad = 1;
42 int Qwerty = 2;
43 int Unknown3 = 3;
44 int Latin = 4;
45 int SimplifiedChinese = 5;
46 int TraditionalChinese = 6;
47 int Korean = 7;
48 };
49
50 /// Corresponds to Service::AM::Applets::SwkbdPasswordMode
51 private interface SwkbdPasswordMode {
52 int Disabled = 0;
53 int Enabled = 1;
54 };
55
56 /// Corresponds to Service::AM::Applets::SwkbdResult
57 private interface SwkbdResult {
58 int Ok = 0;
59 int Cancel = 1;
60 };
61
62 public static class KeyboardConfig implements java.io.Serializable {
63 public String ok_text;
64 public String header_text;
65 public String sub_text;
66 public String guide_text;
67 public String initial_text;
68 public short left_optional_symbol_key;
69 public short right_optional_symbol_key;
70 public int max_text_length;
71 public int min_text_length;
72 public int initial_cursor_position;
73 public int type;
74 public int password_mode;
75 public int text_draw_type;
76 public int key_disable_flags;
77 public boolean use_blur_background;
78 public boolean enable_backspace_button;
79 public boolean enable_return_button;
80 public boolean disable_cancel_button;
81 }
82
83 /// Corresponds to Frontend::KeyboardData
84 public static class KeyboardData {
85 public int result;
86 public String text;
87
88 private KeyboardData(int result, String text) {
89 this.result = result;
90 this.text = text;
91 }
92 }
93
94 public static class KeyboardDialogFragment extends DialogFragment {
95 static KeyboardDialogFragment newInstance(KeyboardConfig config) {
96 KeyboardDialogFragment frag = new KeyboardDialogFragment();
97 Bundle args = new Bundle();
98 args.putSerializable("config", config);
99 frag.setArguments(args);
100 return frag;
101 }
102
103 @NonNull
104 @Override
105 public Dialog onCreateDialog(Bundle savedInstanceState) {
106 final Activity emulationActivity = getActivity();
107 assert emulationActivity != null;
108
109 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
110 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
111 params.leftMargin = params.rightMargin =
112 YuzuApplication.getAppContext().getResources().getDimensionPixelSize(
113 R.dimen.dialog_margin);
114
115 KeyboardConfig config = Objects.requireNonNull(
116 (KeyboardConfig) requireArguments().getSerializable("config"));
117
118 // Set up the input
119 EditText editText = new EditText(YuzuApplication.getAppContext());
120 editText.setHint(config.initial_text);
121 editText.setSingleLine(!config.enable_return_button);
122 editText.setLayoutParams(params);
123 editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(config.max_text_length)});
124
125 // Handle input type
126 int input_type = 0;
127 switch (config.type)
128 {
129 case SwkbdType.Normal:
130 case SwkbdType.Qwerty:
131 case SwkbdType.Unknown3:
132 case SwkbdType.Latin:
133 case SwkbdType.SimplifiedChinese:
134 case SwkbdType.TraditionalChinese:
135 case SwkbdType.Korean:
136 default:
137 input_type = InputType.TYPE_CLASS_TEXT;
138 if (config.password_mode == SwkbdPasswordMode.Enabled)
139 {
140 input_type |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
141 }
142 break;
143 case SwkbdType.NumberPad:
144 input_type = InputType.TYPE_CLASS_NUMBER;
145 if (config.password_mode == SwkbdPasswordMode.Enabled)
146 {
147 input_type |= InputType.TYPE_NUMBER_VARIATION_PASSWORD;
148 }
149 break;
150 }
151
152 // Apply input type
153 editText.setInputType(input_type);
154
155 FrameLayout container = new FrameLayout(emulationActivity);
156 container.addView(editText);
157
158 String headerText = config.header_text.isEmpty() ? emulationActivity.getString(R.string.software_keyboard) : config.header_text;
159 String okText = config.header_text.isEmpty() ? emulationActivity.getString(android.R.string.ok) : config.ok_text;
160
161 MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(emulationActivity)
162 .setTitle(headerText)
163 .setView(container);
164 setCancelable(false);
165
166 builder.setPositiveButton(okText, null);
167 builder.setNegativeButton(emulationActivity.getString(android.R.string.cancel), null);
168
169 final AlertDialog dialog = builder.create();
170 dialog.create();
171 if (dialog.getButton(DialogInterface.BUTTON_POSITIVE) != null) {
172 dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener((view) -> {
173 data.result = SwkbdResult.Ok;
174 data.text = editText.getText().toString();
175 dialog.dismiss();
176
177 synchronized (finishLock) {
178 finishLock.notifyAll();
179 }
180 });
181 }
182 if (dialog.getButton(DialogInterface.BUTTON_NEUTRAL) != null) {
183 dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener((view) -> {
184 data.result = SwkbdResult.Ok;
185 dialog.dismiss();
186 synchronized (finishLock) {
187 finishLock.notifyAll();
188 }
189 });
190 }
191 if (dialog.getButton(DialogInterface.BUTTON_NEGATIVE) != null) {
192 dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener((view) -> {
193 data.result = SwkbdResult.Cancel;
194 dialog.dismiss();
195 synchronized (finishLock) {
196 finishLock.notifyAll();
197 }
198 });
199 }
200
201 return dialog;
202 }
203 }
204
205 private static KeyboardData data;
206 private static final Object finishLock = new Object();
207
208 private static void ExecuteNormalImpl(KeyboardConfig config) {
209 final EmulationActivity emulationActivity = NativeLibrary.sEmulationActivity.get();
210
211 data = new KeyboardData(SwkbdResult.Cancel, "");
212
213 KeyboardDialogFragment fragment = KeyboardDialogFragment.newInstance(config);
214 fragment.show(emulationActivity.getSupportFragmentManager(), "keyboard");
215 }
216
217 private static void ExecuteInlineImpl(KeyboardConfig config) {
218 final EmulationActivity emulationActivity = NativeLibrary.sEmulationActivity.get();
219
220 var overlayView = emulationActivity.findViewById(R.id.surface_input_overlay);
221 InputMethodManager im = (InputMethodManager)overlayView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
222 im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED);
223
224 // There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
225 final Handler handler = new Handler();
226 final int delayMs = 500;
227 handler.postDelayed(new Runnable() {
228 public void run() {
229 var insets = ViewCompat.getRootWindowInsets(overlayView);
230 var isKeyboardVisible = insets.isVisible(WindowInsets.Type.ime());
231 if (isKeyboardVisible) {
232 handler.postDelayed(this, delayMs);
233 return;
234 }
235
236 // No longer visible, submit the result.
237 NativeLibrary.SubmitInlineKeyboardInput(android.view.KeyEvent.KEYCODE_ENTER);
238 }
239 }, delayMs);
240 }
241
242 public static KeyboardData ExecuteNormal(KeyboardConfig config) {
243 NativeLibrary.sEmulationActivity.get().runOnUiThread(() -> ExecuteNormalImpl(config));
244
245 synchronized (finishLock) {
246 try {
247 finishLock.wait();
248 } catch (Exception ignored) {
249 }
250 }
251
252 return data;
253 }
254
255 public static void ExecuteInline(KeyboardConfig config) {
256 NativeLibrary.sEmulationActivity.get().runOnUiThread(() -> ExecuteInlineImpl(config));
257 }
258
259 public static void ShowError(String error) {
260 NativeLibrary.displayAlertMsg(
261 YuzuApplication.getAppContext().getResources().getString(R.string.software_keyboard),
262 error, false);
263 }
264}
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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.applets.keyboard
5
6import android.content.Context
7import android.os.Handler
8import android.os.Looper
9import android.view.KeyEvent
10import android.view.View
11import android.view.WindowInsets
12import android.view.inputmethod.InputMethodManager
13import androidx.core.view.ViewCompat
14import org.yuzu.yuzu_emu.NativeLibrary
15import org.yuzu.yuzu_emu.R
16import org.yuzu.yuzu_emu.applets.keyboard.ui.KeyboardDialogFragment
17import java.io.Serializable
18
19object SoftwareKeyboard {
20 lateinit var data: KeyboardData
21 val dataLock = Object()
22
23 private fun executeNormalImpl(config: KeyboardConfig) {
24 val emulationActivity = NativeLibrary.sEmulationActivity.get()
25 data = KeyboardData(SwkbdResult.Cancel.ordinal, "")
26 val fragment = KeyboardDialogFragment.newInstance(config)
27 fragment.show(emulationActivity!!.supportFragmentManager, KeyboardDialogFragment.TAG)
28 }
29
30 private fun executeInlineImpl(config: KeyboardConfig) {
31 val emulationActivity = NativeLibrary.sEmulationActivity.get()
32
33 val overlayView = emulationActivity!!.findViewById<View>(R.id.surface_input_overlay)
34 val im =
35 overlayView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
36 im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED)
37
38 // There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
39 val handler = Handler(Looper.myLooper()!!)
40 val delayMs = 500
41 handler.postDelayed(object : Runnable {
42 override fun run() {
43 val insets = ViewCompat.getRootWindowInsets(overlayView)
44 val isKeyboardVisible = insets!!.isVisible(WindowInsets.Type.ime())
45 if (isKeyboardVisible) {
46 handler.postDelayed(this, delayMs.toLong())
47 return
48 }
49
50 // No longer visible, submit the result.
51 NativeLibrary.SubmitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
52 }
53 }, delayMs.toLong())
54 }
55
56 @JvmStatic
57 fun executeNormal(config: KeyboardConfig): KeyboardData {
58 NativeLibrary.sEmulationActivity.get()!!.runOnUiThread { executeNormalImpl(config) }
59 synchronized(dataLock) {
60 dataLock.wait()
61 }
62 return data
63 }
64
65 @JvmStatic
66 fun executeInline(config: KeyboardConfig) {
67 NativeLibrary.sEmulationActivity.get()!!.runOnUiThread { executeInlineImpl(config) }
68 }
69
70 // Corresponds to Service::AM::Applets::SwkbdType
71 enum class SwkbdType {
72 Normal,
73 NumberPad,
74 Qwerty,
75 Unknown3,
76 Latin,
77 SimplifiedChinese,
78 TraditionalChinese,
79 Korean
80 }
81
82 // Corresponds to Service::AM::Applets::SwkbdPasswordMode
83 enum class SwkbdPasswordMode {
84 Disabled,
85 Enabled
86 }
87
88 // Corresponds to Service::AM::Applets::SwkbdResult
89 enum class SwkbdResult {
90 Ok,
91 Cancel
92 }
93
94 data class KeyboardConfig(
95 var ok_text: String? = null,
96 var header_text: String? = null,
97 var sub_text: String? = null,
98 var guide_text: String? = null,
99 var initial_text: String? = null,
100 var left_optional_symbol_key: Short = 0,
101 var right_optional_symbol_key: Short = 0,
102 var max_text_length: Int = 0,
103 var min_text_length: Int = 0,
104 var initial_cursor_position: Int = 0,
105 var type: Int = 0,
106 var password_mode: Int = 0,
107 var text_draw_type: Int = 0,
108 var key_disable_flags: Int = 0,
109 var use_blur_background: Boolean = false,
110 var enable_backspace_button: Boolean = false,
111 var enable_return_button: Boolean = false,
112 var disable_cancel_button: Boolean = false
113 ) : Serializable
114
115 // Corresponds to Frontend::KeyboardData
116 data class KeyboardData(var result: Int, var text: String)
117}
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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.applets.keyboard.ui
5
6import android.app.Dialog
7import android.content.DialogInterface
8import android.os.Bundle
9import android.text.InputFilter
10import android.text.InputType
11import androidx.fragment.app.DialogFragment
12import com.google.android.material.dialog.MaterialAlertDialogBuilder
13import org.yuzu.yuzu_emu.R
14import org.yuzu.yuzu_emu.applets.keyboard.SoftwareKeyboard
15import org.yuzu.yuzu_emu.applets.keyboard.SoftwareKeyboard.KeyboardConfig
16import org.yuzu.yuzu_emu.databinding.DialogEditTextBinding
17import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable
18
19class KeyboardDialogFragment : DialogFragment() {
20 private lateinit var binding: DialogEditTextBinding
21 private lateinit var config: KeyboardConfig
22
23 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
24 binding = DialogEditTextBinding.inflate(layoutInflater)
25 config = requireArguments().serializable(CONFIG)!!
26
27 // Set up the input
28 binding.editText.hint = config.initial_text
29 binding.editText.isSingleLine = !config.enable_return_button
30 binding.editText.filters =
31 arrayOf<InputFilter>(InputFilter.LengthFilter(config.max_text_length))
32
33 // Handle input type
34 var inputType: Int
35 when (config.type) {
36 SoftwareKeyboard.SwkbdType.Normal.ordinal,
37 SoftwareKeyboard.SwkbdType.Qwerty.ordinal,
38 SoftwareKeyboard.SwkbdType.Unknown3.ordinal,
39 SoftwareKeyboard.SwkbdType.Latin.ordinal,
40 SoftwareKeyboard.SwkbdType.SimplifiedChinese.ordinal,
41 SoftwareKeyboard.SwkbdType.TraditionalChinese.ordinal,
42 SoftwareKeyboard.SwkbdType.Korean.ordinal -> {
43 inputType = InputType.TYPE_CLASS_TEXT
44 if (config.password_mode == SoftwareKeyboard.SwkbdPasswordMode.Enabled.ordinal) {
45 inputType = inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
46 }
47 }
48 SoftwareKeyboard.SwkbdType.NumberPad.ordinal -> {
49 inputType = InputType.TYPE_CLASS_NUMBER
50 if (config.password_mode == SoftwareKeyboard.SwkbdPasswordMode.Enabled.ordinal) {
51 inputType = inputType or InputType.TYPE_NUMBER_VARIATION_PASSWORD
52 }
53 }
54 else -> {
55 inputType = InputType.TYPE_CLASS_TEXT
56 if (config.password_mode == SoftwareKeyboard.SwkbdPasswordMode.Enabled.ordinal) {
57 inputType = inputType or InputType.TYPE_TEXT_VARIATION_PASSWORD
58 }
59 }
60 }
61 binding.editText.inputType = inputType
62
63 val headerText =
64 config.header_text!!.ifEmpty { resources.getString(R.string.software_keyboard) }
65 val okText =
66 if (config.header_text!!.isEmpty()) resources.getString(android.R.string.ok) else config.ok_text!!
67
68 return MaterialAlertDialogBuilder(requireContext())
69 .setTitle(headerText)
70 .setView(binding.root)
71 .setPositiveButton(okText) { _, _ ->
72 SoftwareKeyboard.data.result = SoftwareKeyboard.SwkbdResult.Ok.ordinal
73 SoftwareKeyboard.data.text = binding.editText.text.toString()
74 }
75 .setNegativeButton(resources.getString(android.R.string.cancel)) { _, _ ->
76 SoftwareKeyboard.data.result = SoftwareKeyboard.SwkbdResult.Cancel.ordinal
77 }
78 .create()
79 }
80
81 override fun onDismiss(dialog: DialogInterface) {
82 super.onDismiss(dialog)
83 synchronized(SoftwareKeyboard.dataLock) {
84 SoftwareKeyboard.dataLock.notifyAll()
85 }
86 }
87
88 companion object {
89 const val TAG = "KeyboardDialogFragment"
90 const val CONFIG = "keyboard_config"
91
92 fun newInstance(config: KeyboardConfig?): KeyboardDialogFragment {
93 val frag = KeyboardDialogFragment()
94 val args = Bundle()
95 args.putSerializable(CONFIG, config)
96 frag.arguments = args
97 return frag
98 }
99 }
100}
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 {
253 253
254void InitJNI(JNIEnv* env) { 254void InitJNI(JNIEnv* env) {
255 s_software_keyboard_class = reinterpret_cast<jclass>( 255 s_software_keyboard_class = reinterpret_cast<jclass>(
256 env->NewGlobalRef(env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard"))); 256 env->NewGlobalRef(env->FindClass("org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard")));
257 s_keyboard_config_class = reinterpret_cast<jclass>(env->NewGlobalRef( 257 s_keyboard_config_class = reinterpret_cast<jclass>(env->NewGlobalRef(
258 env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig"))); 258 env->FindClass("org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig")));
259 s_keyboard_data_class = reinterpret_cast<jclass>(env->NewGlobalRef( 259 s_keyboard_data_class = reinterpret_cast<jclass>(env->NewGlobalRef(
260 env->FindClass("org/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardData"))); 260 env->FindClass("org/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardData")));
261 261
262 s_swkbd_execute_normal = env->GetStaticMethodID( 262 s_swkbd_execute_normal = env->GetStaticMethodID(
263 s_software_keyboard_class, "ExecuteNormal", 263 s_software_keyboard_class, "executeNormal",
264 "(Lorg/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig;)Lorg/yuzu/yuzu_emu/" 264 "(Lorg/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)Lorg/yuzu/yuzu_emu/"
265 "applets/SoftwareKeyboard$KeyboardData;"); 265 "applets/keyboard/SoftwareKeyboard$KeyboardData;");
266 s_swkbd_execute_inline = 266 s_swkbd_execute_inline =
267 env->GetStaticMethodID(s_software_keyboard_class, "ExecuteInline", 267 env->GetStaticMethodID(s_software_keyboard_class, "executeInline",
268 "(Lorg/yuzu/yuzu_emu/applets/SoftwareKeyboard$KeyboardConfig;)V"); 268 "(Lorg/yuzu/yuzu_emu/applets/keyboard/SoftwareKeyboard$KeyboardConfig;)V");
269} 269}
270 270
271void CleanupJNI(JNIEnv* env) { 271void 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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<androidx.constraintlayout.widget.ConstraintLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 xmlns:app="http://schemas.android.com/apk/res-auto"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent">
7
8 <com.google.android.material.textfield.TextInputLayout
9 android:id="@+id/edit_text_layout"
10 android:layout_width="match_parent"
11 android:layout_height="wrap_content"
12 android:layout_margin="24dp"
13 app:layout_constraintTop_toTopOf="parent">
14
15 <com.google.android.material.textfield.TextInputEditText
16 android:id="@+id/edit_text"
17 android:layout_width="match_parent"
18 android:layout_height="wrap_content"
19 android:inputType="none" />
20
21 </com.google.android.material.textfield.TextInputLayout>
22
23</androidx.constraintlayout.widget.ConstraintLayout>