Warning, /graphics/krita/3rdparty/ext_qt/0038-Android-Add-window-manager-for-raster-based-QWidgets.patch is written in an unsupported language. File is not indexed.
0001 From 028b108866e82230dd3f7219ff4c1b4bbbc81004 Mon Sep 17 00:00:00 2001 0002 From: Sharaf Zaman <sharafzaz121@gmail.com> 0003 Date: Thu, 15 Apr 2021 21:35:50 +0000 0004 Subject: [PATCH] Android: Add window manager for raster based QWidgets 0005 0006 The way this works is for window types: (Qt::Dialog || Qt::Tool (without 0007 Qt::FramelessWindowHint)) which on other platforms are typically 0008 expected to have a frame around them; Before we add them to window stack 0009 we add another window which we call Window Manager, this window is 0010 offsetted by specific value and is white which makes it look like a 0011 window manager. We also handle events on this window, using which we can 0012 currently move the window around. 0013 0014 The window is rendered like any other window which does not have 0015 renderToTexture enabled. 0016 --- 0017 src/plugins/platforms/android/android.pro | 6 +- 0018 .../platforms/android/androidjniinput.cpp | 10 +- 0019 .../android/qandroidplatformbackingstore.cpp | 13 +- 0020 .../android/qandroidplatformbackingstore.h | 2 +- 0021 .../android/qandroidplatformopenglwindow.cpp | 16 +- 0022 .../android/qandroidplatformscreen.cpp | 51 ++++- 0023 .../android/qandroidplatformscreen.h | 4 + 0024 .../android/qandroidplatformwindow.cpp | 1 + 0025 .../android/qandroidplatformwindow.h | 1 - 0026 .../android/qandroidplatformwindowmanager.cpp | 214 ++++++++++++++++++ 0027 .../android/qandroidplatformwindowmanager.h | 59 +++++ 0028 11 files changed, 359 insertions(+), 18 deletions(-) 0029 create mode 100644 src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0030 create mode 100644 src/plugins/platforms/android/qandroidplatformwindowmanager.h 0031 0032 diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro 0033 index 78632a9bea..8f62cb4c1e 100644 0034 --- a/src/plugins/platforms/android/android.pro 0035 +++ b/src/plugins/platforms/android/android.pro 0036 @@ -48,7 +48,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \ 0037 $$PWD/qandroidplatformforeignwindow.cpp \ 0038 $$PWD/qandroideventdispatcher.cpp \ 0039 $$PWD/qandroidplatformoffscreensurface.cpp \ 0040 - $$PWD/qandroidplatformfiledialoghelper.cpp 0041 + $$PWD/qandroidplatformfiledialoghelper.cpp \ 0042 + $$PWD/qandroidplatformwindowmanager.cpp 0043 0044 HEADERS += $$PWD/qandroidplatformintegration.h \ 0045 $$PWD/androidcontentfileengine.h \ 0046 @@ -79,7 +80,8 @@ HEADERS += $$PWD/qandroidplatformintegration.h \ 0047 $$PWD/qandroidplatformforeignwindow.h \ 0048 $$PWD/qandroideventdispatcher.h \ 0049 $$PWD/qandroidplatformoffscreensurface.h \ 0050 - $$PWD/qandroidplatformfiledialoghelper.h 0051 + $$PWD/qandroidplatformfiledialoghelper.h \ 0052 + $$PWD/qandroidplatformwindowmanager.h 0053 0054 qtConfig(android-style-assets): SOURCES += $$PWD/extract.cpp 0055 else: SOURCES += $$PWD/extract-dummy.cpp 0056 diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp 0057 index fec394f95e..257d013fa8 100644 0058 --- a/src/plugins/platforms/android/androidjniinput.cpp 0059 +++ b/src/plugins/platforms/android/androidjniinput.cpp 0060 @@ -355,7 +355,10 @@ namespace QtAndroidInput 0061 #if QT_CONFIG(tabletevent) 0062 QPointF globalPosF(x, y); 0063 QPoint globalPos((int)x, (int)y); 0064 - QWindow *tlw = topLevelWindowAt(globalPos); 0065 + QWindow *tlw = m_mouseGrabber.data(); 0066 + if (!tlw) { 0067 + tlw = topLevelWindowAt(globalPos); 0068 + } 0069 0070 QPointF localPos = globalPosF; 0071 if (tlw) { 0072 @@ -381,10 +384,13 @@ namespace QtAndroidInput 0073 Qt::MouseButtons buttons = Qt::NoButton; 0074 switch (action) { 0075 case AMOTION_EVENT_ACTION_UP: 0076 + m_mouseGrabber = nullptr; 0077 buttons = Qt::NoButton; 0078 break; 0079 - case AMOTION_EVENT_ACTION_MOVE: 0080 case AMOTION_EVENT_ACTION_DOWN: 0081 + m_mouseGrabber = tlw; 0082 + // fall through 0083 + case AMOTION_EVENT_ACTION_MOVE: 0084 if (!buttonState) 0085 buttons = Qt::LeftButton; 0086 default: 0087 diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp 0088 index 61d4969c41..75f9b41342 100644 0089 --- a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp 0090 +++ b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp 0091 @@ -42,6 +42,7 @@ 0092 #include "qandroidplatformscreen.h" 0093 #include "qandroidplatformwindow.h" 0094 #include <qpa/qplatformscreen.h> 0095 +#include <private/qhighdpiscaling_p.h> 0096 0097 QT_BEGIN_NAMESPACE 0098 0099 @@ -54,6 +55,7 @@ QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window) 0100 0101 QPaintDevice *QAndroidPlatformBackingStore::paintDevice() 0102 { 0103 + Q_ASSERT(!m_image.isNull()); 0104 return &m_image; 0105 } 0106 0107 @@ -71,8 +73,17 @@ void QAndroidPlatformBackingStore::resize(const QSize &size, const QRegion &stat 0108 { 0109 Q_UNUSED(staticContents); 0110 0111 - if (m_image.size() != size) 0112 + if (m_image.size() != size) { 0113 m_image = QImage(size, window()->screen()->handle()->format()); 0114 + } 0115 +} 0116 + 0117 +QImage QAndroidPlatformBackingStore::toImage() const 0118 +{ 0119 + if (m_image.isNull()) { 0120 + qDebug() << "QAndroidPlatformBackingStore::toImage(): image is null"; 0121 + } 0122 + return m_image; 0123 } 0124 0125 void QAndroidPlatformBackingStore::setBackingStore(QWindow *window) 0126 diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h 0127 index a3a65aa30e..ec1761c789 100644 0128 --- a/src/plugins/platforms/android/qandroidplatformbackingstore.h 0129 +++ b/src/plugins/platforms/android/qandroidplatformbackingstore.h 0130 @@ -53,7 +53,7 @@ public: 0131 QPaintDevice *paintDevice() override; 0132 void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; 0133 void resize(const QSize &size, const QRegion &staticContents) override; 0134 - QImage toImage() const override { return m_image; } 0135 + QImage toImage() const override; 0136 void setBackingStore(QWindow *window); 0137 protected: 0138 QImage m_image; 0139 diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp 0140 index 3de5d30623..35b437dd59 100644 0141 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp 0142 +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp 0143 @@ -82,17 +82,18 @@ void QAndroidPlatformOpenGLWindow::repaint(const QRegion ®ion) 0144 0145 QRect currentGeometry = geometry(); 0146 0147 - QRect dirtyClient = region.boundingRect(); 0148 - QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(), 0149 - currentGeometry.top() + dirtyClient.top(), 0150 - dirtyClient.width(), 0151 - dirtyClient.height()); 0152 + QRect dirtyClient = region.boundingRect(); // not sure if this is necessary 0153 + QRegion dirtyRegion = dirtyClient; 0154 + dirtyRegion += currentGeometry; 0155 + 0156 QRect mOldGeometryLocal = m_oldGeometry; 0157 m_oldGeometry = currentGeometry; 0158 // If this is a move, redraw the previous location 0159 if (mOldGeometryLocal != currentGeometry) 0160 platformScreen()->setDirty(mOldGeometryLocal); 0161 - platformScreen()->setDirty(dirtyRegion); 0162 + for (const auto &dirtyRect : dirtyRegion) { 0163 + platformScreen()->setDirty(dirtyRect); 0164 + } 0165 } 0166 0167 void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect) 0168 @@ -116,8 +117,7 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect) 0169 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size())); 0170 } 0171 0172 - if (rect.topLeft() != m_oldGeometry.topLeft()) 0173 - repaint(QRegion(rect)); 0174 + repaint(QRegion(rect)); 0175 } 0176 0177 EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config) 0178 diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp 0179 index 4213bdc088..0100050bb9 100644 0180 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp 0181 +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp 0182 @@ -50,6 +50,7 @@ 0183 #include "androidjnimain.h" 0184 #include "androidjnimenu.h" 0185 #include "androiddeadlockprotector.h" 0186 +#include "qandroidplatformwindowmanager.h" 0187 0188 #include <android/bitmap.h> 0189 #include <android/native_window_jni.h> 0190 @@ -162,6 +163,15 @@ void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window) 0191 if (window->parent() && window->isRaster()) 0192 return; 0193 0194 + if ((window->window()->type() == Qt::Dialog || window->window()->type() == Qt::Tool) 0195 + && (window->window()->flags() & Qt::FramelessWindowHint) == 0) { 0196 + // we will manage memory ourselves, because our parent is always 0197 + // MainWindow 0198 + QAndroidPlatformWindowManager *wm = new QAndroidPlatformWindowManager(window); 0199 + wm->show(); 0200 + m_windowManagers.insert(window->winId(), wm); 0201 + } 0202 + 0203 Q_ASSERT(!m_windowStack.contains(window)); 0204 m_windowStack.prepend(window); 0205 if (window->isRaster()) { 0206 @@ -179,6 +189,12 @@ void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window) 0207 if (window->parent() && window->isRaster()) 0208 return; 0209 0210 + if (m_windowManagers.contains(window->winId())) { 0211 + QAndroidPlatformWindowManager *wm = m_windowManagers[window->winId()]; 0212 + m_windowManagers.remove(window->winId()); 0213 + wm->close(); 0214 + delete wm; 0215 + } 0216 0217 Q_ASSERT(m_windowStack.contains(window)); 0218 m_windowStack.removeOne(window); 0219 @@ -203,6 +219,9 @@ void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window) 0220 if (index <= 0) 0221 return; 0222 m_windowStack.move(index, 0); 0223 + if (m_windowManagers.contains(window->winId())) { 0224 + m_windowStack.move(index + 1, 1); 0225 + } 0226 if (window->isRaster()) { 0227 setDirty(window->geometry()); 0228 } 0229 @@ -217,9 +236,25 @@ void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window) 0230 return; 0231 0232 int index = m_windowStack.indexOf(window); 0233 - if (index == -1 || index == (m_windowStack.size() - 1)) 0234 + if (index == -1) 0235 + return; 0236 + 0237 + // check if current window is not the last window 0238 + if (m_windowManagers.contains(window->winId())) { 0239 + if (index != (m_windowStack.size() - 2)) { 0240 + // we first move the actual window to last 0241 + m_windowStack.move(index, m_windowStack.size() - 1); 0242 + // then we move the window manager window 0243 + m_windowStack.move(index, m_windowStack.size() - 1); 0244 + } else { 0245 + return; 0246 + } 0247 + } else if (index != (m_windowStack.size() - 1)) { 0248 + m_windowStack.move(index, m_windowStack.size() - 1); 0249 + } else { 0250 return; 0251 - m_windowStack.move(index, m_windowStack.size() - 1); 0252 + } 0253 + 0254 if (window->isRaster()) { 0255 setDirty(window->geometry()); 0256 } 0257 @@ -228,6 +263,14 @@ void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window) 0258 topWindowChanged(w); 0259 } 0260 0261 + 0262 +void QAndroidPlatformScreen::setWindowGeometry(QAndroidPlatformWindow *window, const QRect &rect) 0263 +{ 0264 + if (m_windowManagers.contains(window->winId())) { 0265 + m_windowManagers[window->winId()]->updateGeometry(rect); 0266 + } 0267 +} 0268 + 0269 void QAndroidPlatformScreen::scheduleUpdate() 0270 { 0271 if (!m_updatePending) { 0272 @@ -399,13 +442,15 @@ void QAndroidPlatformScreen::doRedraw() 0273 visibleRegion -= targetRect; 0274 QRect windowRect = targetRect.translated(-window->geometry().topLeft()); 0275 QAndroidPlatformBackingStore *backingStore = static_cast<QAndroidPlatformWindow *>(window)->backingStore(); 0276 + 0277 if (backingStore) 0278 compositePainter.drawImage(targetRect.topLeft(), backingStore->toImage(), windowRect); 0279 } 0280 } 0281 0282 - for (const QRect &rect : visibleRegion) 0283 + for (const QRect &rect : visibleRegion) { 0284 compositePainter.fillRect(rect, QColor(Qt::transparent)); 0285 + } 0286 0287 ret = ANativeWindow_unlockAndPost(m_nativeSurface); 0288 if (ret >= 0) 0289 diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h 0290 index f15aeae3fd..415fcfc932 100644 0291 --- a/src/plugins/platforms/android/qandroidplatformscreen.h 0292 +++ b/src/plugins/platforms/android/qandroidplatformscreen.h 0293 @@ -54,6 +54,7 @@ 0294 0295 QT_BEGIN_NAMESPACE 0296 0297 +class QAndroidPlatformWindowManager; 0298 class QAndroidPlatformWindow; 0299 0300 class QAndroidPlatformScreen: public QObject, public QPlatformScreen, public AndroidSurfaceClient 0301 @@ -77,6 +78,8 @@ public: 0302 void removeWindow(QAndroidPlatformWindow *window); 0303 void raise(QAndroidPlatformWindow *window); 0304 void lower(QAndroidPlatformWindow *window); 0305 + /// @param rect should be in native pixels 0306 + void setWindowGeometry(QAndroidPlatformWindow *window, const QRect &rect); 0307 0308 void scheduleUpdate(); 0309 void topWindowChanged(QWindow *w); 0310 @@ -119,6 +122,7 @@ private: 0311 ANativeWindow* m_nativeSurface = nullptr; 0312 QWaitCondition m_surfaceWaitCondition; 0313 QSize m_size; 0314 + QMap<int, QAndroidPlatformWindowManager *> m_windowManagers; 0315 }; 0316 0317 QT_END_NAMESPACE 0318 diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp 0319 index 61e6f360de..1574b8b013 100644 0320 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp 0321 +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp 0322 @@ -73,6 +73,7 @@ void QAndroidPlatformWindow::raise() 0323 void QAndroidPlatformWindow::setGeometry(const QRect &rect) 0324 { 0325 QWindowSystemInterface::handleGeometryChange(window(), rect); 0326 + platformScreen()->setWindowGeometry(this, rect); 0327 } 0328 0329 void QAndroidPlatformWindow::setVisible(bool visible) 0330 diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h 0331 index f2e51bd3df..aad001c359 100644 0332 --- a/src/plugins/platforms/android/qandroidplatformwindow.h 0333 +++ b/src/plugins/platforms/android/qandroidplatformwindow.h 0334 @@ -86,7 +86,6 @@ public: 0335 0336 virtual void repaint(const QRegion &) { } 0337 0338 -protected: 0339 void setGeometry(const QRect &rect) override; 0340 0341 protected: 0342 diff --git a/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp b/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0343 new file mode 100644 0344 index 0000000000..15bdae76a5 0345 --- /dev/null 0346 +++ b/src/plugins/platforms/android/qandroidplatformwindowmanager.cpp 0347 @@ -0,0 +1,214 @@ 0348 +#include "qandroidplatformwindowmanager.h" 0349 + 0350 +#include "qandroidplatformwindow.h" 0351 +#include "qandroidplatformbackingstore.h" 0352 + 0353 +#include <private/qhighdpiscaling_p.h> 0354 +#include <QPainter> 0355 +#include <qbackingstore.h> 0356 + 0357 +// In HighDPI 0358 +static const int paddingTop = 25; 0359 +static const int paddingLBR = 3; // left, bottom and right 0360 + 0361 +QAndroidPlatformWindowManager::QAndroidPlatformWindowManager(QAndroidPlatformWindow *window) 0362 + : QWindow(window->window()->parent()) 0363 + , m_realWindow(window) 0364 + , m_backingStore(new QAndroidPlatformBackingStore(this)) 0365 +{ 0366 + setObjectName("QAndroidPlatformWindowManager"); 0367 + // popup because they are special, frameless because recursion 0368 + setFlags(Qt::Popup | Qt::FramelessWindowHint); 0369 + setMinimumSize(window->window()->minimumSize()); 0370 + setMaximumSize(window->window()->maximumSize()); 0371 +} 0372 + 0373 +QAndroidPlatformWindowManager::~QAndroidPlatformWindowManager() 0374 +{ 0375 + delete m_backingStore; 0376 +} 0377 + 0378 +void QAndroidPlatformWindowManager::updateGeometry(const QRect &rect) 0379 +{ 0380 + if (m_oldChildGeometry == rect) { 0381 + return; 0382 + } 0383 + m_oldChildGeometry = rect; 0384 + QRect wmGeometry = QHighDpi::fromNativePixels(rect, m_realWindow->window()); 0385 + wmGeometry.translate(-paddingLBR, -paddingTop); 0386 + wmGeometry.setSize({ 2 * paddingLBR + wmGeometry.width(), 0387 + paddingLBR + wmGeometry.height() + paddingTop }); 0388 + 0389 + setGeometry(wmGeometry); 0390 + resize(QHighDpi::toNativePixels(geometry().size(), this)); 0391 +} 0392 + 0393 +void QAndroidPlatformWindowManager::mousePressEvent(QMouseEvent *event) 0394 +{ 0395 + m_startingPoint = event->globalPos(); 0396 + m_realWindowOffset = m_startingPoint - m_realWindow->window()->geometry().topLeft(); 0397 + m_startingGeometry = m_realWindow->window()->geometry(); 0398 + 0399 + calculatePressArea(event->globalPos()); 0400 + 0401 + m_mousePressed = true; 0402 + event->accept(); 0403 +} 0404 + 0405 +void QAndroidPlatformWindowManager::calculatePressArea(const QPoint &pos) 0406 +{ 0407 + QRect wmGeom = geometry(); 0408 + QRect childGeom = m_realWindow->window()->geometry(); 0409 + 0410 + // NOTE: we add + 1 because of QRect's quirks 0411 + if (QRect(wmGeom.topLeft(), QSize(wmGeom.width(), paddingTop)).contains(pos)) { 0412 + m_grabbedAction = MOVE; 0413 + } else if (QRect(wmGeom.topLeft(), QSize(paddingLBR, wmGeom.height())) 0414 + .contains(pos)) { 0415 + m_grabbedAction = HORIZONTAL_RESIZE_LEFT; 0416 + } else if (QRect({childGeom.right() + 1, childGeom.top()}, 0417 + QSize(paddingLBR, wmGeom.height())) 0418 + .contains(pos)) { 0419 + m_grabbedAction = HORIZONTAL_RESIZE_RIGHT; 0420 + } else if (QRect({childGeom.left(), childGeom.bottom() + 1}, childGeom.size()) 0421 + .contains(pos)) { 0422 + m_grabbedAction = VERTICAL_RESIZE; 0423 + } 0424 + 0425 + int cornerPadding = 10; // this makes corners a bit easier to grab 0426 + 0427 + if (QRect(childGeom.translated(-cornerPadding, -cornerPadding).bottomRight(), 0428 + QPoint(wmGeom.right() + 1, wmGeom.bottom() + 1)) 0429 + .contains(pos)) { 0430 + m_grabbedAction = CORNER_RESIZE_RIGHT; 0431 + } 0432 + 0433 + QPoint startOffset = QPoint(wmGeom.left(), childGeom.bottom() - cornerPadding); 0434 + if (QRect(startOffset, QPoint(childGeom.left() + cornerPadding, wmGeom.bottom())) 0435 + .contains(pos)) { 0436 + m_grabbedAction = CORNER_RESIZE_LEFT; 0437 + } 0438 +} 0439 + 0440 +void QAndroidPlatformWindowManager::mouseMoveEvent(QMouseEvent *event) 0441 +{ 0442 + if (m_mousePressed) { 0443 + move(event->globalPos()); 0444 + event->accept(); 0445 + } 0446 +} 0447 + 0448 +void QAndroidPlatformWindowManager::mouseReleaseEvent(QMouseEvent *event) 0449 +{ 0450 + m_mousePressed = false; 0451 + m_grabbedAction = NONE; 0452 + 0453 + event->accept(); 0454 +} 0455 + 0456 +void QAndroidPlatformWindowManager::resizeEvent(QResizeEvent *event) 0457 +{ 0458 + resize(event->size()); 0459 +} 0460 + 0461 +void QAndroidPlatformWindowManager::showEvent(QShowEvent *event) 0462 +{ 0463 + if (m_realWindow->geometry().topLeft().y() < paddingTop) { 0464 + QRect geom = m_realWindow->geometry(); 0465 + geom.translate(0, paddingTop); 0466 + m_realWindow->setGeometry(geom); 0467 + } 0468 + 0469 + updateGeometry(m_realWindow->geometry()); 0470 + 0471 + setWindowState(Qt::WindowNoState); 0472 + // NOTE: platformWindow won't be created yet, so set flags for it. 0473 + // popup because they are special, frameless because recursion 0474 + setFlags(Qt::Popup | Qt::FramelessWindowHint); 0475 + 0476 + event->accept(); 0477 +} 0478 + 0479 +void QAndroidPlatformWindowManager::repaint() 0480 +{ 0481 + QRect childGeometry = handle()->geometry(); 0482 + QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(handle()); 0483 + platformWindow->setBackingStore(m_backingStore); 0484 + 0485 + QPainter painter(m_backingStore->paintDevice()); 0486 + painter.fillRect(0, 0, childGeometry.width(), childGeometry.height(), Qt::white); 0487 + m_backingStore->endPaint(); 0488 + 0489 + // m_backingStore->toImage().save(QString("/data/data/org.krita/files/%1.png").arg(this->objectName())); 0490 +} 0491 + 0492 +void QAndroidPlatformWindowManager::move(const QPoint &pos) 0493 +{ 0494 + switch (m_grabbedAction) { 0495 + case MOVE: 0496 + m_realWindow->window()->setPosition(QPoint(pos.x(), std::max(10, pos.y())) 0497 + - m_realWindowOffset); 0498 + break; 0499 + case HORIZONTAL_RESIZE_LEFT: 0500 + resizeChildWindow(QRect(pos.x(), m_startingGeometry.y(), 0501 + m_startingGeometry.right() - pos.x(), 0502 + m_startingGeometry.height())); 0503 + break; 0504 + case HORIZONTAL_RESIZE_RIGHT: 0505 + resizeChildWindow(QRect(m_startingGeometry.left(), m_startingGeometry.top(), 0506 + (pos.x() - m_startingGeometry.left()), 0507 + m_startingGeometry.height())); 0508 + break; 0509 + case VERTICAL_RESIZE: 0510 + resizeChildWindow(QRect(m_startingGeometry.left(), m_startingGeometry.top(), 0511 + m_startingGeometry.width(), 0512 + (pos.y() - m_startingGeometry.top()))); 0513 + break; 0514 + case CORNER_RESIZE_LEFT: 0515 + resizeChildWindow(QRect(pos.x(), m_startingGeometry.y(), 0516 + m_startingGeometry.right() - pos.x(), 0517 + pos.y() - m_startingGeometry.top())); 0518 + break; 0519 + case CORNER_RESIZE_RIGHT: 0520 + resizeChildWindow(QRect(m_startingGeometry.left(), m_startingGeometry.top(), 0521 + (pos.x() - m_startingGeometry.left()), 0522 + (pos.y() - m_startingGeometry.top()))); 0523 + break; 0524 + default: 0525 + qWarning() << "WindowManager: Bad Action" << m_grabbedAction; 0526 + break; 0527 + } 0528 +} 0529 + 0530 +void QAndroidPlatformWindowManager::resize(const QSize &size) 0531 +{ 0532 + if (m_oldSize == size) { 0533 + return; 0534 + } 0535 + m_oldSize = size; 0536 + m_backingStore->resize(QHighDpi::toNativePixels(size, this), QRegion()); 0537 + repaint(); 0538 +} 0539 + 0540 +void QAndroidPlatformWindowManager::resizeChildWindow(const QRect &geom) 0541 +{ 0542 + QRect adjustedGeom = geom; 0543 + if (adjustedGeom.width() < minimumWidth()) { 0544 + adjustedGeom.setLeft(m_realWindow->window()->geometry().left()); 0545 + adjustedGeom.setWidth(minimumWidth()); 0546 + } 0547 + if (adjustedGeom.height() < minimumHeight()) { 0548 + adjustedGeom.setTop(m_realWindow->window()->geometry().top()); 0549 + adjustedGeom.setHeight(minimumHeight()); 0550 + } 0551 + 0552 + adjustedGeom.setWidth(adjustedGeom.width() > maximumWidth() ? maximumWidth() 0553 + : adjustedGeom.width()); 0554 + 0555 + adjustedGeom.setHeight(adjustedGeom.height() > maximumHeight() 0556 + ? maximumHeight() 0557 + : adjustedGeom.height()); 0558 + 0559 + // this will trigger window manager's updateGeometry as well 0560 + m_realWindow->window()->setGeometry(adjustedGeom); 0561 +} 0562 diff --git a/src/plugins/platforms/android/qandroidplatformwindowmanager.h b/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0563 new file mode 100644 0564 index 0000000000..0688a75794 0565 --- /dev/null 0566 +++ b/src/plugins/platforms/android/qandroidplatformwindowmanager.h 0567 @@ -0,0 +1,59 @@ 0568 +#ifndef __QANDROIDPLATFORMWINDOWMANAGER_H_ 0569 +#define __QANDROIDPLATFORMWINDOWMANAGER_H_ 0570 + 0571 +#include <qpa/qplatformwindow.h> 0572 + 0573 +class QAndroidPlatformWindow; 0574 +class QAndroidPlatformBackingStore; 0575 + 0576 +class QAndroidPlatformWindowManager: public QWindow { 0577 +private: 0578 + enum WM_ACTION { 0579 + MOVE = 0, 0580 + HORIZONTAL_RESIZE_LEFT, 0581 + HORIZONTAL_RESIZE_RIGHT, 0582 + VERTICAL_RESIZE, 0583 + CORNER_RESIZE_LEFT, 0584 + CORNER_RESIZE_RIGHT, 0585 + NONE 0586 + }; 0587 +public: 0588 + QAndroidPlatformWindowManager(QAndroidPlatformWindow *window = nullptr); 0589 + ~QAndroidPlatformWindowManager(); 0590 + 0591 + /* 0592 + * Updates the geometry of the window manager as per its child 0593 + * @param geometry of window to be managed, rect should be in native pixels 0594 + */ 0595 + void updateGeometry(const QRect &rect); 0596 + 0597 +protected: 0598 + void resizeEvent(QResizeEvent *event) override; 0599 + void showEvent(QShowEvent *event) override; 0600 + 0601 + void mousePressEvent(QMouseEvent *event) override; 0602 + void mouseMoveEvent(QMouseEvent *event) override; 0603 + void mouseReleaseEvent(QMouseEvent *event) override; 0604 + 0605 +private: 0606 + void repaint(); 0607 + void calculatePressArea(const QPoint &pos); 0608 + void move(const QPoint &pos); 0609 + void resize(const QSize &size); 0610 + void resizeChildWindow(const QRect &geom); 0611 + 0612 +private: 0613 + QAndroidPlatformWindow *m_realWindow; 0614 + QAndroidPlatformBackingStore *m_backingStore; 0615 + 0616 + QPoint m_startingPoint; 0617 + QRect m_startingGeometry; 0618 + QPoint m_realWindowOffset; 0619 + QRect m_oldChildGeometry; 0620 + QSize m_oldSize; 0621 + bool m_mousePressed {false}; // because synthesized events 0622 + WM_ACTION m_grabbedAction { NONE }; 0623 +}; 0624 + 0625 + 0626 +#endif // __QANDROIDPLATFORMWINDOWMANAGER_H_ 0627 -- 0628 2.34.1 0629