diff options
Diffstat (limited to 'src/plugins/platforms/winrt')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtinputcontext.cpp | 29 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtinputcontext.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtintegration.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 83 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.h | 5 |
5 files changed, 103 insertions, 20 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index 3f476556ee..968c47f2c2 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -39,6 +39,7 @@ #include "qwinrtinputcontext.h" #include "qwinrtscreen.h" +#include <QtGui/QGuiApplication> #include <QtGui/QWindow> #include <private/qeventdispatcher_winrt_p.h> @@ -59,7 +60,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods") -inline QRectF getInputPaneRect(IInputPane *pane, qreal scaleFactor) +inline QRectF getInputPaneRect(ComPtr<IInputPane> pane, qreal scaleFactor) { Rect rect; pane->get_OccludedRect(&rect); @@ -85,28 +86,32 @@ QWinRTInputContext::QWinRTInputContext(QWinRTScreen *screen) { qCDebug(lcQpaInputMethods) << __FUNCTION__ << screen; - IInputPaneStatics *statics; + ComPtr<IInputPaneStatics> statics; if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), &statics))) { qWarning("failed to retrieve input pane statics."); return; } - IInputPane *inputPane; + ComPtr<IInputPane> inputPane; statics->GetForCurrentView(&inputPane); - statics->Release(); if (inputPane) { - EventRegistrationToken showToken, hideToken; - inputPane->add_Showing(Callback<InputPaneVisibilityHandler>( - this, &QWinRTInputContext::onShowing).Get(), &showToken); - inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>( - this, &QWinRTInputContext::onHiding).Get(), &hideToken); + QEventDispatcherWinRT::runOnXamlThread([this, inputPane]() { + EventRegistrationToken showToken, hideToken; + inputPane->add_Showing(Callback<InputPaneVisibilityHandler>( + this, &QWinRTInputContext::onShowing).Get(), &showToken); + inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>( + this, &QWinRTInputContext::onHiding).Get(), &hideToken); + return S_OK; + }); m_keyboardRect = getInputPaneRect(inputPane, m_screen->scaleFactor()); m_isInputPanelVisible = !m_keyboardRect.isEmpty(); } else { qWarning("failed to retrieve InputPane."); } + connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged, + this, &QWinRTInputContext::updateScreenCursorRect); } QRectF QWinRTInputContext::keyboardRect() const @@ -119,6 +124,11 @@ bool QWinRTInputContext::isInputPanelVisible() const return m_isInputPanelVisible; } +void QWinRTInputContext::updateScreenCursorRect() +{ + m_screen->setCursorRect(QGuiApplication::inputMethod()->cursorRectangle()); +} + HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *) { qCDebug(lcQpaInputMethods) << __FUNCTION__ << pane; @@ -141,6 +151,7 @@ HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane) const QRectF keyboardRect = getInputPaneRect(pane, m_screen->scaleFactor()); if (m_keyboardRect != keyboardRect) { m_keyboardRect = keyboardRect; + m_screen->setKeyboardRect(m_keyboardRect); emitKeyboardRectChanged(); } return S_OK; diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index 5e416bb99f..9d5c4187e2 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -79,6 +79,9 @@ public: void hideInputPanel(); #endif +private slots: + void updateScreenCursorRect(); + private: HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *, ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *); @@ -89,6 +92,7 @@ private: QWinRTScreen *m_screen; QRectF m_keyboardRect; + QRectF m_cursorRect; bool m_isInputPanelVisible; }; diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 42b7f7e909..32edf2b1a2 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -197,9 +197,9 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) QEventDispatcherWinRT::runOnXamlThread([d]() { d->mainScreen = new QWinRTScreen; - d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); return S_OK; }); + d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); screenAdded(d->mainScreen); d->platformServices = new QWinRTServices; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index ad32c046df..9236de58a1 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -753,12 +753,66 @@ void QWinRTScreen::initialize() onVisibilityChanged(nullptr, nullptr); } +void QWinRTScreen::setCursorRect(const QRectF &cursorRect) +{ + mCursorRect = cursorRect; +} + +void QWinRTScreen::setKeyboardRect(const QRectF &keyboardRect) +{ + Q_D(QWinRTScreen); + QRectF visibleRectF; + HRESULT hr; + Rect windowSize; + + hr = d->coreWindow->get_Bounds(&windowSize); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get window bounds"); + return; + } + d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + Rect visibleRect; + hr = d->view2->get_VisibleBounds(&visibleRect); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get window visible bounds"); + return; + } + visibleRectF = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height); +#else + visibleRectF = d->logicalRect; +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + // if keyboard is snapped to the bottom of the screen and would cover the cursor the content is + // moved up to make it visible + if (keyboardRect.intersects(mCursorRect) + && qFuzzyCompare(geometry().height(), keyboardRect.y() + keyboardRect.height())) { + visibleRectF.moveTop(visibleRectF.top() - keyboardRect.height() / d->scaleFactor); + } + d->visibleRect = visibleRectF; + + qCDebug(lcQpaWindows) << __FUNCTION__ << d->visibleRect; + QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); + QPlatformScreen::resizeMaximizedWindows(); + handleExpose(); +} + QWindow *QWinRTScreen::topWindow() const { Q_D(const QWinRTScreen); return d->visibleWindows.isEmpty() ? 0 : d->visibleWindows.first(); } +QWindow *QWinRTScreen::windowAt(const QPoint &pos) +{ + Q_D(const QWinRTScreen); + for (auto w : qAsConst(d->visibleWindows)) { + if (w->geometry().contains(pos)) + return w; + } + qCDebug(lcQpaWindows) << __FUNCTION__ << ": No window found at:" << pos; + return nullptr; +} + void QWinRTScreen::addWindow(QWindow *window) { Q_D(QWinRTScreen); @@ -767,8 +821,12 @@ void QWinRTScreen::addWindow(QWindow *window) return; d->visibleWindows.prepend(window); - updateWindowTitle(window->title()); - QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); + const Qt::WindowType type = window->type(); + if (type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool) { + updateWindowTitle(window->title()); + QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); + } + handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); @@ -785,7 +843,9 @@ void QWinRTScreen::removeWindow(QWindow *window) const bool wasTopWindow = window == topWindow(); if (!d->visibleWindows.removeAll(window)) return; - if (wasTopWindow) + + const Qt::WindowType type = window->type(); + if (wasTopWindow && type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool) QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); @@ -1001,9 +1061,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) pointerPoint->get_Position(&point); QPointF pos(point.X * d->scaleFactor, point.Y * d->scaleFactor); QPointF localPos = pos; - if (topWindow()) { - const QPointF globalPosDelta = pos - pos.toPoint(); - localPos = topWindow()->mapFromGlobal(pos.toPoint()) + globalPosDelta; + + const QPoint posPoint = pos.toPoint(); + QWindow *targetWindow = windowAt(posPoint); + if (targetWindow) { + const QPointF globalPosDelta = pos - posPoint; + localPos = targetWindow->mapFromGlobal(posPoint) + globalPosDelta; } VirtualKeyModifiers modifiers; @@ -1038,7 +1101,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) boolean isHorizontal; properties->get_IsHorizontalMouseWheel(&isHorizontal); QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta); - QWindowSystemInterface::handleWheelEvent(topWindow(), localPos, pos, QPoint(), angleDelta, mods); + QWindowSystemInterface::handleWheelEvent(targetWindow, localPos, pos, QPoint(), angleDelta, mods); break; } @@ -1064,7 +1127,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) if (isPressed) buttons |= Qt::XButton2; - QWindowSystemInterface::handleMouseEvent(topWindow(), localPos, pos, buttons, mods); + QWindowSystemInterface::handleMouseEvent(targetWindow, localPos, pos, buttons, mods); break; } @@ -1116,7 +1179,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height()); it.value().pressure = pressure; - QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods); + QWindowSystemInterface::handleTouchEvent(targetWindow, d->touchDevice, d->touchPoints.values(), mods); // Fall-through for pen to generate tablet event if (pointerDeviceType != PointerDeviceType_Pen) @@ -1135,7 +1198,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) float rotation; properties->get_Twist(&rotation); - QWindowSystemInterface::handleTabletEvent(topWindow(), isPressed, pos, pos, 0, + QWindowSystemInterface::handleTabletEvent(targetWindow, isPressed, pos, pos, 0, pointerType, pressure, xTilt, yTilt, 0, rotation, 0, id, mods); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 0e753b748b..e489e208d5 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -104,6 +104,7 @@ public: Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; QWindow *topWindow() const; + QWindow *windowAt(const QPoint &pos); void addWindow(QWindow *window); void removeWindow(QWindow *window); void raise(QWindow *window); @@ -116,6 +117,9 @@ public: void initialize(); + void setCursorRect(const QRectF &cursorRect); + void setKeyboardRect(const QRectF &keyboardRect); + private: void handleExpose(); @@ -140,6 +144,7 @@ private: #endif QScopedPointer<QWinRTScreenPrivate> d_ptr; + QRectF mCursorRect; Q_DECLARE_PRIVATE(QWinRTScreen) }; |