Prevent copying text to non focused widget in STK.

It can happen if user uses the arrows in hacker keyboard to change
widget focus
This commit is contained in:
Benau 2019-05-27 11:09:28 +08:00
parent 9b94437cac
commit febad27342
6 changed files with 28 additions and 19 deletions

View File

@ -18,15 +18,20 @@ public class STKEditText extends EditText
private int m_composing_end; 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; STKInputConnection m_stk_input_connection;
/* Used to avoid infinite calling updateSTKEditBox if setText currently /* Used to avoid infinite calling updateSTKEditBox if setText currently
* by jni. */ * by jni. */
private boolean m_from_stk_editbox; private boolean m_from_stk_editbox;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
private native static void editText2STKEditbox(String full_text, int start, private native static void editText2STKEditbox(int widget_id,
int end, int composing_start, String full_text, int start,
int composing_end); int end,
int composing_start,
int composing_end);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
public STKEditText(Context context) public STKEditText(Context context)
{ {
@ -34,6 +39,7 @@ public class STKEditText extends EditText
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
m_composing_start = 0; m_composing_start = 0;
m_composing_end = 0; m_composing_end = 0;
m_stk_widget_id = -1;
m_from_stk_editbox = false; m_from_stk_editbox = false;
m_stk_input_connection = null; m_stk_input_connection = null;
} }
@ -77,8 +83,9 @@ public class STKEditText extends EditText
{ {
if (!isFocused() || m_from_stk_editbox) if (!isFocused() || m_from_stk_editbox)
return; return;
editText2STKEditbox(getText().toString(), getSelectionStart(), editText2STKEditbox(m_stk_widget_id, getText().toString(),
getSelectionEnd(), m_composing_start, m_composing_end); getSelectionStart(), getSelectionEnd(), m_composing_start,
m_composing_end);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
public void beforeHideKeyboard() 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 /* Called by STK with JNI to set this view with new text (like user focus
* a new editbox in stk, or change cursor / selection). */ * a new editbox in stk, or change cursor / selection). */
public void setTextFromSTK(final String text, int selection_start, public void setTextFromSTK(int widget_id, final String text,
int selection_end) 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 // Avoid sending the newly set text back to STK at the same time
m_from_stk_editbox = true; m_from_stk_editbox = true;
try try

View File

@ -180,8 +180,9 @@ public class SuperTuxKartActivity extends NativeActivity
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/* Called by STK in JNI. */ /* Called by STK in JNI. */
public void fromSTKEditBox(final String text, final int selection_start, public void fromSTKEditBox(final int widget_id, final String text,
final int selection_end) final int selection_start,
final int selection_end)
{ {
runOnUiThread(new Runnable() runOnUiThread(new Runnable()
{ {
@ -190,7 +191,7 @@ public class SuperTuxKartActivity extends NativeActivity
{ {
if (m_stk_edittext == null) if (m_stk_edittext == null)
createSTKEditText(); createSTKEditText();
m_stk_edittext.setTextFromSTK(text, selection_start, m_stk_edittext.setTextFromSTK(widget_id, text, selection_start,
selection_end); selection_end);
} }
}); });

View File

@ -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) if (!Android)
return; return;
@ -1390,7 +1390,7 @@ void CIrrDeviceAndroid::fromSTKEditBox(const core::stringw& text, int selection_
return; 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) if (method_id == NULL)
{ {
os::Printer::log("fromSTKEditBox unable to find method id.", ELL_ERROR); 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); utf8.push_back(0);
jstring jstring_text = env->NewStringUTF(utf8.data()); 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) if (was_detached)
{ {
Android->activity->vm->DetachCurrentThread(); Android->activity->vm->DetachCurrentThread();

View File

@ -73,7 +73,7 @@ namespace irr
virtual bool deactivateGyroscope(); virtual bool deactivateGyroscope();
virtual bool isGyroscopeActive(); virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable(); 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 void toggleOnScreenKeyboard(bool show);
virtual bool supportsTouchDevice() const { return HasTouchDevice; } virtual bool supportsTouchDevice() const { return HasTouchDevice; }
virtual bool hasHardwareKeyboard() const; virtual bool hasHardwareKeyboard() const;

View File

@ -299,7 +299,7 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
{ {
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>( CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice()); irr_driver->getDevice());
dl->fromSTKEditBox(Text, MarkBegin, MarkEnd); dl->fromSTKEditBox(getID(), Text, MarkBegin, MarkEnd);
} }
#endif #endif
} }
@ -1185,7 +1185,7 @@ void CGUIEditBox::setText(const wchar_t* text)
{ {
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>( CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice()); irr_driver->getDevice());
dl->fromSTKEditBox(Text, MarkBegin, MarkEnd); dl->fromSTKEditBox(getID(), Text, MarkBegin, MarkEnd);
} }
#endif #endif
} }
@ -1726,7 +1726,7 @@ void CGUIEditBox::setTextMarkers(s32 begin, s32 end)
{ {
CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>( CIrrDeviceAndroid* dl = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice()); irr_driver->getDevice());
dl->fromSTKEditBox(Text, MarkBegin, MarkEnd); dl->fromSTKEditBox(getID(), Text, MarkBegin, MarkEnd);
} }
#endif #endif
} }

View File

@ -240,14 +240,14 @@ EventPropagation TextBoxWidget::leftPressed (const int playerID)
#error #error
#endif #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) #define ANDROID_EDITTEXT_CALLBACK(PKG_NAME) MAKE_EDITTEXT_CALLBACK(PKG_NAME)
extern "C" extern "C"
ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME) ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
{ {
TextBoxWidget* tb = dynamic_cast<TextBoxWidget*>(getFocusForPlayer(0)); TextBoxWidget* tb = dynamic_cast<TextBoxWidget*>(getFocusForPlayer(0));
if (!tb || text == NULL) if (!tb || (int)widget_id != tb->getID() || text == NULL)
return; return;
const char* utf8_text = env->GetStringUTFChars(text, NULL); const char* utf8_text = env->GetStringUTFChars(text, NULL);