Android: Detect mouse buttons
The mouseDown() and mouseUp() methods in androidjniinput.cpp hardcoded Qt::LeftButton to all mouse-press / release events. If a mouse is connected to an android device, all three buttons are mapped to the left button. Extend both mehtods' signature by a mouse button state. Add a converter method to map from Android button states to Qt::MouseButtons. Add a sendMouseButtonEvents method, that iterates through all buttons pressed/released and sends the respective events to QWSI. Adapt the mouse handler in java, to obtain and pass the button state to C++. The patch can't be verified in an autotest. Testlib's mouse emulation injects into QWSI. Fixes: QTBUG-99106 Pick-to: 6.6 6.5 6.2 Change-Id: I933f490901928db9761d2ef254ae1e5b4f473f28 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> (cherry picked from commit 8d8cbe87e21f05b7d611ed4be47299977288b267) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
1eb9f165ec
commit
e259e5b9c5
@ -501,8 +501,8 @@ public class QtInputDelegate implements QtInputConnection.QtInputConnectionListe
|
||||
// tablet methods
|
||||
|
||||
// pointer methods
|
||||
public static native void mouseDown(int winId, int x, int y);
|
||||
public static native void mouseUp(int winId, int x, int y);
|
||||
public static native void mouseDown(int winId, int x, int y, int mouseButtonState);
|
||||
public static native void mouseUp(int winId, int x, int y, int mouseButtonState);
|
||||
public static native void mouseMove(int winId, int x, int y);
|
||||
public static native void mouseWheel(int winId, int x, int y, float hDelta, float vDelta);
|
||||
public static native void touchBegin(int winId);
|
||||
@ -618,11 +618,11 @@ public class QtInputDelegate implements QtInputConnection.QtInputConnectionListe
|
||||
{
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_UP:
|
||||
mouseUp(id, (int) event.getX(), (int) event.getY());
|
||||
mouseUp(id, (int) event.getX(), (int) event.getY(), event.getButtonState());
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mouseDown(id, (int) event.getX(), (int) event.getY());
|
||||
mouseDown(id, (int) event.getX(), (int) event.getY(), event.getButtonState());
|
||||
m_oldX = (int) event.getX();
|
||||
m_oldY = (int) event.getY();
|
||||
break;
|
||||
|
@ -28,6 +28,8 @@ Q_DECLARE_JNI_CLASS(QtLayout, "org/qtproject/qt/android/QtLayout")
|
||||
namespace QtAndroidInput
|
||||
{
|
||||
static bool m_ignoreMouseEvents = false;
|
||||
static Qt::MouseButtons m_buttons = Qt::NoButton;
|
||||
|
||||
static QRect m_softwareKeyboardRect;
|
||||
|
||||
static QList<QWindowSystemInterface::TouchPoint> m_touchPoints;
|
||||
@ -160,7 +162,72 @@ namespace QtAndroidInput
|
||||
anchor.x(), anchor.y(), rtl);
|
||||
}
|
||||
|
||||
static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
|
||||
// from https://developer.android.com/reference/android/view/MotionEvent#getButtonState()
|
||||
enum AndroidMouseButton {
|
||||
BUTTON_PRIMARY = 0x00000001,
|
||||
BUTTON_SECONDARY = 0x00000002,
|
||||
BUTTON_TERTIARY = 0x00000004,
|
||||
BUTTON_BACK = 0x00000008,
|
||||
BUTTON_FORWARD = 0x00000010,
|
||||
BUTTON_STYLUS_PRIMARY = 0x00000020,
|
||||
BUTTON_STYLUS_SECONDARY = 0x00000040,
|
||||
};
|
||||
Q_DECLARE_FLAGS(AndroidMouseButtons, AndroidMouseButton)
|
||||
|
||||
static Qt::MouseButtons toMouseButtons(jint j_buttons)
|
||||
{
|
||||
const auto buttons = static_cast<AndroidMouseButtons>(j_buttons);
|
||||
Qt::MouseButtons mouseButtons;
|
||||
if (buttons.testFlag(BUTTON_PRIMARY))
|
||||
mouseButtons.setFlag(Qt::LeftButton);
|
||||
|
||||
if (buttons.testFlag(BUTTON_SECONDARY))
|
||||
mouseButtons.setFlag(Qt::RightButton);
|
||||
|
||||
if (buttons.testFlag(BUTTON_TERTIARY))
|
||||
mouseButtons.setFlag(Qt::MiddleButton);
|
||||
|
||||
if (buttons.testFlag(BUTTON_BACK))
|
||||
mouseButtons.setFlag(Qt::BackButton);
|
||||
|
||||
if (buttons.testFlag(BUTTON_FORWARD))
|
||||
mouseButtons.setFlag(Qt::ForwardButton);
|
||||
|
||||
if (buttons.testFlag(BUTTON_STYLUS_PRIMARY))
|
||||
mouseButtons.setFlag(Qt::LeftButton);
|
||||
|
||||
if (buttons.testFlag(BUTTON_STYLUS_SECONDARY))
|
||||
mouseButtons.setFlag(Qt::RightButton);
|
||||
|
||||
// Fall back to left button
|
||||
if (Q_UNLIKELY(buttons != 0 && mouseButtons == Qt::NoButton)) {
|
||||
qWarning() << "Unhandled button value:" << buttons << "Falling back to Qt::LeftButton";
|
||||
mouseButtons = Qt::LeftButton;
|
||||
}
|
||||
return mouseButtons;
|
||||
}
|
||||
|
||||
static void sendMouseButtonEvents(QWindow *topLevel, QPoint localPos, QPoint globalPos,
|
||||
jint mouseButtonState, QEvent::Type type)
|
||||
{
|
||||
const Qt::MouseButtons mouseButtons = toMouseButtons(mouseButtonState);
|
||||
const Qt::MouseButtons changedButtons = mouseButtons & ~m_buttons;
|
||||
|
||||
if (changedButtons == Qt::NoButton)
|
||||
return;
|
||||
|
||||
static_assert (sizeof(changedButtons) <= sizeof(uint), "Qt::MouseButtons size changed. Adapt code.");
|
||||
|
||||
for (uint buttonInt = 0x1; static_cast<uint>(changedButtons) >= buttonInt; buttonInt <<= 1) {
|
||||
const auto button = static_cast<Qt::MouseButton>(buttonInt);
|
||||
if (changedButtons.testFlag(button)) {
|
||||
QWindowSystemInterface::handleMouseEvent(topLevel, localPos, globalPos,
|
||||
mouseButtons, button, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y, jint mouseButtonState)
|
||||
{
|
||||
if (m_ignoreMouseEvents)
|
||||
return;
|
||||
@ -169,13 +236,11 @@ namespace QtAndroidInput
|
||||
QWindow *window = windowFromId(winId);
|
||||
m_mouseGrabber = window;
|
||||
const QPoint localPos = window && window->handle() ?
|
||||
window->handle()->mapFromGlobal(globalPos) : globalPos;
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
|
||||
Qt::MouseButtons(Qt::LeftButton),
|
||||
Qt::LeftButton, QEvent::MouseButtonPress);
|
||||
window->handle()->mapFromGlobal(globalPos) : globalPos;
|
||||
sendMouseButtonEvents(window, localPos, globalPos, mouseButtonState, QEvent::MouseButtonPress);
|
||||
}
|
||||
|
||||
static void mouseUp(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
|
||||
static void mouseUp(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y, jint mouseButtonState)
|
||||
{
|
||||
const QPoint globalPos(x,y);
|
||||
QWindow *window = m_mouseGrabber.data();
|
||||
@ -184,9 +249,8 @@ namespace QtAndroidInput
|
||||
|
||||
const QPoint localPos = window && window->handle() ?
|
||||
window->handle()->mapFromGlobal(globalPos) : globalPos;
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
|
||||
Qt::MouseButtons(Qt::NoButton),
|
||||
Qt::LeftButton, QEvent::MouseButtonRelease);
|
||||
|
||||
sendMouseButtonEvents(window, localPos, globalPos, mouseButtonState, QEvent::MouseButtonRelease);
|
||||
m_ignoreMouseEvents = false;
|
||||
m_mouseGrabber.clear();
|
||||
}
|
||||
@ -900,8 +964,8 @@ namespace QtAndroidInput
|
||||
{"touchAdd","(IIIZIIFFFF)V",(void*)touchAdd},
|
||||
{"touchEnd","(II)V",(void*)touchEnd},
|
||||
{"touchCancel", "(I)V", (void *)touchCancel},
|
||||
{"mouseDown", "(III)V", (void *)mouseDown},
|
||||
{"mouseUp", "(III)V", (void *)mouseUp},
|
||||
{"mouseDown", "(IIII)V", (void *)mouseDown},
|
||||
{"mouseUp", "(IIII)V", (void *)mouseUp},
|
||||
{"mouseMove", "(III)V", (void *)mouseMove},
|
||||
{"mouseWheel", "(IIIFF)V", (void *)mouseWheel},
|
||||
{"longPress", "(III)V", (void *)longPress},
|
||||
|
Loading…
x
Reference in New Issue
Block a user