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