diff options
Diffstat (limited to 'src/client/qwaylandwindow.cpp')
-rw-r--r-- | src/client/qwaylandwindow.cpp | 170 |
1 files changed, 73 insertions, 97 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 4532bc236..9bc400f8a 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -41,6 +41,7 @@ #include "qwaylandbuffer_p.h" #include "qwaylanddisplay_p.h" +#include "qwaylandsurface_p.h" #include "qwaylandinputdevice_p.h" #include "qwaylandscreen_p.h" #include "qwaylandshellsurface_p.h" @@ -80,7 +81,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window) { static WId id = 1; mWindowId = id++; - connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandWindow::handleScreenRemoved); initializeWlSurface(); } @@ -90,7 +90,7 @@ QWaylandWindow::~QWaylandWindow() delete mWindowDecoration; - if (isInitialized()) + if (mSurface) reset(false); const QWindow *parent = window(); @@ -115,7 +115,7 @@ void QWaylandWindow::initWindow() if (window()->type() == Qt::Desktop) return; - if (!isInitialized()) { + if (!mSurface) { initializeWlSurface(); QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); QGuiApplication::sendEvent(window(), &e); @@ -181,7 +181,7 @@ void QWaylandWindow::initWindow() // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale() // to inform the compositor that high-resolution buffers will be provided. if (mDisplay->compositorVersion() >= 3) - set_buffer_scale(scale()); + mSurface->set_buffer_scale(scale()); if (QScreen *s = window()->screen()) setOrientationMask(s->orientationUpdateMask()); @@ -199,7 +199,11 @@ void QWaylandWindow::initWindow() void QWaylandWindow::initializeWlSurface() { - init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); + Q_ASSERT(!mSurface); + mSurface.reset(new QWaylandSurface(mDisplay)); + connect(mSurface.data(), &QWaylandSurface::screensChanged, + this, &QWaylandWindow::handleScreensChanged); + mSurface->m_window = this; } bool QWaylandWindow::shouldCreateShellSurface() const @@ -226,7 +230,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const void QWaylandWindow::reset(bool sendDestroyEvent) { - if (isInitialized() && sendDestroyEvent) { + if (mSurface && sendDestroyEvent) { QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); QGuiApplication::sendEvent(window(), &e); } @@ -234,11 +238,10 @@ void QWaylandWindow::reset(bool sendDestroyEvent) mShellSurface = nullptr; delete mSubSurfaceWindow; mSubSurfaceWindow = nullptr; - if (isInitialized()) { + if (mSurface) { emit wlSurfaceDestroyed(); - destroy(); + mSurface.reset(); } - mScreens.clear(); if (mFrameCallback) { wl_callback_destroy(mFrameCallback); @@ -251,7 +254,9 @@ void QWaylandWindow::reset(bool sendDestroyEvent) QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) { - return static_cast<QWaylandWindow *>(static_cast<QtWayland::wl_surface *>(wl_surface_get_user_data(surface))); + if (auto *s = QWaylandSurface::fromWlSurface(surface)) + return s->m_window; + return nullptr; } WId QWaylandWindow::winId() const @@ -381,7 +386,12 @@ void QWaylandWindow::closePopups(QWaylandWindow *parent) QWaylandScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const { - return mScreens.isEmpty() ? waylandScreen() : mScreens.first(); + if (mSurface) { + if (auto *screen = mSurface->oldestEnteredScreen()) + return screen; + } + + return waylandScreen(); } void QWaylandWindow::setVisible(bool visible) @@ -425,18 +435,18 @@ void QWaylandWindow::setMask(const QRegion &mask) mMask = mask; - if (!isInitialized()) + if (!mSurface) return; if (mMask.isEmpty()) { - set_input_region(nullptr); + mSurface->set_input_region(nullptr); } else { struct ::wl_region *region = mDisplay->createRegion(mMask); - set_input_region(region); + mSurface->set_input_region(region); wl_region_destroy(region); } - wl_surface::commit(); + mSurface->commit(); } void QWaylandWindow::applyConfigureWhenPossible() @@ -490,58 +500,6 @@ void QWaylandWindow::applyConfigure() QWindowSystemInterface::flushWindowSystemEvents(); } -void QWaylandWindow::surface_enter(wl_output *output) -{ - QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents(); - auto addedScreen = QWaylandScreen::fromWlOutput(output); - - if (mScreens.contains(addedScreen)) { - qCWarning(lcQpaWayland) - << "Ignoring unexpected wl_surface.enter received for output with id:" - << wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output)) - << "screen name:" << addedScreen->name() << "screen model:" << addedScreen->model() - << "This is most likely a bug in the compositor."; - return; - } - - mScreens.append(addedScreen); - - QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); - if (oldScreen != newScreen) //currently this will only happen if the first wl_surface.enter is for a non-primary screen - handleScreenChanged(); -} - -void QWaylandWindow::surface_leave(wl_output *output) -{ - QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents(); - auto *removedScreen = QWaylandScreen::fromWlOutput(output); - bool wasRemoved = mScreens.removeOne(removedScreen); - if (!wasRemoved) { - qCWarning(lcQpaWayland) - << "Ignoring unexpected wl_surface.leave received for output with id:" - << wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output)) - << "screen name:" << removedScreen->name() - << "screen model:" << removedScreen->model() - << "This is most likely a bug in the compositor."; - return; - } - - QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); - if (oldScreen != newScreen) - handleScreenChanged(); -} - -void QWaylandWindow::handleScreenRemoved(QScreen *qScreen) -{ - QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents(); - bool wasRemoved = mScreens.removeOne(static_cast<QWaylandScreen *>(qScreen->handle())); - if (wasRemoved) { - QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); - if (oldScreen != newScreen) - handleScreenChanged(); - } -} - void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { Q_ASSERT(!buffer->committed()); @@ -549,9 +507,9 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) handleUpdate(); buffer->setBusy(); - QtWayland::wl_surface::attach(buffer->buffer(), x, y); + mSurface->attach(buffer->buffer(), x, y); } else { - QtWayland::wl_surface::attach(nullptr, 0, 0); + mSurface->attach(nullptr, 0, 0); } } @@ -563,7 +521,7 @@ void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) void QWaylandWindow::damage(const QRect &rect) { - damage(rect.x(), rect.y(), rect.width(), rect.height()); + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); } void QWaylandWindow::safeCommit(QWaylandBuffer *buffer, const QRegion &damage) @@ -593,20 +551,20 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) qCDebug(lcWaylandBackingstore) << "Buffer already committed, ignoring."; return; } - if (!isInitialized()) + if (!mSurface) return; attachOffset(buffer); for (const QRect &rect: damage) - wl_surface::damage(rect.x(), rect.y(), rect.width(), rect.height()); + mSurface->damage(rect.x(), rect.y(), rect.width(), rect.height()); Q_ASSERT(!buffer->committed()); buffer->setCommitted(); - wl_surface::commit(); + mSurface->commit(); } void QWaylandWindow::commit() { - wl_surface::commit(); + mSurface->commit(); } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -691,6 +649,11 @@ QRect QWaylandWindow::windowContentGeometry() const return QRect(QPoint(), surfaceSize()); } +wl_surface *QWaylandWindow::wlSurface() +{ + return mSurface ? mSurface->object() : nullptr; +} + QWaylandShellSurface *QWaylandWindow::shellSurface() const { return mShellSurface; @@ -732,9 +695,9 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orient default: Q_UNREACHABLE(); } - set_buffer_transform(transform); + mSurface->set_buffer_transform(transform); // set_buffer_transform is double buffered, we need to commit. - wl_surface::commit(); + mSurface->commit(); } void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations mask) @@ -866,6 +829,18 @@ QWaylandWindow *QWaylandWindow::transientParent() const void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e) { + if (e.type == QWaylandPointerEvent::Leave) { + if (mWindowDecoration) { + if (mMouseEventsInContentArea) + QWindowSystemInterface::handleLeaveEvent(window()); + } else { + QWindowSystemInterface::handleLeaveEvent(window()); + } +#if QT_CONFIG(cursor) + restoreMouseCursor(inputDevice); +#endif + return; + } if (mWindowDecoration) { handleMouseEventWithDecoration(inputDevice, e); @@ -874,11 +849,15 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan case QWaylandPointerEvent::Enter: QWindowSystemInterface::handleEnterEvent(window(), e.local, e.global); break; + case QWaylandPointerEvent::Press: + case QWaylandPointerEvent::Release: case QWaylandPointerEvent::Motion: QWindowSystemInterface::handleMouseEvent(window(), e.timestamp, e.local, e.global, e.buttons, e.modifiers); break; case QWaylandPointerEvent::Wheel: - QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, e.local, e.global, e.pixelDelta, e.angleDelta, e.modifiers); + QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, e.local, e.global, + e.pixelDelta, e.angleDelta, e.modifiers, + e.phase, e.source, false); break; } } @@ -892,20 +871,6 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan #endif } -void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice) -{ - if (mWindowDecoration) { - if (mMouseEventsInContentArea) { - QWindowSystemInterface::handleLeaveEvent(window()); - } - } else { - QWindowSystemInterface::handleLeaveEvent(window()); - } -#if QT_CONFIG(cursor) - restoreMouseCursor(inputDevice); -#endif -} - bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods) { if (!mWindowDecoration) @@ -947,12 +912,18 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe case QWaylandPointerEvent::Enter: QWindowSystemInterface::handleEnterEvent(window(), localTranslated, globalTranslated); break; + case QWaylandPointerEvent::Press: + case QWaylandPointerEvent::Release: case QWaylandPointerEvent::Motion: QWindowSystemInterface::handleMouseEvent(window(), e.timestamp, localTranslated, globalTranslated, e.buttons, e.modifiers); break; - case QWaylandPointerEvent::Wheel: - QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, localTranslated, globalTranslated, e.pixelDelta, e.angleDelta, e.modifiers); + case QWaylandPointerEvent::Wheel: { + QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, + localTranslated, globalTranslated, + e.pixelDelta, e.angleDelta, e.modifiers, + e.phase, e.source, false); break; + } } mMouseEventsInContentArea = true; @@ -965,16 +936,21 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe } } -void QWaylandWindow::handleScreenChanged() +void QWaylandWindow::handleScreensChanged() { QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); + + if (newScreen == mLastReportedScreen) + return; + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + mLastReportedScreen = newScreen; int scale = newScreen->scale(); if (scale != mScale) { mScale = scale; - if (isInitialized() && mDisplay->compositorVersion() >= 3) - set_buffer_scale(mScale); + if (mSurface && mDisplay->compositorVersion() >= 3) + mSurface->set_buffer_scale(mScale); ensureSize(); } } @@ -1158,7 +1134,7 @@ void QWaylandWindow::handleUpdate() QMetaObject::invokeMethod(this, [=] { killTimer(id); }, Qt::QueuedConnection); } - mFrameCallback = frame(); + mFrameCallback = mSurface->frame(); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); mWaitingForFrameCallback = true; mWaitingForUpdate = false; |