diff options
Diffstat (limited to 'src/gui/kernel/qwindowsysteminterface.cpp')
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 139 |
1 files changed, 80 insertions, 59 deletions
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 00343fef66..1875594300 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -138,7 +138,7 @@ static bool handleWindowSystemEvent(Args ...args) return QWindowSystemHelper<Delivery>::template handleEvent<EventType>(args...); } -int QWindowSystemInterfacePrivate::windowSystemEventsQueued() +qsizetype QWindowSystemInterfacePrivate::windowSystemEventsQueued() { return windowSystemEventQueue.count(); } @@ -240,9 +240,9 @@ void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leav handleEnterEvent(enter, local, global); } -QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::FocusReason r) +QT_DEFINE_QPA_EVENT_HANDLER(void, handleFocusWindowChanged, QWindow *window, Qt::FocusReason r) { - handleWindowSystemEvent<QWindowSystemInterfacePrivate::ActivatedWindowEvent, Delivery>(window, r); + handleWindowSystemEvent<QWindowSystemInterfacePrivate::FocusWindowEvent, Delivery>(window, r); } QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowStates newState, int oldState) @@ -389,61 +389,34 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong times Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { - Q_ASSERT_X(type != QEvent::MouseButtonDblClick && type != QEvent::NonClientAreaMouseButtonDblClick, - "QWindowSystemInterface::handleMouseEvent", - "QTBUG-71263: Native double clicks are not implemented."); - auto localPos = QHighDpi::fromNativeLocalPosition(local, window); - auto globalPos = QHighDpi::fromNativeGlobalPosition(global, window); - - return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent, Delivery>(window, - timestamp, localPos, globalPos, state, mods, button, type, source, false, device); -} -bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, - const QPointF &local, const QPointF &global, - Qt::MouseButtons state, - Qt::MouseButton button, QEvent::Type type, - Qt::KeyboardModifiers mods, - Qt::MouseEventSource source) -{ - const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - return handleFrameStrutMouseEvent(window, time, local, global, state, button, type, mods, source); -} + bool isNonClientArea = {}; -bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, const QPointingDevice *device, - const QPointF &local, const QPointF &global, - Qt::MouseButtons state, - Qt::MouseButton button, QEvent::Type type, - Qt::KeyboardModifiers mods, - Qt::MouseEventSource source) -{ - const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - return handleFrameStrutMouseEvent(window, time, device, local, global, state, button, type, mods, source); -} - -bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, - const QPointF &local, const QPointF &global, - Qt::MouseButtons state, - Qt::MouseButton button, QEvent::Type type, - Qt::KeyboardModifiers mods, - Qt::MouseEventSource source) -{ - return handleFrameStrutMouseEvent(window, timestamp, QPointingDevice::primaryPointingDevice(), - local, global, state, button, type, mods, source); -} + switch (type) { + case QEvent::MouseButtonDblClick: + case QEvent::NonClientAreaMouseButtonDblClick: + Q_ASSERT_X(false, "QWindowSystemInterface::handleMouseEvent", + "QTBUG-71263: Native double clicks are not implemented."); + return false; + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + isNonClientArea = false; + break; + case QEvent::NonClientAreaMouseMove: + case QEvent::NonClientAreaMouseButtonPress: + case QEvent::NonClientAreaMouseButtonRelease: + isNonClientArea = true; + break; + default: + Q_UNREACHABLE(); + } -bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointingDevice *device, - const QPointF &local, const QPointF &global, - Qt::MouseButtons state, - Qt::MouseButton button, QEvent::Type type, - Qt::KeyboardModifiers mods, - Qt::MouseEventSource source) -{ auto localPos = QHighDpi::fromNativeLocalPosition(local, window); auto globalPos = QHighDpi::fromNativeGlobalPosition(global, window); - return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent>(window, - timestamp, localPos, globalPos, state, mods, button, type, source, true, device); + return handleWindowSystemEvent<QWindowSystemInterfacePrivate::MouseEvent, Delivery>(window, + timestamp, localPos, globalPos, state, mods, button, type, source, isNonClientArea, device); } bool QWindowSystemInterface::handleShortcutEvent(QWindow *window, ulong timestamp, int keyCode, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, @@ -738,9 +711,9 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong The screen should be deleted by calling QWindowSystemInterface::handleScreenRemoved(). */ -void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrimary) +void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *platformScreen, bool isPrimary) { - QScreen *screen = new QScreen(ps); + QScreen *screen = new QScreen(platformScreen); if (isPrimary) QGuiApplicationPrivate::screen_list.prepend(screen); @@ -767,9 +740,45 @@ void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrima */ void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen) { - // Important to keep this order since the QSceen doesn't own the platform screen. - // The QScreen destructor will take care changing the primary screen, so no need here. - delete platformScreen->screen(); + QScreen *screen = platformScreen->screen(); + + // Remove screen + const bool wasPrimary = QGuiApplication::primaryScreen() == screen; + QGuiApplicationPrivate::screen_list.removeOne(screen); + QGuiApplicationPrivate::resetCachedDevicePixelRatio(); + + if (qGuiApp) { + QScreen *newPrimaryScreen = QGuiApplication::primaryScreen(); + if (wasPrimary && newPrimaryScreen) + emit qGuiApp->primaryScreenChanged(newPrimaryScreen); + + // Allow clients to manage windows that are affected by the screen going + // away, before we fall back to moving them to the primary screen. + emit qApp->screenRemoved(screen); + + if (!QGuiApplication::closingDown()) { + bool movingFromVirtualSibling = newPrimaryScreen + && newPrimaryScreen->handle()->virtualSiblings().contains(platformScreen); + + // Move any leftover windows to the primary screen + const auto allWindows = QGuiApplication::allWindows(); + for (QWindow *window : allWindows) { + if (!window->isTopLevel() || window->screen() != screen) + continue; + + const bool wasVisible = window->isVisible(); + window->setScreen(newPrimaryScreen); + + // Re-show window if moved from a virtual sibling screen. Otherwise + // leave it up to the application developer to show the window. + if (movingFromVirtualSibling) + window->setVisible(wasVisible); + } + } + } + + // Important to keep this order since the QSceen doesn't own the platform screen + delete screen; delete platformScreen; } @@ -782,7 +791,7 @@ void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen void QWindowSystemInterface::handlePrimaryScreenChanged(QPlatformScreen *newPrimary) { QScreen *newPrimaryScreen = newPrimary->screen(); - int indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen); + qsizetype indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen); Q_ASSERT(indexOfScreen >= 0); if (indexOfScreen == 0) return; @@ -805,6 +814,11 @@ void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const Q void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY) { + // Keep QHighDpiScaling::m_active in sync with platform screen state, in + // order to make scaling calls made during DPI change use the new state. + // FIXME: Remove when QHighDpiScaling::m_active has been removed. + QHighDpiScaling::updateHighDpiScaling(); + const QDpi effectiveDpi = QPlatformScreen::overrideDpi(QDpi{dpiX, dpiY}); handleWindowSystemEvent<QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent>(screen, effectiveDpi.first, effectiveDpi.second); @@ -1049,7 +1063,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo */ bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) { - const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count(); + const qsizetype count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count(); if (!count) return false; if (!QGuiApplication::instance()) { @@ -1196,6 +1210,13 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int #endif } +Q_GUI_EXPORT void qt_handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, + QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, + Qt::ScrollPhase phase) +{ + QWindowSystemInterface::handleWheelEvent(window, local, global, pixelDelta, angleDelta, mods, phase); +} + namespace QTest { Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType, |