summaryrefslogtreecommitdiffstats
path: root/src/client/qwaylandwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/qwaylandwindow.cpp')
-rw-r--r--src/client/qwaylandwindow.cpp170
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;