summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2015-12-05 13:23:26 +0100
committerOlivier Goffart (Woboq GmbH) <ogoffart@woboq.com>2015-12-07 16:56:25 +0000
commit420b4dbece04f8015cad24a49622c65c540f0a22 (patch)
tree39a5832ef95a2f24a1275e683b492c5f8d5744ac /src
parent7908da98f01c24bd95a9e7a7f938de697a6a02b6 (diff)
Android: Implement QInputMethod::keyboardRectangle
We can use getWindowVisibleDisplayFrame to know the height on the keyboard, and we can use getLocationOnScreen to find out how much the view is scrolled. Since onPreDraw is always called when the view is scrolled or when the keyboard appears or disapear, we can call the native functions from there. This is not working for floating keyboards. [ChangeLog][Android] Implemented QInputMethod::keyboardRectangle Task-number: QTBUG-40731 Change-Id: I7848eb34fece410b29a06bf0bbb2313112fffa68 Reviewed-by: Samuel Nevala <samuel.nevala@intopalo.com> Reviewed-by: BogDan Vatra <bogdan@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java21
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java1
-rw-r--r--src/gui/kernel/qinputmethod.cpp3
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp32
-rw-r--r--src/plugins/platforms/android/androidjniinput.h2
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp2
6 files changed, 58 insertions, 3 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 445896622a..4575d8a1d3 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -66,6 +66,8 @@ import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
+import android.view.ViewTreeObserver;
+import android.graphics.Rect;
import java.io.BufferedReader;
import java.io.DataOutputStream;
@@ -859,6 +861,25 @@ public class QtActivityDelegate
QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
m_currentRotation = rotation;
+
+ m_layout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ if (!m_keyboardIsVisible)
+ return true;
+
+ Rect r = new Rect();
+ m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
+ DisplayMetrics metrics = new DisplayMetrics();
+ m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+ final int kbHeight = metrics.heightPixels - r.bottom;
+ final int[] location = new int[2];
+ m_layout.getLocationOnScreen(location);
+ QtNative.keyboardGeometryChanged(location[0], r.bottom - location[1],
+ r.width(), kbHeight);
+ return true;
+ }
+ });
}
public void initializeAccessibility()
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 602b25eb45..8880c003e7 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -677,6 +677,7 @@ public class QtNative
public static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat);
public static native void keyUp(int key, int unicode, int modifier, boolean autoRepeat);
public static native void keyboardVisibilityChanged(boolean visibility);
+ public static native void keyboardGeometryChanged(int x, int y, int width, int height);
// keyboard methods
// dispatch events methods
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index 8d51be853a..2684c43518 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -147,6 +147,9 @@ QRectF QInputMethod::cursorRectangle() const
/*!
\property QInputMethod::keyboardRectangle
\brief Virtual keyboard's geometry in window coordinates.
+
+ This might be an empty rectangle if it is not possible to know the geometry
+ of the keyboard. This is the case for a floating keyboard on android.
*/
QRectF QInputMethod::keyboardRectangle() const
{
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 8982787ec9..9cc5e95378 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -51,6 +51,7 @@ namespace QtAndroidInput
static bool m_ignoreMouseEvents = false;
static bool m_softwareKeyboardVisible = false;
+ static QRect m_softwareKeyboardRect;
static QList<QWindowSystemInterface::TouchPoint> m_touchPoints;
@@ -108,6 +109,11 @@ namespace QtAndroidInput
return m_softwareKeyboardVisible;
}
+ QRect softwareKeyboardRect()
+ {
+ return m_softwareKeyboardRect;
+ }
+
static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
{
@@ -734,14 +740,35 @@ namespace QtAndroidInput
static void keyboardVisibilityChanged(JNIEnv */*env*/, jobject /*thiz*/, jboolean visibility)
{
m_softwareKeyboardVisible = visibility;
+ if (!visibility)
+ m_softwareKeyboardRect = QRect();
+
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
- if (inputContext && qGuiApp)
+ if (inputContext && qGuiApp) {
inputContext->emitInputPanelVisibleChanged();
+ if (!visibility)
+ inputContext->emitKeyboardRectChanged();
+ }
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ KEYBOARDVISIBILITYCHANGED" << inputContext;
#endif
}
+ static void keyboardGeometryChanged(JNIEnv */*env*/, jobject /*thiz*/, jint x, jint y, jint w, jint h)
+ {
+ QRect r = QRect(x, y, w, h);
+ if (r == m_softwareKeyboardRect)
+ return;
+ m_softwareKeyboardRect = r;
+ QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
+ if (inputContext && qGuiApp)
+ inputContext->emitKeyboardRectChanged();
+
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ KEYBOARDRECTCHANGED" << m_softwareKeyboardRect;
+#endif
+ }
+
static JNINativeMethod methods[] = {
{"touchBegin","(I)V",(void*)touchBegin},
{"touchAdd","(IIIZIIFF)V",(void*)touchAdd},
@@ -753,7 +780,8 @@ namespace QtAndroidInput
{"tabletEvent", "(IIJIIIFFF)V", (void *)tabletEvent},
{"keyDown", "(IIIZ)V", (void *)keyDown},
{"keyUp", "(IIIZ)V", (void *)keyUp},
- {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged}
+ {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged},
+ {"keyboardGeometryChanged", "(IIII)V", (void *)keyboardGeometryChanged}
};
bool registerNatives(JNIEnv *env)
diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index d737dc9c98..7132d1fc4e 100644
--- a/src/plugins/platforms/android/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
@@ -35,6 +35,7 @@
#define ANDROIDJNIINPUT_H
#include <jni.h>
#include <QtCore/qglobal.h>
+#include <QtCore/QRect>
QT_BEGIN_NAMESPACE
@@ -45,6 +46,7 @@ namespace QtAndroidInput
void resetSoftwareKeyboard();
void hideSoftwareKeyboard();
bool isSoftwareKeyboardVisible();
+ QRect softwareKeyboardRect();
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd);
// Software keyboard support
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index e3ea048e84..0eddb26959 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -512,7 +512,7 @@ void QAndroidInputContext::invokeAction(QInputMethod::Action action, int cursorP
QRectF QAndroidInputContext::keyboardRect() const
{
- return QPlatformInputContext::keyboardRect();
+ return QtAndroidInput::softwareKeyboardRect();
}
bool QAndroidInputContext::isAnimating() const