Dispatch all key and all generic motion events java objects to QtCore
These events are needed to enable the usage of all input methods available on Android e.g. gamepads, stylus, etc. In orer to get GenericMotionEvents your application min API version must be at least 12, otherwise the application will receive only key events. Change-Id: I7564fccaf5423aa318ba4f62317eaf101ba6e97e Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
This commit is contained in:
parent
4f7e0bdc4c
commit
3674718e3d
@ -59,6 +59,7 @@ import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
@ -89,6 +90,7 @@ public class QtActivityDelegate
|
||||
private Method m_super_onKeyUp = null;
|
||||
private Method m_super_onConfigurationChanged = null;
|
||||
private Method m_super_onActivityResult = null;
|
||||
private Method m_super_dispatchGenericMotionEvent = null;
|
||||
|
||||
private static final String NATIVE_LIBRARIES_KEY = "native.libraries";
|
||||
private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
|
||||
@ -475,6 +477,13 @@ public class QtActivityDelegate
|
||||
m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
|
||||
m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class);
|
||||
m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class);
|
||||
if (Build.VERSION.SDK_INT >= 12) {
|
||||
try {
|
||||
m_super_dispatchGenericMotionEvent = m_activity.getClass().getMethod("super_dispatchGenericMotionEvent", MotionEvent.class);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
@ -1043,6 +1052,9 @@ public class QtActivityDelegate
|
||||
QtNative.keyUp(0, event.getCharacters().charAt(0), event.getMetaState(), event.getRepeatCount() > 0);
|
||||
}
|
||||
|
||||
if (QtNative.dispatchKeyEvent(event))
|
||||
return true;
|
||||
|
||||
try {
|
||||
return (Boolean) m_super_dispatchKeyEvent.invoke(m_activity, event);
|
||||
} catch (Exception e) {
|
||||
@ -1311,4 +1323,17 @@ public class QtActivityDelegate
|
||||
m_layout.moveChild(view, index);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean dispatchGenericMotionEvent (MotionEvent ev)
|
||||
{
|
||||
if (m_started && QtNative.dispatchGenericMotionEvent(ev))
|
||||
return true;
|
||||
|
||||
try {
|
||||
return (Boolean) m_super_dispatchGenericMotionEvent.invoke(m_activity, ev);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import android.text.ClipboardManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -633,6 +634,11 @@ public class QtNative
|
||||
public static native void keyboardVisibilityChanged(boolean visibility);
|
||||
// keyboard methods
|
||||
|
||||
// dispatch events methods
|
||||
public static native boolean dispatchGenericMotionEvent(MotionEvent ev);
|
||||
public static native boolean dispatchKeyEvent(KeyEvent event);
|
||||
// dispatch events methods
|
||||
|
||||
// surface methods
|
||||
public static native void setSurface(int id, Object surface, int w, int h);
|
||||
// surface methods
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "qjnihelpers_p.h"
|
||||
#include "qmutex.h"
|
||||
#include "qlist.h"
|
||||
#include "qvector.h"
|
||||
#include <QtCore/qrunnable.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -56,6 +57,40 @@ static void onAndroidUiThread(JNIEnv *, jclass, jlong thiz)
|
||||
delete runnable;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct GenericMotionEventListeners {
|
||||
QMutex mutex;
|
||||
QVector<QtAndroidPrivate::GenericMotionEventListener *> listeners;
|
||||
};
|
||||
}
|
||||
Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
|
||||
|
||||
static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event)
|
||||
{
|
||||
jboolean ret = JNI_FALSE;
|
||||
QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
|
||||
foreach (auto listener, g_genericMotionEventListeners()->listeners)
|
||||
ret |= listener->handleGenericMotionEvent(event);
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct KeyEventListeners {
|
||||
QMutex mutex;
|
||||
QVector<QtAndroidPrivate::KeyEventListener *> listeners;
|
||||
};
|
||||
}
|
||||
Q_GLOBAL_STATIC(KeyEventListeners, g_keyEventListeners)
|
||||
|
||||
static jboolean dispatchKeyEvent(JNIEnv *, jclass, jobject event)
|
||||
{
|
||||
jboolean ret = JNI_FALSE;
|
||||
QMutexLocker locker(&g_keyEventListeners()->mutex);
|
||||
foreach (auto listener, g_keyEventListeners()->listeners)
|
||||
ret |= listener->handleKeyEvent(event);
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class ActivityResultListeners
|
||||
{
|
||||
@ -227,7 +262,9 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
|
||||
g_javaVM = vm;
|
||||
|
||||
static const JNINativeMethod methods[] = {
|
||||
{"onAndroidUiThread", "(J)V", reinterpret_cast<void *>(onAndroidUiThread)}
|
||||
{"onAndroidUiThread", "(J)V", reinterpret_cast<void *>(onAndroidUiThread)},
|
||||
{"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast<void *>(dispatchGenericMotionEvent)},
|
||||
{"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast<void *>(dispatchKeyEvent)},
|
||||
};
|
||||
|
||||
const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
|
||||
@ -274,4 +311,28 @@ void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env)
|
||||
delete runnable;
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
|
||||
{
|
||||
QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
|
||||
g_genericMotionEventListeners()->listeners.push_back(listener);
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::unregisterGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
|
||||
{
|
||||
QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
|
||||
g_genericMotionEventListeners()->listeners.removeOne(listener);
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::registerKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
|
||||
{
|
||||
QMutexLocker locker(&g_keyEventListeners()->mutex);
|
||||
g_keyEventListeners()->listeners.push_back(listener);
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventListener *listener)
|
||||
{
|
||||
QMutexLocker locker(&g_keyEventListeners()->mutex);
|
||||
g_keyEventListeners()->listeners.removeOne(listener);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -76,6 +76,20 @@ namespace QtAndroidPrivate
|
||||
virtual void handleResume() {};
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT GenericMotionEventListener
|
||||
{
|
||||
public:
|
||||
virtual ~GenericMotionEventListener() {}
|
||||
virtual bool handleGenericMotionEvent(jobject event) = 0;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT KeyEventListener
|
||||
{
|
||||
public:
|
||||
virtual ~KeyEventListener() {}
|
||||
virtual bool handleKeyEvent(jobject event) = 0;
|
||||
};
|
||||
|
||||
Q_CORE_EXPORT jobject activity();
|
||||
Q_CORE_EXPORT JavaVM *javaVM();
|
||||
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
|
||||
@ -95,6 +109,12 @@ namespace QtAndroidPrivate
|
||||
Q_CORE_EXPORT void handleResume();
|
||||
Q_CORE_EXPORT void registerResumePauseListener(ResumePauseListener *listener);
|
||||
Q_CORE_EXPORT void unregisterResumePauseListener(ResumePauseListener *listener);
|
||||
|
||||
Q_CORE_EXPORT void registerGenericMotionEventListener(GenericMotionEventListener *listener);
|
||||
Q_CORE_EXPORT void unregisterGenericMotionEventListener(GenericMotionEventListener *listener);
|
||||
|
||||
Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener);
|
||||
Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user