|
@@ -23,9 +23,6 @@ import android.os.Build;
|
|
|
import android.os.Bundle;
|
|
|
import android.os.Handler;
|
|
|
import android.os.Message;
|
|
|
-import android.text.Editable;
|
|
|
-import android.text.InputType;
|
|
|
-import android.text.Selection;
|
|
|
import android.util.DisplayMetrics;
|
|
|
import android.util.Log;
|
|
|
import android.util.SparseArray;
|
|
@@ -39,12 +36,9 @@ import android.view.View;
|
|
|
import android.view.ViewGroup;
|
|
|
import android.view.Window;
|
|
|
import android.view.WindowManager;
|
|
|
-import android.view.inputmethod.BaseInputConnection;
|
|
|
-import android.view.inputmethod.EditorInfo;
|
|
|
import android.view.inputmethod.InputConnection;
|
|
|
import android.view.inputmethod.InputMethodManager;
|
|
|
import android.widget.Button;
|
|
|
-import android.widget.EditText;
|
|
|
import android.widget.LinearLayout;
|
|
|
import android.widget.RelativeLayout;
|
|
|
import android.widget.TextView;
|
|
@@ -210,7 +204,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|
|
// Main components
|
|
|
protected static SDLActivity mSingleton;
|
|
|
protected static SDLSurface mSurface;
|
|
|
- protected static DummyEdit mTextEdit;
|
|
|
+ protected static SDLDummyEdit mTextEdit;
|
|
|
protected static boolean mScreenKeyboardShown;
|
|
|
protected static ViewGroup mLayout;
|
|
|
protected static SDLClipboardHandler mClipboardHandler;
|
|
@@ -1353,7 +1347,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|
|
params.topMargin = y;
|
|
|
|
|
|
if (mTextEdit == null) {
|
|
|
- mTextEdit = new DummyEdit(SDL.getContext());
|
|
|
+ mTextEdit = new SDLDummyEdit(SDL.getContext());
|
|
|
|
|
|
mLayout.addView(mTextEdit, params);
|
|
|
} else {
|
|
@@ -1975,186 +1969,6 @@ class SDLMain implements Runnable {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* This is a fake invisible editor view that receives the input and defines the
|
|
|
- * pan&scan region
|
|
|
- */
|
|
|
-class DummyEdit extends View implements View.OnKeyListener {
|
|
|
- InputConnection ic;
|
|
|
-
|
|
|
- public DummyEdit(Context context) {
|
|
|
- super(context);
|
|
|
- setFocusableInTouchMode(true);
|
|
|
- setFocusable(true);
|
|
|
- setOnKeyListener(this);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean onCheckIsTextEditor() {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean onKey(View v, int keyCode, KeyEvent event) {
|
|
|
- return SDLActivity.handleKeyEvent(v, keyCode, event, ic);
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- @Override
|
|
|
- public boolean onKeyPreIme (int keyCode, KeyEvent event) {
|
|
|
- // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
|
|
|
- // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
|
|
|
- // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
|
|
|
- // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout
|
|
|
- // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
|
|
|
- // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
|
|
|
- if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
|
|
- if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
|
|
|
- SDLActivity.onNativeKeyboardFocusLost();
|
|
|
- }
|
|
|
- }
|
|
|
- return super.onKeyPreIme(keyCode, event);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
|
|
- ic = new SDLInputConnection(this, true);
|
|
|
-
|
|
|
- outAttrs.inputType = InputType.TYPE_CLASS_TEXT |
|
|
|
- InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
|
|
- outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI |
|
|
|
- EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */;
|
|
|
-
|
|
|
- return ic;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-class SDLInputConnection extends BaseInputConnection {
|
|
|
-
|
|
|
- protected EditText mEditText;
|
|
|
- protected String mCommittedText = "";
|
|
|
-
|
|
|
- public SDLInputConnection(View targetView, boolean fullEditor) {
|
|
|
- super(targetView, fullEditor);
|
|
|
- mEditText = new EditText(SDL.getContext());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Editable getEditable() {
|
|
|
- return mEditText.getEditableText();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean sendKeyEvent(KeyEvent event) {
|
|
|
- /*
|
|
|
- * This used to handle the keycodes from soft keyboard (and IME-translated input from hardkeyboard)
|
|
|
- * However, as of Ice Cream Sandwich and later, almost all soft keyboard doesn't generate key presses
|
|
|
- * and so we need to generate them ourselves in commitText. To avoid duplicates on the handful of keys
|
|
|
- * that still do, we empty this out.
|
|
|
- */
|
|
|
-
|
|
|
- /*
|
|
|
- * Return DOES still generate a key event, however. So rather than using it as the 'click a button' key
|
|
|
- * as we do with physical keyboards, let's just use it to hide the keyboard.
|
|
|
- */
|
|
|
-
|
|
|
- if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
|
|
|
- if (SDLActivity.onNativeSoftReturnKey()) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return super.sendKeyEvent(event);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean commitText(CharSequence text, int newCursorPosition) {
|
|
|
- if (!super.commitText(text, newCursorPosition)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- updateText();
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
|
|
- if (!super.setComposingText(text, newCursorPosition)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- updateText();
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
|
|
- if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
|
|
|
- // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
|
|
|
- // and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
|
|
- if (beforeLength > 0 && afterLength == 0) {
|
|
|
- // backspace(s)
|
|
|
- while (beforeLength-- > 0) {
|
|
|
- nativeGenerateScancodeForUnichar('\b');
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!super.deleteSurroundingText(beforeLength, afterLength)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- updateText();
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- protected void updateText() {
|
|
|
- final Editable content = getEditable();
|
|
|
- if (content == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- String text = content.toString();
|
|
|
- int compareLength = Math.min(text.length(), mCommittedText.length());
|
|
|
- int matchLength, offset;
|
|
|
-
|
|
|
- /* Backspace over characters that are no longer in the string */
|
|
|
- for (matchLength = 0; matchLength < compareLength; ) {
|
|
|
- int codePoint = mCommittedText.codePointAt(matchLength);
|
|
|
- if (codePoint != text.codePointAt(matchLength)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- matchLength += Character.charCount(codePoint);
|
|
|
- }
|
|
|
- /* FIXME: This doesn't handle graphemes, like '🌬️' */
|
|
|
- for (offset = matchLength; offset < mCommittedText.length(); ) {
|
|
|
- int codePoint = mCommittedText.codePointAt(offset);
|
|
|
- nativeGenerateScancodeForUnichar('\b');
|
|
|
- offset += Character.charCount(codePoint);
|
|
|
- }
|
|
|
-
|
|
|
- if (matchLength < text.length()) {
|
|
|
- String pendingText = text.subSequence(matchLength, text.length()).toString();
|
|
|
- for (offset = 0; offset < pendingText.length(); ) {
|
|
|
- int codePoint = pendingText.codePointAt(offset);
|
|
|
- if (codePoint == '\n') {
|
|
|
- if (SDLActivity.onNativeSoftReturnKey()) {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- /* Higher code points don't generate simulated scancodes */
|
|
|
- if (codePoint < 128) {
|
|
|
- nativeGenerateScancodeForUnichar((char)codePoint);
|
|
|
- }
|
|
|
- offset += Character.charCount(codePoint);
|
|
|
- }
|
|
|
- SDLInputConnection.nativeCommitText(pendingText, 0);
|
|
|
- }
|
|
|
- mCommittedText = text;
|
|
|
- }
|
|
|
-
|
|
|
- public static native void nativeCommitText(String text, int newCursorPosition);
|
|
|
-
|
|
|
- public static native void nativeGenerateScancodeForUnichar(char c);
|
|
|
-}
|
|
|
-
|
|
|
class SDLClipboardHandler implements
|
|
|
ClipboardManager.OnPrimaryClipChangedListener {
|
|
|
|