From febad27342fccd7119641f606ddb952aee412a71 Mon Sep 17 00:00:00 2001 From: Benau Date: Mon, 27 May 2019 11:09:28 +0800 Subject: [PATCH] Prevent copying text to non focused widget in STK. It can happen if user uses the arrows in hacker keyboard to change widget focus --- android/src/main/java/STKEditText.java | 22 +++++++++++++------ .../src/main/java/SuperTuxKartActivity.java | 7 +++--- .../source/Irrlicht/CIrrDeviceAndroid.cpp | 6 ++--- .../source/Irrlicht/CIrrDeviceAndroid.h | 2 +- src/guiengine/widgets/CGUIEditBox.cpp | 6 ++--- src/guiengine/widgets/text_box_widget.cpp | 4 ++-- 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/android/src/main/java/STKEditText.java b/android/src/main/java/STKEditText.java index 1f2be3e09..4752126b1 100644 --- a/android/src/main/java/STKEditText.java +++ b/android/src/main/java/STKEditText.java @@ -18,15 +18,20 @@ public class STKEditText extends EditText private int m_composing_end; + /* Used to prevent copying text to non focused widget in STK. */ + private int m_stk_widget_id; + STKInputConnection m_stk_input_connection; /* Used to avoid infinite calling updateSTKEditBox if setText currently * by jni. */ private boolean m_from_stk_editbox; // ------------------------------------------------------------------------ - private native static void editText2STKEditbox(String full_text, int start, - int end, int composing_start, - int composing_end); + private native static void editText2STKEditbox(int widget_id, + String full_text, int start, + int end, + int composing_start, + int composing_end); // ------------------------------------------------------------------------ public STKEditText(Context context) { @@ -34,6 +39,7 @@ public class STKEditText extends EditText setFocusableInTouchMode(true); m_composing_start = 0; m_composing_end = 0; + m_stk_widget_id = -1; m_from_stk_editbox = false; m_stk_input_connection = null; } @@ -77,8 +83,9 @@ public class STKEditText extends EditText { if (!isFocused() || m_from_stk_editbox) return; - editText2STKEditbox(getText().toString(), getSelectionStart(), - getSelectionEnd(), m_composing_start, m_composing_end); + editText2STKEditbox(m_stk_widget_id, getText().toString(), + getSelectionStart(), getSelectionEnd(), m_composing_start, + m_composing_end); } // ------------------------------------------------------------------------ public void beforeHideKeyboard() @@ -89,9 +96,10 @@ public class STKEditText extends EditText // ------------------------------------------------------------------------ /* Called by STK with JNI to set this view with new text (like user focus * a new editbox in stk, or change cursor / selection). */ - public void setTextFromSTK(final String text, int selection_start, - int selection_end) + public void setTextFromSTK(int widget_id, final String text, + int selection_start, int selection_end) { + m_stk_widget_id = widget_id; // Avoid sending the newly set text back to STK at the same time m_from_stk_editbox = true; try diff --git a/android/src/main/java/SuperTuxKartActivity.java b/android/src/main/java/SuperTuxKartActivity.java index f5be27342..668b72e44 100644 --- a/android/src/main/java/SuperTuxKartActivity.java +++ b/android/src/main/java/SuperTuxKartActivity.java @@ -180,8 +180,9 @@ public class SuperTuxKartActivity extends NativeActivity } // ------------------------------------------------------------------------ /* Called by STK in JNI. */ - public void fromSTKEditBox(final String text, final int selection_start, - final int selection_end) + public void fromSTKEditBox(final int widget_id, final String text, + final int selection_start, + final int selection_end) { runOnUiThread(new Runnable() { @@ -190,7 +191,7 @@ public class SuperTuxKartActivity extends NativeActivity { if (m_stk_edittext == null) createSTKEditText(); - m_stk_edittext.setTextFromSTK(text, selection_start, + m_stk_edittext.setTextFromSTK(widget_id, text, selection_start, selection_end); } }); diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp index e4d7cd748..b22e4c7f6 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp @@ -1352,7 +1352,7 @@ void CIrrDeviceAndroid::toggleOnScreenKeyboard(bool show) } } -void CIrrDeviceAndroid::fromSTKEditBox(const core::stringw& text, int selection_start, int selection_end) +void CIrrDeviceAndroid::fromSTKEditBox(int widget_id, const core::stringw& text, int selection_start, int selection_end) { if (!Android) return; @@ -1390,7 +1390,7 @@ void CIrrDeviceAndroid::fromSTKEditBox(const core::stringw& text, int selection_ return; } - jmethodID method_id = env->GetMethodID(class_native_activity, "fromSTKEditBox", "(Ljava/lang/String;II)V"); + jmethodID method_id = env->GetMethodID(class_native_activity, "fromSTKEditBox", "(ILjava/lang/String;II)V"); if (method_id == NULL) { os::Printer::log("fromSTKEditBox unable to find method id.", ELL_ERROR); @@ -1409,7 +1409,7 @@ void CIrrDeviceAndroid::fromSTKEditBox(const core::stringw& text, int selection_ utf8.push_back(0); jstring jstring_text = env->NewStringUTF(utf8.data()); - env->CallVoidMethod(native_activity, method_id, jstring_text, (jint)selection_start, (jint)selection_end); + env->CallVoidMethod(native_activity, method_id, (jint)widget_id, jstring_text, (jint)selection_start, (jint)selection_end); if (was_detached) { Android->activity->vm->DetachCurrentThread(); diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h index fbf38b2c7..d5173ea25 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h @@ -73,7 +73,7 @@ namespace irr virtual bool deactivateGyroscope(); virtual bool isGyroscopeActive(); virtual bool isGyroscopeAvailable(); - void fromSTKEditBox(const core::stringw& text, int selection_start, int selection_end); + void fromSTKEditBox(int widget_id, const core::stringw& text, int selection_start, int selection_end); virtual void toggleOnScreenKeyboard(bool show); virtual bool supportsTouchDevice() const { return HasTouchDevice; } virtual bool hasHardwareKeyboard() const; diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index ea0d0aec3..1f3428a72 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -299,7 +299,7 @@ bool CGUIEditBox::OnEvent(const SEvent& event) { CIrrDeviceAndroid* dl = dynamic_cast( irr_driver->getDevice()); - dl->fromSTKEditBox(Text, MarkBegin, MarkEnd); + dl->fromSTKEditBox(getID(), Text, MarkBegin, MarkEnd); } #endif } @@ -1185,7 +1185,7 @@ void CGUIEditBox::setText(const wchar_t* text) { CIrrDeviceAndroid* dl = dynamic_cast( irr_driver->getDevice()); - dl->fromSTKEditBox(Text, MarkBegin, MarkEnd); + dl->fromSTKEditBox(getID(), Text, MarkBegin, MarkEnd); } #endif } @@ -1726,7 +1726,7 @@ void CGUIEditBox::setTextMarkers(s32 begin, s32 end) { CIrrDeviceAndroid* dl = dynamic_cast( irr_driver->getDevice()); - dl->fromSTKEditBox(Text, MarkBegin, MarkEnd); + dl->fromSTKEditBox(getID(), Text, MarkBegin, MarkEnd); } #endif } diff --git a/src/guiengine/widgets/text_box_widget.cpp b/src/guiengine/widgets/text_box_widget.cpp index 2a992e8e4..42dd57353 100644 --- a/src/guiengine/widgets/text_box_widget.cpp +++ b/src/guiengine/widgets/text_box_widget.cpp @@ -240,14 +240,14 @@ EventPropagation TextBoxWidget::leftPressed (const int playerID) #error #endif -#define MAKE_EDITTEXT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_STKEditText_editText2STKEditbox(JNIEnv* env, jobject this_obj, jstring text, jint start, jint end, jint composing_start, jint composing_end) +#define MAKE_EDITTEXT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_STKEditText_editText2STKEditbox(JNIEnv* env, jobject this_obj, jint widget_id, jstring text, jint start, jint end, jint composing_start, jint composing_end) #define ANDROID_EDITTEXT_CALLBACK(PKG_NAME) MAKE_EDITTEXT_CALLBACK(PKG_NAME) extern "C" ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME) { TextBoxWidget* tb = dynamic_cast(getFocusForPlayer(0)); - if (!tb || text == NULL) + if (!tb || (int)widget_id != tb->getID() || text == NULL) return; const char* utf8_text = env->GetStringUTFChars(text, NULL);