diff --git a/modules/juce_core/native/java/JuceAppActivity.java b/modules/juce_core/native/java/JuceAppActivity.java index 547e43c08f..a6299599c5 100644 --- a/modules/juce_core/native/java/JuceAppActivity.java +++ b/modules/juce_core/native/java/JuceAppActivity.java @@ -701,7 +701,8 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$ //============================================================================== private native void handleKeyDown (long host, int keycode, int textchar); private native void handleKeyUp (long host, int keycode, int textchar); - private native void handleBackButton (long host); + private native void handleBackButton (long host); + private native void handleKeyboardHidden (long host); public void showKeyboard (String type) { @@ -712,11 +713,13 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$ if (type.length() > 0) { imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); - imm.setInputMethod (getWindowToken(), type); + imm.setInputMethod (getWindowToken(), type); + keyboardDismissListener.startListening(); } else { - imm.hideSoftInputFromWindow (getWindowToken(), 0); + imm.hideSoftInputFromWindow (getWindowToken(), 0); + keyboardDismissListener.stopListening(); } } } @@ -781,7 +784,48 @@ public class JuceAppActivity extends $$JuceAppActivityBaseClass$$ } return false; - } + } + + //============================================================================== + private final class KeyboardDismissListener + { + public KeyboardDismissListener (ComponentPeerView viewToUse) + { + view = viewToUse; + } + + private void startListening() + { + view.getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserver); + } + + private void stopListening() + { + view.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver); + } + + private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener + { + @Override + public void onGlobalLayout() + { + Rect r = new Rect(); + + view.getWindowVisibleDisplayFrame(r); + + int diff = view.getHeight() - (r.bottom - r.top); + + // Arbitrary threshold, surely keyboard would take more than 20 pix. + if (diff < 20) + handleKeyboardHidden (view.host); + }; + }; + + private ComponentPeerView view; + private TreeObserver viewTreeObserver = new TreeObserver(); + } + + private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener(this); // this is here to make keyboard entry work on a Galaxy Tab2 10.1 @Override diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 07f0a3d37a..77ef17591a 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -551,6 +551,11 @@ public: app->backButtonPressed(); } + void handleKeyboardHiddenCallback() + { + Component::unfocusAllComponents(); + } + void handleAppResumedCallback() { if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) @@ -607,11 +612,16 @@ public: { view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get()); - if (Component* kiosk = Desktop::getInstance().getKioskModeComponent()) - if (kiosk->getPeer() == this) - setNavBarsHidden (navBarsHidden); + // updating the nav bar visibility is a bit odd on Android - need to wait for + if (! isTimerRunning()) + hideNavBarDelayed(); } + void hideNavBarDelayed() + { + startTimer (500); + } + //============================================================================== void handlePaintCallback (JNIEnv* env, jobject canvas, jobject paint) { @@ -786,16 +796,17 @@ AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr; peer->juceMethodInvocation; \ } -JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject /*view*/, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint)) -JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point ((float) x, (float) y), (int64) time)) -JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point ((float) x, (float) y), (int64) time)) -JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point ((float) x, (float) y), (int64) time)) -JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject /*view*/, jlong host), handleMovedOrResized()) -JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject /*view*/, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus)) -JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc)) -JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc)) -JUCE_VIEW_CALLBACK (void, handleBackButton, (JNIEnv* env, jobject /*view*/, jlong host), handleBackButtonCallback()) -JUCE_VIEW_CALLBACK (void, handleAppResumed, (JNIEnv* env, jobject /*view*/, jlong host), handleAppResumedCallback()) +JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject /*view*/, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint)) +JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point ((float) x, (float) y), (int64) time)) +JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point ((float) x, (float) y), (int64) time)) +JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point ((float) x, (float) y), (int64) time)) +JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject /*view*/, jlong host), handleMovedOrResized()) +JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject /*view*/, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus)) +JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc)) +JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc)) +JUCE_VIEW_CALLBACK (void, handleBackButton, (JNIEnv* env, jobject /*view*/, jlong host), handleBackButtonCallback()) +JUCE_VIEW_CALLBACK (void, handleKeyboardHidden, (JNIEnv* env, jobject /*view*/, jlong host), handleKeyboardHiddenCallback()) +JUCE_VIEW_CALLBACK (void, handleAppResumed, (JNIEnv* env, jobject /*view*/, jlong host), handleAppResumedCallback()) //============================================================================== ComponentPeer* Component::createNewPeer (int styleFlags, void*) diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index 08cbc900ae..409991dbb4 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -1242,8 +1242,14 @@ void TextEditor::removeListener (Listener* l) { listeners.remove (l); } void TextEditor::timerCallbackInt() { if (hasKeyboardFocus (false) && ! isCurrentlyBlockedByAnotherModalComponent()) + { wasFocused = true; + if (auto* peer = getPeer()) + if (! isReadOnly()) + peer->textInputRequired (peer->globalToLocal (getScreenPosition()), *this); + } + auto now = Time::getApproximateMillisecondCounter(); if (now > lastTransactionTime + 200) @@ -2062,10 +2068,6 @@ void TextEditor::focusGained (FocusChangeType) repaint(); updateCaretPosition(); - - if (auto* peer = getPeer()) - if (! isReadOnly()) - peer->textInputRequired (peer->globalToLocal (getScreenPosition()), *this); } void TextEditor::focusLost (FocusChangeType)