Warning, /graphics/krita/3rdparty/ext_qt/0001-Android-Make-window-which-is-clicked-on-the-activate.patch is written in an unsupported language. File is not indexed.
0001 From 0a2f068d34cf3c15a5f6aed28420b4888bf2068b Mon Sep 17 00:00:00 2001 0002 From: Sharaf Zaman <shzam@sdf.org> 0003 Date: Thu, 27 Jan 2022 11:46:29 +0000 0004 Subject: [PATCH] Android: Make window which is clicked on the activated window 0005 0006 Typically this functioning is managed by a proper window manager. Before 0007 this whichever window was added the last was made the active window. 0008 This raised a problem where if we have two popup windows (A & B), and B 0009 came later. If we tried selecting text widget in A (even though 0010 QAndroidPlatformScreen::topLevelAt would return the correct text 0011 widget). The text handles wouldn't be placed properly or not invoked 0012 because the Active window would still be B. 0013 0014 With this patch, we correctly move the focus to the window if it isn't 0015 blocked by a modal window and also raise the window - so, a window's 0016 z-order can changed. 0017 --- 0018 .../platforms/android/androidjniinput.cpp | 40 ++++++++++++++++++- 0019 .../android/qandroidplatformscreen.cpp | 19 ++++++++- 0020 .../android/qandroidplatformwindowmanager.cpp | 10 +++++ 0021 .../android/qandroidplatformwindowmanager.h | 3 ++ 0022 4 files changed, 70 insertions(+), 2 deletions(-) 0023 0024 diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp 0025 index 257d013fa8..a4bb8ae1a7 100644 0026 --- a/src/plugins/platforms/android/androidjniinput.cpp 0027 +++ b/src/plugins/platforms/android/androidjniinput.cpp 0028 @@ -46,11 +46,13 @@ 0029 #include "androidjnimain.h" 0030 #include "qandroidplatformintegration.h" 0031 #include "qandroidplatformwindow.h" 0032 +#include "qandroidplatformwindowmanager.h" 0033 0034 #include <qpa/qwindowsysteminterface.h> 0035 #include <QTouchEvent> 0036 #include <QPointer> 0037 0038 +#include <private/qguiapplication_p.h> 0039 #include <QGuiApplication> 0040 #include <QDebug> 0041 #include <QtMath> 0042 @@ -136,6 +138,33 @@ namespace QtAndroidInput 0043 anchor.x(), anchor.y(), rtl); 0044 } 0045 0046 + static void checkAndSetTopLevelWindow(QWindow *window) 0047 + { 0048 + QWindow *focusWindow = QGuiApplication::focusWindow(); 0049 + if (focusWindow == window || (window && window->flags() & Qt::WindowDoesNotAcceptFocus)) { 0050 + return; 0051 + } 0052 + 0053 + // NOTE: Apparently, Qt expects Popups to be on top and have focus. If we move focus popup 0054 + // should be closed (see notifyActiveWindowChange). So we close the popup first if some 0055 + // other window is clicked. Otherwise Qt goes in an undefined state. I'm not 100% sure 0056 + // though. 0057 + if (focusWindow && (focusWindow->type() == Qt::Popup || focusWindow->type() == Qt::ToolTip)) { 0058 + focusWindow->hide(); 0059 + } 0060 + 0061 + QAndroidPlatformWindowManager *wm = dynamic_cast<QAndroidPlatformWindowManager *>(window); 0062 + if (wm) { 0063 + // check if the window managed by this manager is blocked by a modal 0064 + // dialog (because a window manager won't be blocked) 0065 + window = wm->realWindow()->window(); 0066 + } 0067 + if (window && !QGuiApplicationPrivate::instance()->isWindowBlocked(window)) { 0068 + window->raise(); 0069 + QWindowSystemInterface::handleWindowActivated(window, Qt::ActiveWindowFocusReason); 0070 + } 0071 + } 0072 + 0073 static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, 0074 jint x, jint y, jint modifier, jint actionButton) 0075 { 0076 @@ -150,6 +179,7 @@ namespace QtAndroidInput 0077 localPos = platformWindow ? platformWindow->mapFromGlobal(globalPos) : globalPos; 0078 } 0079 m_mouseGrabber = tlw; 0080 + checkAndSetTopLevelWindow(m_mouseGrabber); 0081 // NOTE: mapping between MotionEvent's BUTTON states and Qt seem consistent 0082 m_mouseActionButton = actionButton; 0083 QWindowSystemInterface::handleMouseEvent(tlw, 0084 @@ -265,7 +295,7 @@ namespace QtAndroidInput 0085 m_touchPoints.clear(); 0086 } 0087 0088 - static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean /*primary*/, jint x, jint y, 0089 + static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean primary, jint x, jint y, 0090 jfloat major, jfloat minor, jfloat rotation, jfloat pressure) 0091 { 0092 Qt::TouchPointState state = Qt::TouchPointStationary; 0093 @@ -302,6 +332,13 @@ namespace QtAndroidInput 0094 QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); 0095 if (inputContext && qGuiApp) 0096 QMetaObject::invokeMethod(inputContext, "touchDown", Q_ARG(int, x), Q_ARG(int, y)); 0097 + 0098 + // if the touchpoint is the first one, the window which received it should be the top 0099 + // level 0100 + if (primary) { 0101 + checkAndSetTopLevelWindow( 0102 + QtAndroid::topLevelWindowAt(touchPoint.area.center().toPoint())); 0103 + } 0104 } 0105 } 0106 0107 @@ -389,6 +426,7 @@ namespace QtAndroidInput 0108 break; 0109 case AMOTION_EVENT_ACTION_DOWN: 0110 m_mouseGrabber = tlw; 0111 + checkAndSetTopLevelWindow(m_mouseGrabber); 0112 // fall through 0113 case AMOTION_EVENT_ACTION_MOVE: 0114 if (!buttonState) 0115 diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp 0116 index da6de1806f..f1f936850a 100644 0117 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp 0118 +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp 0119 @@ -218,6 +218,15 @@ void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window) 0120 if (window->parent() && window->isRaster()) 0121 return; 0122 0123 + // if the window being raised is the window manager, we just prompt the real window to be 0124 + // raised, and then this gets handled automatically 0125 + QAndroidPlatformWindowManager *wm = 0126 + dynamic_cast<QAndroidPlatformWindowManager *>(window->window()); 0127 + if (wm) { 0128 + wm->raiseRealWindow(); 0129 + return; 0130 + } 0131 + 0132 int index = m_windowStack.indexOf(window); 0133 if (index <= 0) 0134 return; 0135 @@ -238,6 +247,15 @@ void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window) 0136 if (window->parent() && window->isRaster()) 0137 return; 0138 0139 + // if the window being lowered is the window manager, we just prompt the real window to be 0140 + // lowered, and then this gets handled automatically 0141 + QAndroidPlatformWindowManager *wm = 0142 + dynamic_cast<QAndroidPlatformWindowManager *>(window->window()); 0143 + if (wm) { 0144 + wm->lowerRealWindow(); 0145 + return; 0146 + } 0147 + 0148 int index = m_windowStack.indexOf(window); 0149 if (index == -1) 0150 return; 0151 @@ -266,7 +284,6 @@ void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window) 0152 topWindowChanged(w); 0153 } 0154 0155 - 0156 void QAndroidPlatformScreen::setWindowGeometry(QAndroidPlatformWindow *window, const QRect &rect) 0157 { 0158 if (m_windowManagers.contains(window->winId())) { 0159 diff --git a/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp b/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0160 index 15bdae76a5..a352017731 100644 0161 --- a/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0162 +++ b/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0163 @@ -43,6 +43,16 @@ void QAndroidPlatformWindowManager::updateGeometry(const QRect &rect) 0164 resize(QHighDpi::toNativePixels(geometry().size(), this)); 0165 } 0166 0167 +void QAndroidPlatformWindowManager::raiseRealWindow() 0168 +{ 0169 + m_realWindow->raise(); 0170 +} 0171 + 0172 +void QAndroidPlatformWindowManager::lowerRealWindow() 0173 +{ 0174 + m_realWindow->lower(); 0175 +} 0176 + 0177 void QAndroidPlatformWindowManager::mousePressEvent(QMouseEvent *event) 0178 { 0179 m_startingPoint = event->globalPos(); 0180 diff --git a/src/plugins/platforms/android/qandroidplatformwindowmanager.h b/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0181 index 0688a75794..f78cdc0725 100644 0182 --- a/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0183 +++ b/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0184 @@ -26,6 +26,9 @@ public: 0185 * @param geometry of window to be managed, rect should be in native pixels 0186 */ 0187 void updateGeometry(const QRect &rect); 0188 + void raiseRealWindow(); 0189 + void lowerRealWindow(); 0190 + QAndroidPlatformWindow *realWindow() { return m_realWindow; } 0191 0192 protected: 0193 void resizeEvent(QResizeEvent *event) override; 0194 -- 0195 2.37.0 0196