summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTinja Paavoseppä <tinja.paavoseppa@qt.io>2023-10-12 09:41:51 +0300
committerSoheil Armin <soheil.armin@qt.io>2023-12-14 00:26:55 +0200
commitb2e44a2d1d1fa109bb2971177a4fda1210637410 (patch)
tree9cade51ddbb6a2c6b75c073bef5cfe9e47e0e1f5
parent4376467169979ce6886d6f58944a2f50dcf77e51 (diff)
Android: Fix touch events for child windows
In the touch dispatcher methods, all events were routed for the top level window at the position, which lead to all the events being delivered for the parent window. Since the JNI methods already have a parameter for window ID, take that into use and determine the window to deliver the events to by ID. Pick-to: 6.7 Change-Id: I07ad7851c32a3e633ee748036d6818b6d0fa5588 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp83
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp15
-rw-r--r--src/plugins/platforms/android/androidjnimain.h1
3 files changed, 62 insertions, 37 deletions
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 0262f69c5c..9ae39269fb 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -160,71 +160,75 @@ namespace QtAndroidInput
anchor.x(), anchor.y(), rtl);
}
- static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
{
if (m_ignoreMouseEvents)
return;
const QPoint globalPos(x,y);
- QWindow *tlw = topLevelWindowAt(globalPos);
- m_mouseGrabber = tlw;
- const QPoint localPos = tlw && tlw->handle() ? tlw->handle()->mapFromGlobal(globalPos) : globalPos;
- QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos,
+ 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);
}
- 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)
{
const QPoint globalPos(x,y);
- QWindow *tlw = m_mouseGrabber.data();
- if (!tlw)
- tlw = topLevelWindowAt(globalPos);
+ QWindow *window = m_mouseGrabber.data();
+ if (!window)
+ window = windowFromId(winId);
- const QPoint localPos = tlw && tlw->handle() ? tlw->handle()->mapFromGlobal(globalPos) : globalPos;
- QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos,
+ const QPoint localPos = window && window->handle() ?
+ window->handle()->mapFromGlobal(globalPos) : globalPos;
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
Qt::MouseButtons(Qt::NoButton),
Qt::LeftButton, QEvent::MouseButtonRelease);
m_ignoreMouseEvents = false;
m_mouseGrabber.clear();
}
- static void mouseMove(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ static void mouseMove(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
{
if (m_ignoreMouseEvents)
return;
const QPoint globalPos(x,y);
- QWindow *tlw = m_mouseGrabber.data();
- if (!tlw)
- tlw = topLevelWindowAt(globalPos);
- const QPoint localPos = tlw && tlw->handle() ? tlw->handle()->mapFromGlobal(globalPos) : globalPos;
- QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos,
+ QWindow *window = m_mouseGrabber.data();
+ if (!window)
+ window = windowFromId(winId);
+ const QPoint localPos = window && window->handle() ?
+ window->handle()->mapFromGlobal(globalPos) : globalPos;
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
Qt::MouseButtons(m_mouseGrabber ? Qt::LeftButton : Qt::NoButton),
Qt::NoButton, QEvent::MouseMove);
}
- static void mouseWheel(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y, jfloat hdelta, jfloat vdelta)
+ static void mouseWheel(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y, jfloat hdelta, jfloat vdelta)
{
if (m_ignoreMouseEvents)
return;
const QPoint globalPos(x,y);
- QWindow *tlw = m_mouseGrabber.data();
- if (!tlw)
- tlw = topLevelWindowAt(globalPos);
- const QPoint localPos = tlw && tlw->handle() ? tlw->handle()->mapFromGlobal(globalPos) : globalPos;
+ QWindow *window = m_mouseGrabber.data();
+ if (!window)
+ window = windowFromId(winId);
+ const QPoint localPos = window && window->handle() ?
+ window->handle()->mapFromGlobal(globalPos) : globalPos;
const QPoint angleDelta(hdelta * 120, vdelta * 120);
- QWindowSystemInterface::handleWheelEvent(tlw,
+ QWindowSystemInterface::handleWheelEvent(window,
localPos,
globalPos,
QPoint(),
angleDelta);
}
- static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
+ static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
{
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
if (inputContext && qGuiApp)
@@ -236,15 +240,16 @@ namespace QtAndroidInput
return;
m_ignoreMouseEvents = true;
const QPoint globalPos(x,y);
- QWindow *tlw = topLevelWindowAt(globalPos);
- const QPoint localPos = tlw && tlw->handle() ? tlw->handle()->mapFromGlobal(globalPos) : globalPos;
+ QWindow *window = windowFromId(winId);
+ const QPoint localPos = window && window->handle() ?
+ window->handle()->mapFromGlobal(globalPos) : globalPos;
// Click right button if no other button is already pressed.
if (!m_mouseGrabber) {
- QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos,
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
Qt::MouseButtons(Qt::RightButton), Qt::RightButton,
QEvent::MouseButtonPress);
- QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos,
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
Qt::MouseButtons(Qt::NoButton), Qt::RightButton,
QEvent::MouseButtonRelease);
}
@@ -287,7 +292,6 @@ namespace QtAndroidInput
double(minor * 2),
double(major * 2));
m_touchPoints.push_back(touchPoint);
-
if (state == QEventPoint::State::Pressed) {
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
if (inputContext && qGuiApp)
@@ -318,7 +322,7 @@ namespace QtAndroidInput
return touchDevice;
}
- static void touchEnd(JNIEnv * /*env*/, jobject /*thiz*/, jint /*winId*/, jint /*action*/)
+ static void touchEnd(JNIEnv * /*env*/, jobject /*thiz*/, jint winId, jint /*action*/)
{
if (m_touchPoints.isEmpty())
return;
@@ -328,11 +332,13 @@ namespace QtAndroidInput
if (!touchDevice)
return;
- QWindow *window = QtAndroid::topLevelWindowAt(m_touchPoints.at(0).area.center().toPoint());
+ QWindow *window = QtAndroid::windowFromId(winId);
+ if (!window)
+ return;
QWindowSystemInterface::handleTouchEvent(window, touchDevice, m_touchPoints);
}
- static void touchCancel(JNIEnv * /*env*/, jobject /*thiz*/, jint /*winId*/)
+ static void touchCancel(JNIEnv * /*env*/, jobject /*thiz*/, jint winId)
{
if (m_touchPoints.isEmpty())
return;
@@ -342,7 +348,9 @@ namespace QtAndroidInput
if (!touchDevice)
return;
- QWindow *window = QtAndroid::topLevelWindowAt(m_touchPoints.at(0).area.center().toPoint());
+ QWindow *window = QtAndroid::windowFromId(winId);
+ if (!window)
+ return;
QWindowSystemInterface::handleTouchCancelEvent(window, touchDevice);
}
@@ -355,13 +363,14 @@ namespace QtAndroidInput
#endif // QT_CONFIG(tabletevent)
}
- static void tabletEvent(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint deviceId, jlong time, jint action,
+ static void tabletEvent(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint deviceId, jlong time, jint action,
jint pointerType, jint buttonState, jfloat x, jfloat y, jfloat pressure)
{
#if QT_CONFIG(tabletevent)
const QPointF globalPosF(x, y);
- QWindow *tlw = topLevelWindowAt(globalPosF.toPoint());
- const QPointF localPos = tlw && tlw->handle() ? tlw->handle()->mapFromGlobalF(globalPosF) : globalPosF;
+ QWindow *window = windowFromId(winId);
+ const QPointF localPos = window && window->handle() ?
+ window->handle()->mapFromGlobalF(globalPosF) : globalPosF;
// Galaxy Note with plain Android:
// 0 1 0 stylus press
@@ -395,7 +404,7 @@ namespace QtAndroidInput
qCDebug(lcQpaInputMethods) << action << pointerType << buttonState << '@' << x << y << "pressure" << pressure << ": buttons" << buttons;
- QWindowSystemInterface::handleTabletEvent(tlw, ulong(time),
+ QWindowSystemInterface::handleTabletEvent(window, ulong(time),
localPos, globalPosF, int(QInputDevice::DeviceType::Stylus), pointerType,
buttons, pressure, 0, 0, 0., 0., 0, deviceId, Qt::NoModifier);
#endif // QT_CONFIG(tabletevent)
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index d59c170095..9a9a0ac777 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -125,6 +125,21 @@ namespace QtAndroid
: 0;
}
+ QWindow *windowFromId(int windowId)
+ {
+ if (!qGuiApp)
+ return nullptr;
+
+ for (QWindow *w : qGuiApp->allWindows()) {
+ if (!w->handle())
+ continue;
+ QAndroidPlatformWindow *window = static_cast<QAndroidPlatformWindow *>(w->handle());
+ if (window->nativeViewId() == windowId)
+ return w;
+ }
+ return nullptr;
+ }
+
int availableWidthPixels()
{
return m_availableWidthPixels;
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index f65f82d6c3..2affde4961 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -38,6 +38,7 @@ namespace QtAndroid
void setViewVisibility(jobject view, bool visible);
QWindow *topLevelWindowAt(const QPoint &globalPos);
+ QWindow *windowFromId(int windowId);
int availableWidthPixels();
int availableHeightPixels();
double scaledDensity();