Warning, /graphics/krita/3rdparty/ext_qt/0001-Android-Fix-incorrect-handling-of-window-modality.patch is written in an unsupported language. File is not indexed.
0001 From 03fea83a0520bc99e2d6a569facfde73537baec1 Mon Sep 17 00:00:00 2001 0002 From: Sharaf Zaman <shzam@sdf.org> 0003 Date: Tue, 19 Jul 2022 08:50:25 +0000 0004 Subject: [PATCH] Android: Fix incorrect handling of window modality 0005 0006 Before this, we used to ignore the modality in the "topWindowAt" API 0007 which made us rely on window modality handling somewhere down the line. 0008 This resulted in a problem where even though the modal window should be 0009 able to receive the events, it didn't because the point didn't exist in 0010 its boundingRect (and we could shift focus to windows whose modality 0011 wasn't properly handled downstream). 0012 0013 With current implementation. If the dialog is a popup and the point is 0014 in its bounding rect, then we return it (this ignores modality rules, 0015 but should be safe enough -- because it is a popup?). 0016 0017 Then we check if the window is modal, if it is we should send all the 0018 events to it, unless the window has a window manager. In that case if we 0019 touch the window manager's frame, it should get the events instead. 0020 --- 0021 .../android/qandroidplatformscreen.cpp | 20 ++++++++++++++----- 0022 .../android/qandroidplatformwindowmanager.cpp | 11 ++++++++++ 0023 .../android/qandroidplatformwindowmanager.h | 16 +++++++++++++++ 0024 3 files changed, 42 insertions(+), 5 deletions(-) 0025 0026 diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp 0027 index f1f936850a..8152523ba3 100644 0028 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp 0029 +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp 0030 @@ -139,9 +139,20 @@ QWindow *QAndroidPlatformScreen::topLevelAt(const QPoint &p) const 0031 // These are the types of widgets which are usually kept on top by the 0032 // compositor. But since there is none for SurfaceView, we try our best to 0033 // give them the first preference. 0034 - for (QAndroidPlatformWindow *w : m_windowStack) { 0035 - if (isPopup(w) && w->geometry().contains(p, false) && w->window()->isVisible()) { 0036 - return w->window(); 0037 + for (QAndroidPlatformWindow *platformWindow : m_windowStack) { 0038 + if (isPopup(platformWindow) && platformWindow->geometry().contains(p, false) 0039 + && platformWindow->window()->isVisible()) { 0040 + return platformWindow->window(); 0041 + } 0042 + 0043 + if (platformWindow->window()->isModal() && platformWindow->window()->isVisible()) { 0044 + // check if the platformWindow doesn't have a window manager and if it does, then check 0045 + // if the point p isn't in the bounds of window manager, if it is, then we should just 0046 + // let it (the window manager) handle it. 0047 + if (!m_windowManagers.contains(platformWindow->winId()) 0048 + || !m_windowManagers[platformWindow->winId()]->contains(p, true)) { 0049 + return platformWindow->window(); 0050 + } 0051 } 0052 } 0053 for (QAndroidPlatformWindow *w : m_windowStack) { 0054 @@ -166,8 +177,7 @@ void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window) 0055 if (window->parent() && window->isRaster()) 0056 return; 0057 0058 - if ((window->window()->type() == Qt::Dialog || window->window()->type() == Qt::Tool) 0059 - && (window->window()->flags() & Qt::FramelessWindowHint) == 0) { 0060 + if (QAndroidPlatformWindowManager::needsWindowManager(window->window())) { 0061 // we will manage memory ourselves, because our parent is always 0062 // MainWindow 0063 QAndroidPlatformWindowManager *wm = new QAndroidPlatformWindowManager(window); 0064 diff --git a/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp b/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0065 index 4e896eab3c..4bad4b6553 100644 0066 --- a/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0067 +++ b/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0068 @@ -53,6 +53,17 @@ void QAndroidPlatformWindowManager::lowerRealWindow() 0069 m_realWindow->lower(); 0070 } 0071 0072 +bool QAndroidPlatformWindowManager::contains(QPoint point, bool inNativeUnits) 0073 +{ 0074 + if (inNativeUnits) { 0075 + point = QHighDpi::fromNativePixels(point, this); 0076 + } 0077 + const QRegion wmGeom = geometry(); 0078 + const QRegion childGeom = m_realWindow->window()->geometry(); 0079 + 0080 + return wmGeom.subtracted(childGeom).contains(point); 0081 +} 0082 + 0083 void QAndroidPlatformWindowManager::mousePressEvent(QMouseEvent *event) 0084 { 0085 m_startingPoint = event->globalPos(); 0086 diff --git a/src/plugins/platforms/android/qandroidplatformwindowmanager.h b/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0087 index f78cdc0725..a548f3dd44 100644 0088 --- a/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0089 +++ b/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0090 @@ -30,6 +30,22 @@ public: 0091 void lowerRealWindow(); 0092 QAndroidPlatformWindow *realWindow() { return m_realWindow; } 0093 0094 + /** 0095 + * return true of the window type needs a window manager. 0096 + */ 0097 + static bool needsWindowManager(QWindow *window) 0098 + { 0099 + return ((window->type() == Qt::Dialog || window->type() == Qt::Tool) 0100 + && (window->flags() & Qt::FramelessWindowHint) == 0); 0101 + } 0102 + 0103 + /** 0104 + * Returns true if point is in the window manager bounds, but not in the bounds of its 0105 + * child/real window. If the point is in native units, inNativeUnits should be set to true for 0106 + * valid calulcations. 0107 + */ 0108 + bool contains(QPoint point, bool inNativeUnits = false); 0109 + 0110 protected: 0111 void resizeEvent(QResizeEvent *event) override; 0112 void showEvent(QShowEvent *event) override; 0113 -- 0114 2.37.0 0115