diff options
Diffstat (limited to 'src/plugins')
70 files changed, 780 insertions, 529 deletions
diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp index c5712d65b..f82ad6f97 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp @@ -50,7 +50,7 @@ #include "wayland-brcm-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandBrcmEglIntegration::QWaylandBrcmEglIntegration(QWaylandDisplay *waylandDisplay) : m_waylandDisplay(waylandDisplay->wl_display()) @@ -62,13 +62,13 @@ QWaylandBrcmEglIntegration::QWaylandBrcmEglIntegration(QWaylandDisplay *waylandD void QWaylandBrcmEglIntegration::wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_brcm") { + if (interface == "qt_brcm") { QWaylandBrcmEglIntegration *integration = static_cast<QWaylandBrcmEglIntegration *>(data); - integration->m_waylandBrcm = static_cast<struct wl_brcm *>(wl_registry_bind(registry, id, &wl_brcm_interface, 1)); + integration->m_waylandBrcm = static_cast<struct qt_brcm *>(wl_registry_bind(registry, id, &qt_brcm_interface, 1)); } } -wl_brcm *QWaylandBrcmEglIntegration::waylandBrcm() const +qt_brcm *QWaylandBrcmEglIntegration::waylandBrcm() const { return m_waylandBrcm; } @@ -129,3 +129,4 @@ QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDispla return new QWaylandBrcmEglIntegration(waylandDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h index fd971ffb9..f1100d8de 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWindow; -struct wl_brcm; +struct qt_brcm; class QWaylandBrcmEglIntegration : public QWaylandGLIntegration { @@ -74,7 +74,7 @@ public: EGLDisplay eglDisplay() const; - struct wl_brcm *waylandBrcm() const; + struct qt_brcm *waylandBrcm() const; PFNEGLFLUSHBRCMPROC eglFlushBRCM; PFNEGLCREATEGLOBALIMAGEBRCMPROC eglCreateGlobalImageBRCM; @@ -84,7 +84,7 @@ private: static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); struct wl_display *m_waylandDisplay; - struct wl_brcm *m_waylandBrcm; + struct qt_brcm *m_waylandBrcm; EGLDisplay m_eglDisplay; }; diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp index 0b2f4d316..31db4328b 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp @@ -50,22 +50,18 @@ #include <QtGui/QWindow> #include <qpa/qwindowsysteminterface.h> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext_brcm.h> #include "wayland-brcm-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWaylandBrcmBuffer : public QWaylandBuffer { public: QWaylandBrcmBuffer(QWaylandDisplay *display, - struct wl_brcm *brcm, + struct qt_brcm *brcm, const QSize &size, EGLint *data, int count) @@ -79,7 +75,7 @@ public: for (int i = 0; i < count; ++i) m_data[i] = data[i]; - mBuffer = wl_brcm_create_buffer(brcm, size.width(), size.height(), &m_array); + mBuffer = qt_brcm_create_buffer(brcm, size.width(), size.height(), &m_array); static const struct wl_buffer_listener buffer_listener = { QWaylandBrcmBuffer::buffer_release @@ -294,3 +290,4 @@ bool QWaylandBrcmEglWindow::makeCurrent(EGLContext context) return eglMakeCurrent(m_eglIntegration->eglDisplay(), m_eglSurfaces[m_current], m_eglSurfaces[m_current], context); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h index e8fcfbaa2..02abd244f 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class QWaylandGLContext; class QWaylandBrcmBuffer; -class QWaylandBrcmEglWindow : public QObject, public QWaylandWindow +class QWaylandBrcmEglWindow : public QWaylandWindow { Q_OBJECT public: diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp index 14b989870..dfb86e54c 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp @@ -50,7 +50,7 @@ #include <qpa/qplatformopenglcontext.h> #include <QtGui/QSurfaceFormat> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE extern QSurfaceFormat brcmFixFormat(const QSurfaceFormat &format); @@ -102,3 +102,4 @@ EGLConfig QWaylandBrcmGLContext::eglConfig() const return m_config; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp b/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp index 7a65f89c3..07f6d586e 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp @@ -50,7 +50,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) : m_waylandDisplay(waylandDisplay) @@ -107,3 +107,5 @@ QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDispla { return new QWaylandEglIntegration(waylandDisplay->wl_display()); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp index 9c39ec956..7829f381a 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp @@ -52,11 +52,7 @@ #include <QOpenGLFramebufferObject> #include <QOpenGLContext> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandEglWindow::QWaylandEglWindow(QWindow *window) : QWaylandWindow(window) @@ -104,7 +100,7 @@ void QWaylandEglWindow::setGeometry(const QRect &rect) m_resize = true; } } else { - m_waylandEglWindow = wl_egl_window_create(wl_surface(), sizeWithMargins.width(), sizeWithMargins.height()); + m_waylandEglWindow = wl_egl_window_create(object(), sizeWithMargins.width(), sizeWithMargins.height()); } QWaylandWindow::setGeometry(rect); @@ -129,7 +125,7 @@ EGLSurface QWaylandEglWindow::eglSurface() const self->createDecoration(); QMargins margins = frameMargins(); QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); - m_waylandEglWindow = wl_egl_window_create(self->wl_surface(), sizeWithMargins.width(), sizeWithMargins.height()); + m_waylandEglWindow = wl_egl_window_create(self->object(), sizeWithMargins.width(), sizeWithMargins.height()); } if (!m_eglSurface) { @@ -171,3 +167,5 @@ void QWaylandEglWindow::bindContentFBO() m_contentFBO->bind(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp index e28f0d172..303e59f76 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp @@ -55,7 +55,7 @@ #include <QtGui/QSurfaceFormat> #include <QtGui/QOpenGLShaderProgram> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) : QPlatformOpenGLContext() @@ -64,7 +64,6 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) , m_blitProgram(0) , m_textureCache(0) - , m_currentOnSurface(0) { m_shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; @@ -93,20 +92,12 @@ QWaylandGLContext::~QWaylandGLContext() bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) { QWaylandEglWindow *window = static_cast<QWaylandEglWindow *>(surface); - if (m_currentOnSurface != window) { - if (m_currentOnSurface) { - QWaylandWindow *oldWindow = m_currentOnSurface; - m_currentOnSurface = 0; - oldWindow->resizeMutex()->unlock(); - } - window->resizeMutex()->lock(); - m_currentOnSurface = window; - } + + window->setCanResize(false); EGLSurface eglSurface = window->eglSurface(); if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) { qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this); - m_currentOnSurface->resizeMutex()->unlock(); return false; } @@ -118,11 +109,6 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) void QWaylandGLContext::doneCurrent() { eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (m_currentOnSurface) { - QWaylandWindow *window = m_currentOnSurface; - m_currentOnSurface = 0; - window->resizeMutex()->unlock(); - } } void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) @@ -218,11 +204,8 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) } eglSwapBuffers(m_eglDisplay, eglSurface); - if (m_currentOnSurface == window) { - m_currentOnSurface = 0; - window->resizeMutex()->unlock(); - } + window->setCanResize(true); } GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const @@ -250,3 +233,4 @@ EGLConfig QWaylandGLContext::eglConfig() const return m_config; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h index b42168303..bc231e82d 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h +++ b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h @@ -86,8 +86,6 @@ private: QSurfaceFormat m_format; QOpenGLShaderProgram *m_blitProgram; QOpenGLTextureCache *m_textureCache; - - QWaylandWindow *m_currentOnSurface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro index e41cf59b4..b691ec9dc 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro @@ -6,10 +6,6 @@ include (../xcomposite_share/xcomposite_share.pri) OTHER_FILES += qwayland-xcomposite-egl.json -contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - WAYLANDCLIENTSOURCES += ../../../extensions/windowmanager.xml -} - !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += xcomposite egl x11 diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp index 635e47c06..8d4a99b97 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp @@ -48,7 +48,7 @@ #include <QtPlatformSupport/private/qeglconvenience_p.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) : QEGLPlatformContext(format, share, display, q_configFromGLFormat(display, format, true, EGL_WINDOW_BIT | EGL_PIXMAP_BIT), EGL_OPENGL_ES_API) @@ -65,6 +65,7 @@ void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface) QSize size = w->geometry().size(); w->damage(QRect(QPoint(), size)); + w->commit(); w->waitForFrameSync(); } @@ -72,3 +73,5 @@ EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformS { return static_cast<QWaylandXCompositeEGLWindow *>(surface)->eglSurface(); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp index c2ea9a934..cd3a06ff8 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp @@ -47,7 +47,7 @@ #include "wayland-xcomposite-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { @@ -117,7 +117,7 @@ const struct qt_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_xcomposite") { + if (interface == "qt_xcomposite") { QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); integration->mWaylandComposite = static_cast<struct qt_xcomposite *>(wl_registry_bind(registry,id,&qt_xcomposite_interface,1)); qt_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); @@ -143,3 +143,4 @@ void QWaylandXCompositeEGLIntegration::rootInformation(void *data, qt_xcomposite qDebug() << "ROOT INFORMATION" << integration->mDisplay << integration->mRootWindow << integration->mScreen; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h index d7d1d4912..ba36fac3f 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h @@ -58,7 +58,13 @@ #include <X11/Xlib.h> #include <EGL/egl.h> -struct wl_xcomposite; +// avoid clashes with Qt::CursorShape +#ifdef CursorShape +# define X_CursorShape CursorShape +# undef CursorShape +#endif + +struct qt_xcomposite; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp index f1768991f..f0df2bd2d 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp @@ -50,13 +50,9 @@ #include <X11/extensions/Xcomposite.h> #include "qwaylandxcompositeeglintegration.h" -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration) : QWaylandWindow(window) @@ -138,11 +134,4 @@ void QWaylandXCompositeEGLWindow::createEglSurface() attach(m_buffer, 0, 0); } -void QWaylandXCompositeEGLWindow::requestActivateWindow() -{ -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - mDisplay->windowManagerIntegration()->authenticateWithToken(); -#endif - - QWaylandWindow::requestActivateWindow(); -} +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h index 98f0ed736..8fb631185 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h @@ -57,7 +57,6 @@ public: WindowType windowType() const; void setGeometry(const QRect &rect); - void requestActivateWindow(); EGLSurface eglSurface() const; diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp index bc3167b9f..6854dc3b2 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp @@ -47,7 +47,7 @@ #include <QRegion> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen) : m_display(display) @@ -81,6 +81,7 @@ void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface) glXSwapBuffers(m_display, w->xWindow()); w->damage(QRect(QPoint(), size)); + w->commit(); w->waitForFrameSync(); } @@ -94,3 +95,4 @@ QSurfaceFormat QWaylandXCompositeGLXContext::format() const return m_format; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp index e3316d96f..2e8b444f9 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp @@ -47,7 +47,7 @@ #include "wayland-xcomposite-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { @@ -103,28 +103,28 @@ QWaylandDisplay * QWaylandXCompositeGLXIntegration::waylandDisplay() const { return mWaylandDisplay; } -wl_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const +qt_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const { return mWaylandComposite; } -const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = { +const struct qt_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = { QWaylandXCompositeGLXIntegration::rootInformation }; void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_xcomposite") { - qDebug("XComposite-GLX: got wl_xcomposite global"); + if (interface == "qt_xcomposite") { + qDebug("XComposite-GLX: got qt_xcomposite global"); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); - integration->mWaylandComposite = static_cast<struct wl_xcomposite *>(wl_registry_bind(registry, id, &wl_xcomposite_interface, 1)); - wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); + integration->mWaylandComposite = static_cast<struct qt_xcomposite *>(wl_registry_bind(registry, id, &qt_xcomposite_interface, 1)); + qt_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); } } -void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window) +void QWaylandXCompositeGLXIntegration::rootInformation(void *data, qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window) { Q_UNUSED(xcomposite); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); @@ -136,3 +136,4 @@ void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite integration->mScreen = XDefaultScreen(integration->mDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h index 066295c12..aeb7c66de 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h @@ -53,7 +53,13 @@ #include <X11/Xlib.h> -struct wl_xcomposite; +// avoid clashes with Qt::CursorShape +#ifdef CursorShape +# define X_CursorShape CursorShape +# undef CursorShape +#endif + +struct qt_xcomposite; QT_BEGIN_NAMESPACE @@ -70,7 +76,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; - struct wl_xcomposite *waylandXComposite() const; + struct qt_xcomposite *waylandXComposite() const; Display *xDisplay() const; int screen() const; @@ -80,7 +86,7 @@ public: private: QWaylandDisplay *mWaylandDisplay; - struct wl_xcomposite *mWaylandComposite; + struct qt_xcomposite *mWaylandComposite; Display *mDisplay; int mScreen; @@ -89,9 +95,9 @@ private: static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); - static const struct wl_xcomposite_listener xcomposite_listener; + static const struct qt_xcomposite_listener xcomposite_listener; static void rootInformation(void *data, - struct wl_xcomposite *xcomposite, + struct qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window); }; diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp index c142a3639..3a64961f1 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp @@ -49,7 +49,7 @@ #include <X11/extensions/Xcomposite.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration) : QWaylandWindow(window) @@ -120,3 +120,5 @@ void QWaylandXCompositeGLXWindow::createSurface() size); attach(m_buffer, 0, 0); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp b/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp index 31fe60455..4cf055d30 100644 --- a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp @@ -46,7 +46,7 @@ #include "qwaylanddatasource.h" #include "qwaylanddatadevicemanager.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) : mDisplay(display) @@ -82,3 +82,4 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const return mode == QClipboard::Clipboard; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp index 9ea1836b7..e0abba304 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp @@ -51,7 +51,7 @@ #include <wayland-cursor.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) : mDisplay(screen->display()) @@ -74,12 +74,17 @@ QWaylandCursor::~QWaylandCursor() wl_cursor_theme_destroy(mCursorTheme); } -void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape) { - Q_UNUSED(window) - struct wl_cursor *waylandCursor = 0; - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + + /* Hide cursor */ + if (newShape == Qt::BlankCursor) + { + mDisplay->setCursor(NULL, NULL); + return NULL; + } + if (newShape < Qt::BitmapCursor) { waylandCursor = requestCursor((WaylandCursor)newShape); } else if (newShape == Qt::BitmapCursor) { @@ -90,17 +95,31 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) if (!waylandCursor) { qDebug("Could not find cursor for shape %d", newShape); - return; + return NULL; } struct wl_cursor_image *image = waylandCursor->images[0]; - struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); if (!buffer) { qDebug("Could not find buffer for cursor"); + return NULL; + } + + return image; +} + +void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +{ + Q_UNUSED(window) + + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + + struct wl_cursor_image *image = cursorImage(newShape); + if (!image) { return; } + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); mDisplay->setCursor(buffer, image); } @@ -132,9 +151,6 @@ void QWaylandCursor::setPos(const QPoint &pos) wl_cursor *QWaylandCursor::requestCursor(WaylandCursor shape) { - if (shape == BlankCursor) - return 0; - struct wl_cursor *cursor = mCursors.value(shape, 0); //If the cursor has not been loaded already, load it @@ -277,3 +293,5 @@ void QWaylandCursor::initCursorMap() mCursorNamesMap.insert(ResizeSouthWestCursor, "sw-resize"); mCursorNamesMap.insert(ResizeSouthWestCursor, "bottom_left_corner"); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.h b/src/plugins/platforms/wayland_common/qwaylandcursor.h index df5dcbe39..ceb6d7488 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.h +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.h @@ -45,11 +45,14 @@ #include <qpa/qplatformcursor.h> #include <QMap> +struct wl_cursor; +struct wl_cursor_image; +struct wl_cursor_theme; + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandScreen; -struct wl_cursor_theme; class QWaylandCursor : public QPlatformCursor { @@ -62,6 +65,8 @@ public: QPoint pos() const; void setPos(const QPoint &pos); + struct wl_cursor_image *cursorImage(Qt::CursorShape shape); + private: enum WaylandCursor { ArrowCursor = Qt::ArrowCursor, diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp index 901069c5c..8674aae9e 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp @@ -58,12 +58,13 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataDeviceManager::data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *id) { + Q_UNUSED(data_device); QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data); new QWaylandDataOffer(handler->display(),id); @@ -322,4 +323,4 @@ struct wl_data_device_manager *QWaylandDataDeviceManager::handle() const return m_data_device_manager; } - +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp b/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp index d2080ea55..d98cfc2ab 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataOffer::offer_sync_callback(void *data, struct wl_callback *callback, @@ -143,3 +143,5 @@ struct wl_data_offer *QWaylandDataOffer::handle() const { return m_data_offer; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h b/src/plugins/platforms/wayland_common/qwaylanddataoffer.h index fada683a2..abc7c690a 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h +++ b/src/plugins/platforms/wayland_common/qwaylanddataoffer.h @@ -52,6 +52,9 @@ #include <stdint.h> struct wl_callback; +struct wl_callback_listener; +struct wl_data_offer; +struct wl_data_offer_listener; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp index ad280b03c..7bf8b0c96 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp @@ -50,7 +50,7 @@ #include <unistd.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataSource::data_source_target(void *data, struct wl_data_source *wl_data_source, @@ -117,3 +117,5 @@ struct wl_data_source *QWaylandDataSource::handle() const { return m_data_source; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp index f5f79ae67..a4b978330 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp @@ -44,6 +44,7 @@ #include "qwaylandwindow.h" #include "qwaylandshellsurface.h" #include "qwaylandinputdevice.h" +#include "qwaylandscreen.h" #include <QtGui/QGuiApplication> #include <QtGui/QImage> @@ -52,7 +53,7 @@ #include <QtGui/QPalette> #include <QtGui/QLinearGradient> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE #define BUTTON_SPACING 5 @@ -128,7 +129,6 @@ QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window) , m_isDirty(true) , m_decorationContentImage(0) , m_margins(3,30,3,3) - , m_hasSetCursor(false) , m_mouseButtons(Qt::NoButton) { m_wayland_window->setDecoration(this); @@ -312,7 +312,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo // Figure out what area mouse is in if (closeButtonRect().contains(local) && isLeftClicked(b)) { - QCoreApplication::postEvent(m_window, new QCloseEvent()); + QWindowSystemInterface::handleCloseEvent(m_window); } else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) { m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized); } else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) { @@ -326,7 +326,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo } else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) { processMouseRight(inputDevice,local,b,mods); } else { - restoreMouseCursor(); + m_wayland_window->restoreMouseCursor(inputDevice); return false; } @@ -334,15 +334,6 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo return true; } -void QWaylandDecoration::restoreMouseCursor() -{ - if (m_hasSetCursor) { - overrideCursor(Qt::ArrowCursor); - QGuiApplication::restoreOverrideCursor(); - m_hasSetCursor = false; - } -} - bool QWaylandDecoration::inMouseButtonPressedState() const { return m_mouseButtons & Qt::NoButton; @@ -370,19 +361,19 @@ void QWaylandDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const if (local.y() <= m_margins.bottom()) { if (local.x() <= margins().left()) { //top left bit - overrideCursor(Qt::SizeFDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b); } else if (local.x() > m_window->width() - margins().right()) { //top right bit - overrideCursor(Qt::SizeBDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b); } else { //top reszie bit - overrideCursor(Qt::SplitVCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b); } } else { - restoreMouseCursor(); + m_wayland_window->restoreMouseCursor(inputDevice); startMove(inputDevice,b); } @@ -393,15 +384,15 @@ void QWaylandDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, co Q_UNUSED(mods); if (local.x() <= margins().left()) { //bottom left bit - overrideCursor(Qt::SizeBDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b); } else if (local.x() > m_window->width() - margins().right()) { //bottom right bit - overrideCursor(Qt::SizeFDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b); } else { //bottom bit - overrideCursor(Qt::SplitVCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b); } } @@ -410,7 +401,7 @@ void QWaylandDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, cons { Q_UNUSED(local); Q_UNUSED(mods); - overrideCursor(Qt::SplitHCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b); } @@ -418,7 +409,7 @@ void QWaylandDecoration::processMouseRight(QWaylandInputDevice *inputDevice, con { Q_UNUSED(local); Q_UNUSED(mods); - overrideCursor(Qt::SplitHCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b); } @@ -463,3 +454,5 @@ void QWaylandDecoration::setBackgroundColor(const QColor &c) { m_backgroundColor = c; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.h b/src/plugins/platforms/wayland_common/qwaylanddecoration.h index 14755699d..5efeab226 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.h @@ -60,6 +60,7 @@ class QWindow; class QPaintDevice; class QPainter; class QEvent; +class QWaylandScreen; class QWaylandWindow; class QWaylandInputDevice; @@ -73,7 +74,6 @@ public: bool isDirty() const; bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); - void restoreMouseCursor(); bool inMouseButtonPressedState() const; void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons); @@ -93,8 +93,6 @@ protected: void paint(QPaintDevice *device); private: - void overrideCursor(Qt::CursorShape shape); - void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); @@ -114,8 +112,6 @@ private: QImage m_decorationContentImage; QMargins m_margins; - bool m_hasSetCursor; - Qt::CursorShape m_cursorShape; Qt::MouseButtons m_mouseButtons; QColor m_foregroundColor; @@ -153,20 +149,6 @@ inline QColor QWaylandDecoration::backgroundColor() const return m_backgroundColor; } -inline void QWaylandDecoration::overrideCursor(Qt::CursorShape shape) -{ - if (m_hasSetCursor) { - if (m_cursorShape != shape) { - QGuiApplication::changeOverrideCursor(QCursor(shape)); - m_cursorShape = shape; - } - } else { - QGuiApplication::setOverrideCursor(QCursor(shape)); - m_hasSetCursor = true; - m_cursorShape = shape; - } -} - QT_END_NAMESPACE #endif // QWAYLANDDECORATION_H diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp index bb056c969..6cc01d0ed 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp @@ -53,9 +53,7 @@ #include "qwaylandglintegration.h" #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif +#include "qwaylandwindowmanagerintegration.h" #include "qwaylandextendedoutput.h" #include "qwaylandextendedsurface.h" @@ -68,7 +66,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE struct wl_surface *QWaylandDisplay::createSurface(void *handle) { @@ -84,12 +82,10 @@ QWaylandGLIntegration * QWaylandDisplay::eglIntegration() } #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() { return mWindowManagerIntegration; } -#endif QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const { @@ -139,9 +135,7 @@ QWaylandDisplay::QWaylandDisplay() mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); -#endif blockingReadEvents(); @@ -168,13 +162,15 @@ QWaylandDisplay::~QWaylandDisplay(void) void QWaylandDisplay::flushRequests() { - wl_display_dispatch_queue_pending(mDisplay, mEventQueue); + if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && errno == EPIPE) + QCoreApplication::quit(); wl_display_flush(mDisplay); } void QWaylandDisplay::blockingReadEvents() { - wl_display_dispatch_queue(mDisplay, mEventQueue); + if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && errno == EPIPE) + QCoreApplication::quit(); } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const @@ -196,8 +192,20 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) void QWaylandDisplay::waitForScreens() { flushRequests(); - while (mScreens.isEmpty()) - blockingReadEvents(); + + while (true) { + bool screensReady = !mScreens.isEmpty(); + + for (int ii = 0; screensReady && ii < mScreens.count(); ++ii) { + if (mScreens.at(ii)->geometry() == QRect(0, 0, 0, 0)) + screensReady = false; + } + + if (!screensReady) + blockingReadEvents(); + else + return; + } } void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version) @@ -219,17 +227,17 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mInputDevices.append(inputDevice); } else if (interface == "wl_data_device_manager") { mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); - } else if (interface == "wl_output_extension") { + } else if (interface == "qt_output_extension") { mOutputExtension = new QtWayland::qt_output_extension(registry, id); foreach (QPlatformScreen *screen, screens()) static_cast<QWaylandScreen *>(screen)->createExtendedOutput(); - } else if (interface == "wl_surface_extension") { + } else if (interface == "qt_surface_extension") { mWindowExtension = new QtWayland::qt_surface_extension(registry, id); - } else if (interface == "wl_sub_surface_extension") { + } else if (interface == "qt_sub_surface_extension") { mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id); - } else if (interface == "wl_touch_extension") { + } else if (interface == "qt_touch_extension") { mTouchExtension = new QWaylandTouchExtension(this, id); - } else if (interface == "wl_qtkey_extension") { + } else if (interface == "qt_key_extension") { mQtKeyExtension = new QWaylandQtKeyExtension(this, id); } @@ -252,3 +260,4 @@ void QWaylandDisplay::forceRoundTrip() wl_display_roundtrip(mDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/plugins/platforms/wayland_common/qwaylanddisplay.h index bb26be69f..6b2cc89d6 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.h @@ -50,6 +50,8 @@ #include <wayland-client.h> #include <qwayland-wayland.h> +struct wl_cursor_image; + QT_BEGIN_NAMESPACE class QAbstractEventDispatcher; @@ -96,9 +98,7 @@ public: QWaylandGLIntegration *eglIntegration(); #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT QWaylandWindowManagerIntegration *windowManagerIntegration(); -#endif void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); @@ -162,6 +162,7 @@ private: QtWayland::qt_output_extension *mOutputExtension; QWaylandTouchExtension *mTouchExtension; QWaylandQtKeyExtension *mQtKeyExtension; + QWaylandWindowManagerIntegration *mWindowManagerIntegration; QSocketNotifier *mReadNotifier; int mFd; @@ -174,10 +175,6 @@ private: QWaylandGLIntegration *mEglIntegration; #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - QWaylandWindowManagerIntegration *mWindowManagerIntegration; -#endif - static void shellHandleConfigure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, struct wl_surface *surface, diff --git a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp b/src/plugins/platforms/wayland_common/qwaylanddnd.cpp index 790fbbd09..0dc80e636 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddnd.cpp @@ -43,7 +43,7 @@ #include "qwaylanddatadevicemanager.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandDrag::QWaylandDrag(QWaylandDisplay *display) : m_display(display) @@ -93,3 +93,5 @@ Qt::DropAction QWaylandDrag::executedDropAction() const { return Qt::CopyAction; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp b/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp index 5c0a1d5b2..ca968a2d0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp @@ -1,11 +1,14 @@ #include "qwaylandeventthread.h" #include <QtCore/QSocketNotifier> +#include <QCoreApplication> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <errno.h> +QT_BEGIN_NAMESPACE + QWaylandEventThread::QWaylandEventThread(QObject *parent) : QObject(parent) , m_display(0) @@ -29,7 +32,8 @@ void QWaylandEventThread::displayConnect() void QWaylandEventThread::readWaylandEvents() { - wl_display_dispatch(m_display); + if (wl_display_dispatch(m_display) == -1 && errno == EPIPE) + QCoreApplication::quit(); emit newEventsRead(); } @@ -53,3 +57,5 @@ wl_display *QWaylandEventThread::display() const QMutexLocker displayLock(m_displayLock); return m_display; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.h b/src/plugins/platforms/wayland_common/qwaylandeventthread.h index bedf4ea51..f4aec744c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.h +++ b/src/plugins/platforms/wayland_common/qwaylandeventthread.h @@ -5,6 +5,8 @@ #include <QMutex> #include <wayland-client.h> +QT_BEGIN_NAMESPACE + class QSocketNotifier; class QWaylandEventThread : public QObject @@ -37,4 +39,6 @@ private: }; +QT_END_NAMESPACE + #endif // QWAYLANDEVENTTHREAD_H diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp index 24b264e28..d7c684be9 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, ::qt_extended_output *extended_output) : QtWayland::qt_extended_output(extended_output) @@ -96,3 +96,5 @@ void QWaylandExtendedOutput::extended_output_set_screen_rotation(int32_t rotatio } QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp index 46280bcf3..58eb0a833 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp @@ -53,15 +53,19 @@ #include <qpa/qplatformnativeinterface.h> #include <qpa/qwindowsysteminterface.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface) : QtWayland::qt_extended_surface(extended_surface) , m_window(window) - , m_exposed(true) { } +QWaylandExtendedSurface::~QWaylandExtendedSurface() +{ + qt_extended_surface_destroy(object()); +} + void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value) { QByteArray byteValue; @@ -107,18 +111,9 @@ QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant & return m_properties.value(name,defaultValue); } -void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visible) +void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility) { - // Do not send events when the state is not changing... - if (visible == m_exposed) - return; - - m_exposed = visible; - QWaylandWindow *w = m_window; - QWindowSystemInterface::handleExposeEvent(w->window(), - visible - ? QRegion(w->geometry()) - : QRegion()); + m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility)); } void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value) @@ -136,6 +131,11 @@ void QWaylandExtendedSurface::extended_surface_set_generic_property(const QStrin nativeInterface->emitWindowPropertyChanged(m_window, name); } +void QWaylandExtendedSurface::extended_surface_close() +{ + QWindowSystemInterface::handleCloseEvent(m_window->window()); +} + Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) { uint wlFlags = 0; @@ -147,3 +147,5 @@ Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h index 9dbebaf47..4bef5e073 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h @@ -57,6 +57,7 @@ class QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); + ~QWaylandExtendedSurface(); void setContentOrientation(Qt::ScreenOrientation orientation); @@ -68,16 +69,13 @@ public: Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); - bool isExposed() const { return m_exposed; } - private: - void extended_surface_onscreen_visibility(int32_t visible) Q_DECL_OVERRIDE; + void extended_surface_onscreen_visibility(int32_t visibility) Q_DECL_OVERRIDE; void extended_surface_set_generic_property(const QString &name, wl_array *value) Q_DECL_OVERRIDE; + void extended_surface_close() Q_DECL_OVERRIDE; QWaylandWindow *m_window; QVariantMap m_properties; - - bool m_exposed; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp index a4b3331c6..bafb99443 100644 --- a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp @@ -41,7 +41,7 @@ #include "qwaylandglintegration.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration::QWaylandGLIntegration() { @@ -52,3 +52,5 @@ QWaylandGLIntegration::~QWaylandGLIntegration() { } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp index 62cbdf36b..aab939f6d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -46,6 +46,8 @@ #include "qwaylandbuffer.h" #include "qwaylanddatadevicemanager.h" #include "qwaylandtouch.h" +#include "qwaylandscreen.h" +#include "qwaylandcursor.h" #include <QtGui/private/qpixmap_raster_p.h> #include <qpa/qplatformwindow.h> @@ -53,6 +55,7 @@ #include <unistd.h> #include <fcntl.h> +#include <sys/mman.h> #include <wayland-cursor.h> @@ -63,18 +66,20 @@ #include <X11/keysym.h> #endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) : QtWayland::wl_seat(display->wl_registry(), id) , mQDisplay(display) , mDisplay(display->wl_display()) + , mFocusCallback(0) , mCaps(0) , mTransferDevice(0) , mPointerFocus(0) , mKeyboardFocus(0) , mTouchFocus(0) , mButtons(0) + , mCursorSerial(0) , mTouchDevice(0) #ifndef QT_NO_WAYLAND_XKB , mXkbContext(0) @@ -90,7 +95,7 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) names.variant = strdup(""); names.options = strdup(""); - xkb_context *mXkbContext = xkb_context_new(xkb_context_flags(0)); + mXkbContext = xkb_context_new(xkb_context_flags(0)); if (mXkbContext) { mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0)); if (mXkbMap) { @@ -167,9 +172,28 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) mButtons = mButtons & !button; } +void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *screen) +{ + struct wl_cursor_image *image = screen->waylandCursor()->cursorImage(newShape); + if (!image) { + return; + } + + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); + setCursor(buffer, image); +} + void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) { if (mCaps & WL_SEAT_CAPABILITY_POINTER) { + mCursorSerial = mEnterSerial; + /* Hide cursor */ + if (!buffer) + { + set_cursor(mEnterSerial, NULL, 0, 0); + return; + } + set_cursor(mEnterSerial, pointerSurface, image->hotspot_x, image->hotspot_y); wl_surface_attach(pointerSurface, buffer, 0, 0); @@ -187,16 +211,17 @@ void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surf if (!surface) return; - QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseEnter(); - window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + window->window()->setCursor(window->window()->cursor()); + mPointerFocus = window; mTime = QWaylandDisplay::currentTimeMillisec(); mSerial = serial; mEnterSerial = serial; + + window->handleMouseEnter(this); + window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) @@ -206,10 +231,8 @@ void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surfac if (!surface) return; - QGuiApplication::restoreOverrideCursor(); - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseLeave(); + window->handleMouseLeave(this); mPointerFocus = 0; mButtons = Qt::NoButton; @@ -401,30 +424,73 @@ static const uint32_t KeyTbl[] = { 0, 0 }; -static uint32_t translateKey(uint32_t sym, char *string, size_t size) +static int keysymToQtKey(xkb_keysym_t key) { - Q_UNUSED(size); - string[0] = '\0'; + int code = 0; + int i = 0; + while (KeyTbl[i]) { + if (key == KeyTbl[i]) { + code = (int)KeyTbl[i+1]; + break; + } + i += 2; + } - if (sym >= XK_F1 && sym <= XK_F35) - return Qt::Key_F1 + (int(sym) - XK_F1); + return code; +} - for (int i = 0; KeyTbl[i]; i += 2) - if (sym == KeyTbl[i]) - return KeyTbl[i + 1]; +static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text) +{ + int code = 0; + + if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { + code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1); + } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) { + if (keysym >= XKB_KEY_KP_0) { + // numeric keypad keys + code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0); + } else { + code = keysymToQtKey(keysym); + } + modifiers |= Qt::KeypadModifier; + } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f + && text.unicode()->unicode() != 0x7f + && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) { + code = text.unicode()->toUpper().unicode(); + } else { + // any other keys + code = keysymToQtKey(keysym); + } - string[0] = sym; - string[1] = '\0'; - return toupper(sym); + return code; } #endif // QT_NO_WAYLAND_XKB void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) { +#ifndef QT_NO_WAYLAND_XKB + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) { + close(fd); + return; + } + + mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); + munmap(map_str, size); + close(fd); + + mXkbState = xkb_state_new(mXkbMap); +#else Q_UNUSED(format); Q_UNUSED(fd); Q_UNUSED(size); +#endif } void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) @@ -435,10 +501,14 @@ void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surfa if (!surface) return; + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); mKeyboardFocus = window; - mQDisplay->setLastKeyboardFocusInputDevice(this); - QWindowSystemInterface::handleWindowActivated(window->window()); + + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } } void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) @@ -447,7 +517,32 @@ void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surfa Q_UNUSED(surface); mKeyboardFocus = NULL; - mQDisplay->setLastKeyboardFocusInputDevice(0); + + // Use a callback to set the focus because we may get a leave/enter pair, and + // the latter one would be lost in the QWindowSystemInterface queue, if + // we issue the handleWindowActivated() calls immediately. + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } +} + +const wl_callback_listener QWaylandInputDevice::callback = { + QWaylandInputDevice::focusCallback +}; + +void QWaylandInputDevice::focusCallback(void *data, struct wl_callback *callback, uint32_t time) +{ + Q_UNUSED(time); + Q_UNUSED(callback); + QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); + if (self->mFocusCallback) { + wl_callback_destroy(self->mFocusCallback); + self->mFocusCallback = 0; + } + + self->mQDisplay->setLastKeyboardFocusInputDevice(self->mKeyboardFocus ? self : 0); + QWindowSystemInterface::handleWindowActivated(self->mKeyboardFocus ? self->mKeyboardFocus->window() : 0); } void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) @@ -476,15 +571,15 @@ void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t Qt::KeyboardModifiers modifiers = translateModifiers(mXkbState); QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; - char s[2]; - sym = translateKey(sym, s, sizeof s); + uint utf32 = xkb_keysym_to_utf32(sym); + QString text = QString::fromUcs4(&utf32, 1); + + int qtkey = keysymToQtKey(sym, modifiers, text); - if (window) - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), - time, type, sym, - modifiers, - code, 0, 0, - QString::fromLatin1(s)); + QWindowSystemInterface::handleExtendedKeyEvent(window->window(), + time, type, qtkey, + modifiers, + code, 0, 0, text); } #else // Generic fallback for single hard keys: Assume 'key' is a Qt key code. @@ -621,7 +716,9 @@ void QWaylandInputDevice::touch_frame() return; } - QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints); + QWindow *window = mTouchFocus ? mTouchFocus->window() : 0; + + QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); bool allReleased = true; for (int i = 0; i < mTouchPoints.count(); ++i) @@ -634,7 +731,9 @@ void QWaylandInputDevice::touch_frame() mTouchPoints.clear(); if (allReleased) { - QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints); + QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); mPrevTouchPoints.clear(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h index c0e57a909..c92026841 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h @@ -75,6 +75,7 @@ public: struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); } + void setCursor(Qt::CursorShape cursor, QWaylandScreen *screen); void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); void handleWindowDestroyed(QWaylandWindow *window); @@ -84,10 +85,12 @@ public: void removeMouseButtonFromState(Qt::MouseButton button); uint32_t serial() const; + uint32_t cursorSerial() const { return mCursorSerial; } private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; + struct wl_callback *mFocusCallback; uint32_t mCaps; @@ -104,6 +107,7 @@ private: uint32_t mTime; uint32_t mSerial; uint32_t mEnterSerial; + uint32_t mCursorSerial; void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE; @@ -152,6 +156,9 @@ private: void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); + static const wl_callback_listener callback; + static void focusCallback(void *data, struct wl_callback *callback, uint32_t time); + QList<QWindowSystemInterface::TouchPoint> mTouchPoints; QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; QTouchDevice *mTouchDevice; diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp index c3a479a21..b0d5b271f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp @@ -47,6 +47,7 @@ #include "qwaylandnativeinterface.h" #include "qwaylandclipboard.h" #include "qwaylanddnd.h" +#include "qwaylandwindowmanagerintegration.h" #include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h" #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> @@ -67,11 +68,37 @@ #include "qwaylandglintegration.h" #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE + +class GenericWaylandTheme: public QGenericUnixTheme +{ +public: + static QStringList themeNames() + { + QStringList result; + + if (QGuiApplication::desktopSettingsAware()) { + const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); + + // Ignore X11 desktop environments + if (!desktopEnvironment.isEmpty() && + desktopEnvironment != QByteArrayLiteral("UNKNOWN") && + desktopEnvironment != QByteArrayLiteral("KDE") && + desktopEnvironment != QByteArrayLiteral("GNOME") && + desktopEnvironment != QByteArrayLiteral("UNITY") && + desktopEnvironment != QByteArrayLiteral("MATE") && + desktopEnvironment != QByteArrayLiteral("XFCE") && + desktopEnvironment != QByteArrayLiteral("LXDE")) + result.push_back(desktopEnvironment.toLower()); + } + + if (result.isEmpty()) + result.push_back(QLatin1String(QGenericUnixTheme::name)); + + return result; + } +}; QWaylandIntegration::QWaylandIntegration() : mFontDb(new QGenericUnixFontDatabase()) @@ -84,7 +111,6 @@ QWaylandIntegration::QWaylandIntegration() #endif { QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - QGuiApplication::setDesktopSettingsAware(false); mDisplay = new QWaylandDisplay(); mClipboard = new QWaylandClipboard(mDisplay); mDrag = new QWaylandDrag(mDisplay); @@ -184,10 +210,9 @@ QPlatformInputContext *QWaylandIntegration::inputContext() const QVariant QWaylandIntegration::styleHint(StyleHint hint) const { -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration()) return mDisplay->windowManagerIntegration()->showIsFullScreen(); -#endif + return QPlatformIntegration::styleHint(hint); } @@ -198,11 +223,7 @@ QPlatformAccessibility *QWaylandIntegration::accessibility() const QPlatformServices *QWaylandIntegration::services() const { -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT return mDisplay->windowManagerIntegration(); -#else - return QWaylandIntegration::services(); -#endif } QWaylandDisplay *QWaylandIntegration::display() const @@ -212,10 +233,12 @@ QWaylandDisplay *QWaylandIntegration::display() const QStringList QWaylandIntegration::themeNames() const { - return QGenericUnixTheme::themeNames(); + return GenericWaylandTheme::themeNames(); } QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) const { - return QGenericUnixTheme::createUnixTheme(name); + return GenericWaylandTheme::createUnixTheme(name); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp index 31d25c0f9..354e8dbaa 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp @@ -45,12 +45,11 @@ #include "qwaylandextendedsurface.h" #include "qwaylandintegration.h" #include "qwaylanddisplay.h" +#include "qwaylandwindowmanagerintegration.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/QScreen> -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandNativeInterface::QWaylandNativeInterface(QWaylandIntegration *integration) : m_integration(integration) @@ -78,7 +77,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc if (lowerCaseResource == "compositor") return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); if (lowerCaseResource == "surface") { - return ((QWaylandWindow *) window->handle())->wl_surface(); + return ((QWaylandWindow *) window->handle())->object(); } return NULL; @@ -131,3 +130,5 @@ void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window, { emit windowPropertyChanged(window,name); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp index d9f2071ec..e723078cd 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp @@ -42,7 +42,7 @@ #include "qwaylandqtkey.h" #include "qwaylandinputdevice.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id) : QtWayland::qt_key_extension(display->wl_registry(), id) @@ -63,7 +63,7 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, { QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); if (inputDevices.isEmpty()) { - qWarning("wl_qtkey_extension: handle_qtkey: No input device"); + qWarning("qt_key_extension: handle_qtkey: No input device"); return; } @@ -71,7 +71,7 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, QWaylandWindow *win = dev->mKeyboardFocus; if (!win || !win->window()) { - qWarning("wl_qtkey_extension: handle_qtkey: No keyboard focus"); + qWarning("qt_key_extension: handle_qtkey: No keyboard focus"); return; } @@ -80,3 +80,5 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp index 1cb1b9cfb..5956c2fd3 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp @@ -47,7 +47,7 @@ #include <qpa/qwindowsysteminterface.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) : QtWayland::wl_output(waylandDisplay->wl_registry(), id) @@ -56,6 +56,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) , mDepth(32) , mRefreshRate(60000) , mFormat(QImage::Format_ARGB32_Premultiplied) + , mOutputName(QStringLiteral("Screen%1").arg(id)) , mWaylandCursor(new QWaylandCursor(this)) { // handle case of output extension global being sent after outputs @@ -138,11 +139,12 @@ void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refr if (size != mGeometry.size()) { mGeometry.setSize(size); QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry); } if (refresh != mRefreshRate) { mRefreshRate = refresh; - QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); + QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate()); } } @@ -155,9 +157,11 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y, { Q_UNUSED(subpixel); Q_UNUSED(make); - Q_UNUSED(model); Q_UNUSED(transform); + if (!model.isEmpty()) + mOutputName = model; + QRect geom(x, y, width, height); if (mGeometry == geom) @@ -165,4 +169,7 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y, mGeometry = geom; QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.h b/src/plugins/platforms/wayland_common/qwaylandscreen.h index 005f25eea..91848ad05 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.h +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.h @@ -69,7 +69,10 @@ public: Qt::ScreenOrientation orientation() const; qreal refreshRate() const; + QString name() const { return mOutputName; } + QPlatformCursor *cursor() const; + QWaylandCursor *waylandCursor() const { return mWaylandCursor; }; ::wl_output *output() { return object(); } @@ -94,6 +97,7 @@ private: int mRefreshRate; QImage::Format mFormat; QSize mPhysicalSize; + QString mOutputName; QWaylandCursor *mWaylandCursor; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp index 986890732..6e638e6b1 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp @@ -49,7 +49,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window) : QtWayland::wl_shell_surface(shell_surface) @@ -114,7 +114,7 @@ void QWaylandShellSurface::setTopLevel() void QWaylandShellSurface::updateTransientParent(QWindow *parent) { QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle()); - if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + if (!parent_wayland_window) return; // set_transient expects a position relative to the parent @@ -132,7 +132,7 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) || wf.testFlag(Qt::WindowTransparentForInput)) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; - set_transient(parent_wayland_window->wl_surface(), + set_transient(parent_wayland_window->object(), transientPos.x(), transientPos.y(), flags); @@ -140,8 +140,8 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) { - QWaylandWindow *parent_wayland_window = parent->topLevelWindow(); - if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + QWaylandWindow *parent_wayland_window = parent; + if (!parent_wayland_window) return; // set_popup expects a position relative to the parent @@ -152,19 +152,8 @@ void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } - wl_shell_surface_set_popup(object(), device->wl_seat(), serial, - parent_wayland_window->wl_surface(), - transientPos.x(), transientPos.y(), 0); -} - -void QWaylandShellSurface::setClassName(const char *className) -{ - set_class(className); -} - -void QWaylandShellSurface::setTitle(const char *title) -{ - set_title(title); + set_popup(device->wl_seat(), serial, parent_wayland_window->object(), + transientPos.x(), transientPos.y(), 0); } void QWaylandShellSurface::shell_surface_ping(uint32_t serial) @@ -183,3 +172,5 @@ void QWaylandShellSurface::shell_surface_popup_done() { QCoreApplication::postEvent(m_window->window(), new QCloseEvent()); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h index 9e886cf0a..172a0f965 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h @@ -76,10 +76,6 @@ private: void updateTransientParent(QWindow *parent); void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); - void setClassName(const char *_class); - - void setTitle(const char *title); - QWaylandWindow *m_window; bool m_maximized; bool m_fullscreen; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp index 93161a3f7..00a4b13a2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp @@ -172,11 +172,13 @@ void QWaylandShmBackingStore::beginPaint(const QRegion &) waylandWindow->waitForFrameSync(); } + waylandWindow()->setCanResize(false); } void QWaylandShmBackingStore::endPaint() { mPainting = false; + waylandWindow()->setCanResize(true); } void QWaylandShmBackingStore::ensureSize() @@ -224,8 +226,8 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons waylandWindow()->damage(rect); } } + waylandWindow()->commit(); mFrontBufferIsDirty = false; - waylandWindow()->doResize(); } void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) @@ -299,18 +301,17 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t wl_callback_destroy(self->mFrameCallback); self->mFrameCallback = 0; - if (self->mFrontBuffer != window->attached()) { - delete window->attached(); - } - - if (window->attached() != self->mFrontBuffer) - window->attachOffset(self->mFrontBuffer); if (self->mFrontBufferIsDirty && !self->mPainting) { self->mFrontBufferIsDirty = false; - self->mFrameCallback = wl_surface_frame(window->wl_surface()); + self->mFrameCallback = wl_surface_frame(window->object()); wl_callback_add_listener(self->mFrameCallback,&self->frameCallbackListener,self); + if (self->mFrontBuffer != window->attached()) { + delete window->attached(); + } + window->attachOffset(self->mFrontBuffer); window->damage(QRect(QPoint(0,0),self->mFrontBuffer->size())); + window->commit(); } } @@ -319,4 +320,3 @@ const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener }; QT_END_NAMESPACE - diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp index f4a0ede0c..48a1bfd53 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandShmWindow::QWaylandShmWindow(QWindow *window) : QWaylandWindow(window) @@ -69,3 +69,5 @@ void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp index 99713bb6b..0e9d575a9 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp @@ -45,7 +45,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface) : QtWayland::qt_sub_surface(sub_surface) @@ -87,3 +87,5 @@ void QWaylandSubSurface::adjustPositionOfChildren() } setPositionToParent(m_window); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp index b19165d6d..5835d9d3c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp @@ -42,7 +42,7 @@ #include "qwaylandtouch.h" #include "qwaylandinputdevice.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id) : QtWayland::qt_touch_extension(display->wl_registry(), id), @@ -78,7 +78,7 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, if (!mInputDevice) { QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); if (inputDevices.isEmpty()) { - qWarning("wl_touch_extension: handle_touch: No input devices"); + qWarning("qt_touch_extension: handle_touch: No input devices"); return; } mInputDevice = inputDevices.first(); @@ -89,7 +89,7 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, if (!win) win = mInputDevice->mKeyboardFocus; if (!win || !win->window()) { - qWarning("wl_touch_extension: handle_touch: No pointer focus"); + qWarning("qt_touch_extension: handle_touch: No pointer focus"); return; } mTargetWindow = win->window(); @@ -205,3 +205,5 @@ void QWaylandTouchExtension::touch_extension_configure(uint32_t flags) { mFlags = flags; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp index 666222107..27b624fb2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp @@ -49,25 +49,23 @@ #include "qwaylandextendedsurface.h" #include "qwaylandsubsurface.h" #include "qwaylanddecoration.h" +#include "qwaylandwindowmanagerintegration.h" #include <QtCore/QFileInfo> #include <QtGui/QWindow> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - -#include <QCoreApplication> +#include <QGuiApplication> #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandWindow::QWaylandWindow(QWindow *window) : QObject() , QPlatformWindow(window) - , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) + , mScreen(QWaylandScreen::waylandScreenFromWindow(window)) + , mDisplay(mScreen->display()) , mShellSurface(0) , mExtendedWindow(0) , mSubSurfaceWindow(0) @@ -77,7 +75,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) - , mResizeExposedSent(false) + , mRequestResizeSent(false) + , mCanResize(true) , mSentInitialResize(false) , mMouseDevice(0) , mMouseSerial(0) @@ -88,25 +87,26 @@ QWaylandWindow::QWaylandWindow(QWindow *window) static WId id = 1; mWindowId = id++; - if (mDisplay->shell() && !(window->flags() & Qt::BypassWindowManagerHint)) - mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(wl_surface()), this); + if (mDisplay->shell() && window->type() & Qt::Window && !(window->flags() & Qt::BypassWindowManagerHint)) + mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(object()), this); if (mDisplay->windowExtension()) - mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(wl_surface())); + mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(object())); if (mDisplay->subSurfaceExtension()) - mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(wl_surface())); + mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(object())); if (mShellSurface) { // Set surface class to the .desktop file name (obtained from executable name) QFileInfo exeFileInfo(qApp->applicationFilePath()); QString className = exeFileInfo.baseName() + QLatin1String(".desktop"); - mShellSurface->setClassName(className.toUtf8().constData()); + mShellSurface->set_class(className); } if (QPlatformWindow::parent() && mSubSurfaceWindow) { mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(QPlatformWindow::parent())); - } else if (window->transientParent()) { - if (window->transientParent() && mShellSurface) + } else if (window->transientParent() && mShellSurface) { + if (window->type() != Qt::Popup) { mShellSurface->updateTransientParent(window->transientParent()); + } } else if (mShellSurface) { mShellSurface->setTopLevel(); } @@ -123,10 +123,18 @@ QWaylandWindow::~QWaylandWindow() delete mExtendedWindow; destroy(); } + if (mFrameCallback) + wl_callback_destroy(mFrameCallback); QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); for (int i = 0; i < inputDevices.size(); ++i) inputDevices.at(i)->handleWindowDestroyed(this); + + const QWindow *parent = window(); + foreach (QWindow *w, QGuiApplication::topLevelWindows()) { + if (w->transientParent() == parent) + QWindowSystemInterface::handleCloseEvent(w); + } } QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) @@ -150,8 +158,7 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent) void QWaylandWindow::setWindowTitle(const QString &title) { if (mShellSurface) { - QByteArray titleUtf8 = title.toUtf8(); - mShellSurface->setTitle(titleUtf8.constData()); + mShellSurface->set_title(title); } if (mWindowDecoration && window()->isVisible()) @@ -175,6 +182,11 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (mWindowDecoration && window()->isVisible()) mWindowDecoration->update(); + + if (mConfigure.isEmpty()) { + QWindowSystemInterface::handleGeometryChange(window(), rect); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect)); + } } void QWaylandWindow::setVisible(bool visible) @@ -201,38 +213,42 @@ void QWaylandWindow::setVisible(bool visible) // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). } else { - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); attach(static_cast<QWaylandBuffer *>(0), 0, 0); } damage(QRect(QPoint(0,0),geometry().size())); + commit(); } -bool QWaylandWindow::isExposed() const +void QWaylandWindow::raise() { - if (!window()->isVisible()) - return false; if (mExtendedWindow) - return mExtendedWindow->isExposed(); - return true; + mExtendedWindow->raise(); } +void QWaylandWindow::lower() +{ + if (mExtendedWindow) + mExtendedWindow->lower(); +} + void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) { + QMutexLocker resizeLocker(&mResizeLock); mConfigure.edges |= edges; mConfigure.width = width; mConfigure.height = height; - if (!mResizeExposedSent) { - mResizeExposedSent = true; - QMetaObject::invokeMethod(this, "doResize", Qt::QueuedConnection); + if (!mRequestResizeSent && !mConfigure.isEmpty()) { + mRequestResizeSent= true; + QMetaObject::invokeMethod(this, "requestResize", Qt::QueuedConnection); } } void QWaylandWindow::doResize() { - mResizeExposedSent = false; if (mConfigure.isEmpty()) { return; } @@ -255,13 +271,34 @@ void QWaylandWindow::doResize() } mOffset += QPoint(x, y); - mResizeLock.lock(); setGeometry(geometry); - mResizeLock.unlock(); mConfigure.clear(); QWindowSystemInterface::handleGeometryChange(window(), geometry); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry)); +} + +void QWaylandWindow::setCanResize(bool canResize) +{ + QMutexLocker lock(&mResizeLock); + mCanResize = canResize; + + if (canResize && !mConfigure.isEmpty()) { + doResize(); + QWindowSystemInterface::handleExposeEvent(window(), geometry()); + } +} + +void QWaylandWindow::requestResize() +{ + QMutexLocker lock(&mResizeLock); + + if (mCanResize) { + doResize(); + } + + mRequestResizeSent = false; + lock.unlock(); + QWindowSystemInterface::handleExposeEvent(window(), geometry()); QWindowSystemInterface::flushWindowSystemEvents(); } @@ -269,8 +306,10 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { mBuffer = buffer; - if (window()->isVisible()) + if (mBuffer) attach(mBuffer->buffer(), x, y); + else + QtWayland::wl_surface::attach(0, 0, 0); } void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) @@ -293,9 +332,9 @@ void QWaylandWindow::damage(const QRect &rect) wl_callback_add_listener(mFrameCallback,&QWaylandWindow::callbackListener,this); mWaitingForFrameSync = true; } - - damage(rect.x(), rect.y(), rect.width(), rect.height()); - commit(); + if (mBuffer) { + damage(rect.x(), rect.y(), rect.width(), rect.height()); + } } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -379,6 +418,9 @@ void QWaylandWindow::setWindowState(Qt::WindowState state) default: mShellSurface->setNormal(); } + + QWindowSystemInterface::handleWindowStateChanged(window(), mState); + QWindowSystemInterface::flushWindowSystemEvents(); // Required for oldState to work on WindowStateChanged } void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) @@ -434,21 +476,20 @@ void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) } } -QWaylandWindow *QWaylandWindow::topLevelWindow() +static QWindow *topLevelWindow(QWindow *window) { - QWaylandWindow *w = this; - while (w->QPlatformWindow::parent()) { - w = static_cast<QWaylandWindow *>(w->QPlatformWindow::parent()); - } - return w; + while (QWindow *parent = window->parent()) + window = parent; + return window; } QWaylandWindow *QWaylandWindow::transientParent() const { if (window()->transientParent()) { - // Take the top level window here, since the transient parent may be some non-native - // QWindow, which cannot have the mMouseDevice and mMouseSerial - return static_cast<QWaylandWindow *>(window()->transientParent()->handle())->topLevelWindow(); + // Take the top level window here, since the transient parent may be a QWidgetWindow + // or some other window without a shell surface, which is then not able to get mouse + // events, nor set mMouseSerial and mMouseDevice. + return static_cast<QWaylandWindow *>(topLevelWindow(window()->transientParent())->handle()); } return 0; } @@ -468,23 +509,24 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timesta QWindowSystemInterface::handleMouseEvent(window(),timestamp,local,global,b,mods); } -void QWaylandWindow::handleMouseEnter() +void QWaylandWindow::handleMouseEnter(QWaylandInputDevice *inputDevice) { if (!mWindowDecoration) { QWindowSystemInterface::handleEnterEvent(window()); } + restoreMouseCursor(inputDevice); } -void QWaylandWindow::handleMouseLeave() +void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice) { if (mWindowDecoration) { if (mMouseEventsInContentArea) { QWindowSystemInterface::handleLeaveEvent(window()); } - mWindowDecoration->restoreMouseCursor(); } else { QWindowSystemInterface::handleLeaveEvent(window()); } + restoreMouseCursor(inputDevice); } void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) @@ -505,7 +547,7 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe globalTranslated.setX(globalTranslated.x() - marg.left()); globalTranslated.setY(globalTranslated.y() - marg.top()); if (!mMouseEventsInContentArea) { - mWindowDecoration->restoreMouseCursor(); + restoreMouseCursor(inputDevice); QWindowSystemInterface::handleEnterEvent(window()); } QWindowSystemInterface::handleMouseEvent(window(), timestamp, localTranslated, globalTranslated, b, mods); @@ -519,3 +561,18 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe mWindowDecoration->handleMouse(inputDevice,local,global,b,mods); } } + +void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape) +{ + if (m_cursorShape != shape || device->serial() > device->cursorSerial()) { + device->setCursor(shape, mScreen); + m_cursorShape = shape; + } +} + +void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) +{ + setMouseCursor(device, window()->cursor().shape()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/plugins/platforms/wayland_common/qwaylandwindow.h index 3cd891f65..8fd104d0a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.h @@ -122,10 +122,6 @@ public: QMargins frameMargins() const; - // TODO: remove? - struct ::wl_surface *wl_surface() { return object(); } - const struct ::wl_surface *wl_surface() const { return object(); } - static QWaylandWindow *fromWlSurface(::wl_surface *surface); QWaylandShellSurface *shellSurface() const; @@ -137,7 +133,8 @@ public: void setWindowState(Qt::WindowState state); void setWindowFlags(Qt::WindowFlags flags); - bool isExposed() const; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; QWaylandDecoration *decoration() const; void setDecoration(QWaylandDecoration *decoration); @@ -149,25 +146,27 @@ public: const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods); - void handleMouseEnter(); - void handleMouseLeave(); + void handleMouseEnter(QWaylandInputDevice *inputDevice); + void handleMouseLeave(QWaylandInputDevice *inputDevice); bool createDecoration(); inline bool isMaximized() const { return mState == Qt::WindowMaximized; } inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; } - QWaylandWindow *topLevelWindow(); + void setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape); + void restoreMouseCursor(QWaylandInputDevice *device); + QWaylandWindow *transientParent() const; QMutex *resizeMutex() { return &mResizeLock; } - -public slots: void doResize(); + void setCanResize(bool canResize); +public slots: + void requestResize(); protected: - virtual void createDecorationInstance() {} - + QWaylandScreen *mScreen; QWaylandDisplay *mDisplay; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; @@ -176,6 +175,7 @@ protected: QWaylandDecoration *mWindowDecoration; bool mMouseEventsInContentArea; Qt::MouseButtons mMousePressedInContentArea; + Qt::CursorShape m_cursorShape; QWaylandBuffer *mBuffer; WId mWindowId; @@ -185,7 +185,8 @@ protected: QMutex mResizeLock; QWaylandWindowConfigure mConfigure; - bool mResizeExposedSent; + bool mRequestResizeSent; + bool mCanResize; bool mSentInitialResize; QPoint mOffset; diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp index 673400bda..7543ba13c 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp @@ -54,7 +54,7 @@ #include <QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWaylandWindowManagerIntegrationPrivate { public: @@ -93,7 +93,7 @@ bool QWaylandWindowManagerIntegration::showIsFullScreen() const void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_windowmanager") + if (interface == "qt_windowmanager") static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id); } @@ -108,6 +108,27 @@ void QWaylandWindowManagerIntegration::windowmanager_quit() QGuiApplication::quit(); } +QByteArray QWaylandWindowManagerIntegration::desktopEnvironment() const +{ + const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); + if (!xdgCurrentDesktop.isEmpty()) + return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE... + + // Classic fallbacks + if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION")) + return QByteArrayLiteral("KDE"); + if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID")) + return QByteArrayLiteral("GNOME"); + + // Fallback to checking $DESKTOP_SESSION (unreliable) + const QByteArray desktopSession = qgetenv("DESKTOP_SESSION"); + if (desktopSession == "gnome") + return QByteArrayLiteral("GNOME"); + if (desktopSession == "xfce") + return QByteArrayLiteral("XFCE"); + + return QByteArrayLiteral("UNKNOWN"); +} void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { @@ -134,3 +155,5 @@ bool QWaylandWindowManagerIntegration::openDocument(const QUrl &url) openUrl_helper(url); return true; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h index 0982632d2..4524ce121 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h @@ -65,6 +65,8 @@ public: explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); virtual ~QWaylandWindowManagerIntegration(); + QByteArray desktopEnvironment() const; + bool openUrl(const QUrl &url); bool openDocument(const QUrl &url); diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro index 4a1b0e885..d8aedb65f 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pro +++ b/src/plugins/platforms/wayland_common/wayland_common.pro @@ -2,7 +2,6 @@ TEMPLATE = lib CONFIG += staticlib include ($$PWD/wayland_common_share.pri) -include (windowmanager_integration/windowmanager_integration.pri) SOURCES += qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ @@ -26,7 +25,8 @@ SOURCES += qwaylandintegration.cpp \ qwaylandqtkey.cpp \ ../../../shared/qwaylandmimehelper.cpp \ qwaylanddecoration.cpp \ - qwaylandeventthread.cpp + qwaylandeventthread.cpp\ + qwaylandwindowmanagerintegration.cpp HEADERS += qwaylandintegration.h \ qwaylandnativeinterface.h \ @@ -51,7 +51,8 @@ HEADERS += qwaylandintegration.h \ qwaylandqtkey.h \ ../../../shared/qwaylandmimehelper.h \ qwaylanddecoration.h \ - qwaylandeventthread.h + qwaylandeventthread.h \ + qwaylandwindowmanagerintegration.h contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { SOURCES += qwaylandglintegration.cpp @@ -64,6 +65,7 @@ WAYLANDCLIENTSOURCES += \ ../../../extensions/output-extension.xml \ ../../../extensions/touch-extension.xml \ ../../../extensions/qtkey-extension.xml \ + ../../../extensions/windowmanager.xml \ PLUGIN_TYPE = platforms diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri deleted file mode 100644 index 9228358ec..000000000 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri +++ /dev/null @@ -1,16 +0,0 @@ -DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT - -contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - - WAYLANDCLIENTSOURCES += $$PWD/../../../../extensions/windowmanager.xml - - HEADERS += \ - $$PWD/qwaylandwindowmanagerintegration.h - - SOURCES += \ - $$PWD/qwaylandwindowmanagerintegration.cpp - -} - - - diff --git a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp index 3e18eaefb..c65ad4a1a 100644 --- a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -44,7 +44,7 @@ #include "wayland-client.h" #include "wayland-xcomposite-client-protocol.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(qt_xcomposite *xcomposite, uint32_t window, const QSize &size) :mSize(size) @@ -59,3 +59,5 @@ QSize QWaylandXCompositeBuffer::size() const { return mSize; } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp index 7f5c3893a..e4fbfb553 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp +++ b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp @@ -45,17 +45,14 @@ #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext_brcm.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE -BrcmBuffer::BrcmBuffer(QtWayland::Compositor *compositor, const QSize &size, EGLint *data, size_t count) - : m_invertedY(false) +BrcmBuffer::BrcmBuffer(struct ::wl_client *client, uint32_t id, const QSize &size, EGLint *data, size_t count) + : QtWaylandServer::wl_buffer(client, id) , m_handle(count) + , m_invertedY(false) + , m_size(size) { - Q_UNUSED(compositor); - - base()->height = size.height(); - base()->width = size.width(); - for (size_t i = 0; i < count; ++i) m_handle[i] = data[i]; } @@ -65,17 +62,14 @@ BrcmBuffer::~BrcmBuffer() eglDestroyGlobalImageBRCM(handle()); } -struct wl_buffer_interface BrcmBuffer::buffer_interface = { - BrcmBuffer::buffer_interface_destroy -}; - -void BrcmBuffer::buffer_interface_destroy(wl_client *client, wl_resource *buffer) +void BrcmBuffer::buffer_destroy_resource(Resource *) { - Q_UNUSED(client); - Q_UNUSED(buffer); + delete this; } -void BrcmBuffer::delete_resource(struct wl_resource *resource) +void BrcmBuffer::buffer_destroy(Resource *resource) { - delete reinterpret_cast<BrcmBuffer *>(resource); + wl_resource_destroy(resource->handle); } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h index 11f49d4a9..6ec5868f9 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h +++ b/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h @@ -41,8 +41,8 @@ #ifndef BRCMBUFFER_H #define BRCMBUFFER_H -#include <QtCompositor/qwaylandobject.h> #include <QtCompositor/private/qwlcompositor_p.h> +#include <qwayland-server-wayland.h> #include <QtCore/QSize> #include <QtCore/QVector> @@ -51,26 +51,29 @@ QT_BEGIN_NAMESPACE -class BrcmBuffer : public QtWayland::Object<struct wl_buffer> +class BrcmBuffer : public QtWaylandServer::wl_buffer { public: - BrcmBuffer(QtWayland::Compositor *compositor, const QSize &size, EGLint *data, size_t count); + BrcmBuffer(struct ::wl_client *client, uint32_t id, const QSize &size, EGLint *data, size_t count); ~BrcmBuffer(); - static struct wl_buffer_interface buffer_interface; - static void delete_resource(struct wl_resource *resource); - bool isYInverted() const { return m_invertedY; } void setInvertedY(bool inverted) { m_invertedY = inverted; } EGLint *handle() { return m_handle.data(); } - static void buffer_interface_destroy(struct wl_client *client, - struct wl_resource *buffer); + QSize size() { return m_size; } + + static BrcmBuffer *fromResource(struct ::wl_resource *resource) { return static_cast<BrcmBuffer*>(Resource::fromResource(resource)->buffer); } + +protected: + void buffer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void buffer_destroy(Resource *resource) Q_DECL_OVERRIDE; private: QVector<EGLint> m_handle; bool m_invertedY; + QSize m_size; }; QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp index 531bdc415..0ef8318fb 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp +++ b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp @@ -58,9 +58,7 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> -#include "wayland-brcm-server-protocol.h" - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class BrcmEglIntegrationPrivate { @@ -79,6 +77,7 @@ public: BrcmEglIntegration::BrcmEglIntegration() : QWaylandGraphicsHardwareIntegration() + , QtWaylandServer::qt_brcm() , d_ptr(new BrcmEglIntegrationPrivate) { } @@ -121,12 +120,11 @@ void BrcmEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay) return; } d->valid = true; + init(waylandDisplay->handle()); } - - wl_display_add_global(waylandDisplay->handle(), &wl_brcm_interface, this, brcm_bind_func); } -GLuint BrcmEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context) +GLuint BrcmEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { Q_D(BrcmEglIntegration); if (!d->valid) { @@ -134,7 +132,7 @@ GLuint BrcmEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLCon return 0; } - BrcmBuffer *brcmBuffer = QtWayland::wayland_cast<BrcmBuffer>(buffer); + BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer); if (!d->eglQueryGlobalImageBRCM(brcmBuffer->handle(), brcmBuffer->handle() + 2)) { qWarning("eglQueryGlobalImageBRCM failed!"); @@ -162,34 +160,25 @@ GLuint BrcmEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLCon return textureId; } -void BrcmEglIntegration::create_buffer(struct wl_client *client, - struct wl_resource *brcm, - uint32_t id, - int32_t width, - int32_t height, - wl_array *data) +bool BrcmEglIntegration::isYInverted(struct ::wl_resource *) const { - BrcmEglIntegration *that = static_cast<BrcmEglIntegration *>(brcm->data); - BrcmBuffer *buffer = new BrcmBuffer(that->m_compositor->handle(), QSize(width, height), static_cast<EGLint *>(data->data), data->size / sizeof(EGLint)); - buffer->addClientResource(client, &buffer->base()->resource, - id, &wl_buffer_interface, - &BrcmBuffer::buffer_interface, - BrcmBuffer::delete_resource); + return false; } -static struct wl_brcm_interface brcm_interface = { - BrcmEglIntegration::create_buffer -}; +void BrcmEglIntegration::brcm_bind_resource(Resource *) +{ +} -void BrcmEglIntegration::brcm_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id) +void BrcmEglIntegration::brcm_create_buffer(Resource *resource, uint32_t id, int32_t width, int32_t height, wl_array *data) { - Q_UNUSED(version); - BrcmEglIntegration *integration = static_cast<BrcmEglIntegration *>(data); - wl_client_add_object(client, &wl_brcm_interface, &brcm_interface, id, integration); + new BrcmBuffer(resource->client(), id, QSize(width, height), static_cast<EGLint *>(data->data), data->size / sizeof(EGLint)); } -bool BrcmEglIntegration::isYInverted(struct wl_buffer *buffer) const +QSize BrcmEglIntegration::bufferSize(struct ::wl_resource *buffer) const { - Q_UNUSED(buffer); - return false; + BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer); + + return brcmBuffer->size(); } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h index 8ed7f07a8..229905612 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h +++ b/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h @@ -42,31 +42,30 @@ #define BRCMEGLINTEGRATION_H #include <QtCompositor/qwaylandgraphicshardwareintegration.h> +#include "qwayland-server-brcm.h" + #include <QtCore/QScopedPointer> QT_BEGIN_NAMESPACE class BrcmEglIntegrationPrivate; -class BrcmEglIntegration : public QWaylandGraphicsHardwareIntegration +class BrcmEglIntegration : public QWaylandGraphicsHardwareIntegration, public QtWaylandServer::qt_brcm { Q_DECLARE_PRIVATE(BrcmEglIntegration) public: BrcmEglIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(struct wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; - static void create_buffer(struct wl_client *client, - struct wl_resource *brcm, - uint32_t id, - int32_t width, - int32_t height, - wl_array *data); + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; - static void brcm_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); +protected: + void brcm_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void brcm_create_buffer(Resource *resource, uint32_t id, int32_t width, int32_t height, wl_array *data) Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(BrcmEglIntegration) diff --git a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp index 2a923ceff..abf12fad4 100644 --- a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp +++ b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp @@ -60,6 +60,7 @@ #ifndef EGL_WL_bind_wayland_display typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_buffer *buffer, EGLint attribute, EGLint *value); #endif #ifndef EGL_KHR_image @@ -72,7 +73,7 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); #endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class WaylandEglIntegrationPrivate { @@ -80,28 +81,30 @@ public: WaylandEglIntegrationPrivate() : egl_display(EGL_NO_DISPLAY) , valid(false) + , display_bound(false) , flipperConnected(false) , egl_bind_wayland_display(0) , egl_unbind_wayland_display(0) + , egl_query_wayland_buffer(0) , egl_create_image(0) , egl_destroy_image(0) , gl_egl_image_target_texture_2d(0) { } EGLDisplay egl_display; bool valid; + bool display_bound; bool flipperConnected; #ifdef EGL_WL_request_client_buffer_format QPointer<WaylandSurface> directRenderSurface; #endif PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display; PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display; + PFNEGLQUERYWAYLANDBUFFERWL egl_query_wayland_buffer; PFNEGLCREATEIMAGEKHRPROC egl_create_image; PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d; - - QPlatformNativeInterface::NativeResourceForContextFunction get_egl_context; }; WaylandEglIntegration::WaylandEglIntegration() @@ -114,47 +117,66 @@ void WaylandEglIntegration::initializeHardware(QtWayland::Display *waylandDispla { Q_D(WaylandEglIntegration); + const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty(); + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - if (nativeInterface) { - d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window()); - if (d->egl_display) { - const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS); - if (extensionString && strstr(extensionString, "EGL_WL_bind_wayland_display")) - { - d->get_egl_context = nativeInterface->nativeResourceFunctionForContext("get_egl_context"); - if (!d->get_egl_context) { - qWarning("Failed to retrieve the get_egl_context function"); - } - d->egl_bind_wayland_display = - reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); - d->egl_unbind_wayland_display = - reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); - d->egl_create_image = - reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); - d->egl_destroy_image = - reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); - d->gl_egl_image_target_texture_2d = - reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); - - if (d->egl_bind_wayland_display - && d->get_egl_context - && d->egl_unbind_wayland_display - && d->egl_create_image - && d->egl_destroy_image - && d->gl_egl_image_target_texture_2d) { - if (d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle())) { - d->valid = true; - } - } - } - } + if (!nativeInterface) { + qWarning("Failed to initialize egl display. No native platform interface available.\n"); + return; + } + + d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window()); + if (!d->egl_display) { + qWarning("Failed to initialize egl display. Could not get EglDisplay for window.\n"); + return; + } + + const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS); + if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) { + qWarning("Failed to initialize egl display. There is no EGL_WL_bind_wayland_display extension.\n"); + return; + } - if (!d->valid) - qWarning("Failed to initialize egl display\n"); + d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); + d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); + if (!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display && !ignoreBindDisplay) { + qWarning("Failed to initialize egl display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.\n"); + return; } + + d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL>(eglGetProcAddress("eglQueryWaylandBufferWL")); + if (!d->egl_query_wayland_buffer) { + qWarning("Failed to initialize egl display. Could not find eglQueryWaylandBufferWL.\n"); + return; + } + + d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); + d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); + if (!d->egl_create_image || !d->egl_destroy_image) { + qWarning("Failed to initialize egl display. Could not find eglCreateImageKHR and eglDestroyImageKHR.\n"); + return; + } + + d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + if (!d->gl_egl_image_target_texture_2d) { + qWarning("Failed to initialize egl display. Could not find glEGLImageTargetTexture2DOES.\n"); + return; + } + + if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) { + d->display_bound = d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle()); + if (!d->display_bound || ignoreBindDisplay) { + qWarning("Failed to initialize egl display. Could not bind Wayland display.\n"); + return; + } + } + + d->valid = true; + + qWarning("EGL Wayland extension successfully initialized.%s\n", !d->display_bound ? " eglBindWaylandDisplayWL ignored" : ""); } -GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context) +GLuint WaylandEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { Q_D(WaylandEglIntegration); if (!d->valid) { @@ -162,10 +184,7 @@ GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGL return 0; } - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - EGLContext egl_context = d->get_egl_context(context); - - EGLImageKHR image = d->egl_create_image(d->egl_display, egl_context, + EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); @@ -186,7 +205,7 @@ GLuint WaylandEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGL return textureId; } -bool WaylandEglIntegration::isYInverted(struct wl_buffer *buffer) const +bool WaylandEglIntegration::isYInverted(struct ::wl_resource *buffer) const { #ifdef EGL_WL_request_client_buffer_format return eglGetBufferYInvertedWL(buffer); @@ -203,7 +222,7 @@ bool WaylandEglIntegration::setDirectRenderSurface(QWaylandSurface *surface) QPlatformScreen *screen = QPlatformScreen::platformScreenForWindow(m_compositor->window()); QPlatformScreenPageFlipper *flipper = screen ? screen->pageFlipper() : 0; if (flipper && !d->flipperConnected) { - QObject::connect(flipper, SIGNAL(bufferReleased(void*)), m_compositor->handle(), SLOT(releaseBuffer(void*))); + QObject::connect(flipper, SIGNAL(bufferReleased(QPlatformScreenBuffer*)), m_compositor->handle(), SLOT(releaseBuffer(QPlatformScreenBuffer*))); d->flipperConnected = true; } #ifdef EGL_WL_request_client_buffer_format @@ -225,14 +244,11 @@ bool WaylandEglIntegration::setDirectRenderSurface(QWaylandSurface *surface) return flipper; } -void *WaylandEglIntegration::lockNativeBuffer(struct wl_buffer *buffer, QOpenGLContext *context) const +void *WaylandEglIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *) const { Q_D(const WaylandEglIntegration); - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - EGLContext egl_context = d->get_egl_context(context); - - EGLImageKHR image = d->egl_create_image(d->egl_display, egl_context, + EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); return image; @@ -246,3 +262,15 @@ void WaylandEglIntegration::unlockNativeBuffer(void *native_buffer, QOpenGLConte d->egl_destroy_image(d->egl_display, image); } +QSize WaylandEglIntegration::bufferSize(struct ::wl_resource *buffer) const +{ + Q_D(const WaylandEglIntegration); + + int width, height; + d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_WIDTH, &width); + d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_HEIGHT, &height); + + return QSize(width, height); +} + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h index c22ff3158..ce3284291 100644 --- a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h +++ b/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h @@ -54,15 +54,17 @@ class WaylandEglIntegration : public QWaylandGraphicsHardwareIntegration public: WaylandEglIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(struct wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; - bool setDirectRenderSurface(QWaylandSurface *); + bool setDirectRenderSurface(QWaylandSurface *) Q_DECL_OVERRIDE; - virtual void *lockNativeBuffer(struct wl_buffer *buffer, QOpenGLContext *context) const; - virtual void unlockNativeBuffer(void *native_buffer, QOpenGLContext *context) const; + void *lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) const Q_DECL_OVERRIDE; + void unlockNativeBuffer(void *native_buffer, QOpenGLContext *context) const Q_DECL_OVERRIDE; + + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(WaylandEglIntegration) diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp index 72f2fbc2f..b80858b2c 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp @@ -40,7 +40,6 @@ #include "xcompositeeglintegration.h" -#include <QtCompositor/qwaylandobject.h> #include "wayland-xcomposite-server-protocol.h" #include <QtCompositor/private/qwlcompositor_p.h> @@ -54,7 +53,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QVector<EGLint> eglbuildSpec() { @@ -92,9 +91,9 @@ void XCompositeEglIntegration::initializeHardware(QtWayland::Display *) new XCompositeHandler(m_compositor->handle(), mDisplay); } -GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *) +GLuint XCompositeEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { - XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); QVector<EGLint> eglConfigSpec = eglbuildSpec(); @@ -135,8 +134,17 @@ GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpe return textureId; } -bool XCompositeEglIntegration::isYInverted(wl_buffer *buffer) const +bool XCompositeEglIntegration::isYInverted(struct ::wl_resource *buffer) const { - XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); return compositorBuffer->isYInverted(); } + +QSize XCompositeEglIntegration::bufferSize(struct ::wl_resource *buffer) const +{ + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); + + return compositorBuffer->size(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h index 7a9ac4499..562fce140 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h +++ b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h @@ -54,10 +54,12 @@ class XCompositeEglIntegration : public QWaylandGraphicsHardwareIntegration public: XCompositeEglIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; + + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: Display *mDisplay; diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp index 41d291203..421e5df1a 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp +++ b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp @@ -40,7 +40,6 @@ #include "xcompositeglxintegration.h" -#include <QtCompositor/qwaylandobject.h> #include <QtCompositor/private/qwlcompositor_p.h> #include "wayland-xcomposite-server-protocol.h" @@ -54,7 +53,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QVector<int> qglx_buildSpec() { @@ -113,9 +112,9 @@ void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *) delete glContext; } -GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_buffer *buffer, QOpenGLContext *) +GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) { - XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); QVector<int> glxConfigSpec = qglx_buildSpec(); @@ -146,7 +145,16 @@ GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_buffer *buf return textureId; } -bool XCompositeGLXIntegration::isYInverted(wl_buffer *buffer) const +bool XCompositeGLXIntegration::isYInverted(struct ::wl_resource *buffer) const { - return static_cast<XCompositeBuffer *>(buffer)->isYInverted(); + return XCompositeBuffer::fromResource(buffer)->isYInverted(); } + +QSize XCompositeGLXIntegration::bufferSize(struct ::wl_resource *buffer) const +{ + XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); + + return compositorBuffer->size(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h index 8e4db3937..11146ef23 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h +++ b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h @@ -59,10 +59,12 @@ public: XCompositeGLXIntegration(); ~XCompositeGLXIntegration(); - void initializeHardware(QtWayland::Display *waylandDisplay); + void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct wl_buffer *buffer, QOpenGLContext *context); - bool isYInverted(wl_buffer *) const; + GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; + + QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: PFNGLXBINDTEXIMAGEEXTPROC m_glxBindTexImageEXT; diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp index d7196b796..0457214b4 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp @@ -40,41 +40,30 @@ #include "xcompositebuffer.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE XCompositeBuffer::XCompositeBuffer(Window window, const QSize &size, struct ::wl_client *client, uint32_t id) - : mWindow(window) + : QtWaylandServer::wl_buffer(client, id) + , mWindow(window) , mInvertedY(false) + , mSize(size) { - base()->height = size.height(); - base()->width = size.width(); - - base()->resource.object.id = id; - base()->resource.object.interface = &::wl_buffer_interface; - base()->resource.object.implementation = (void (**)(void))&buffer_interface; - base()->resource.data = base(); - wl_client_add_resource(client, &base()->resource); - - base()->resource.destroy = delete_resource; } -struct wl_buffer_interface XCompositeBuffer::buffer_interface = { - XCompositeBuffer::buffer_interface_destroy -}; - -void XCompositeBuffer::buffer_interface_destroy(wl_client *client, wl_resource *buffer) +void XCompositeBuffer::buffer_destroy_resource(Resource *) { - Q_UNUSED(client); - Q_UNUSED(buffer); + delete this; } -void XCompositeBuffer::delete_resource(struct wl_resource *resource) +void XCompositeBuffer::buffer_destroy(Resource *resource) { - delete static_cast<XCompositeBuffer *>(static_cast<wl_buffer *>(resource->data)); + wl_resource_destroy(resource->handle); } Window XCompositeBuffer::window() { return mWindow; } + +QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h index 2a42aeb16..20cf399b6 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h @@ -41,8 +41,8 @@ #ifndef XCOMPOSITEBUFFER_H #define XCOMPOSITEBUFFER_H -#include <QtCompositor/qwaylandobject.h> #include <private/qwlcompositor_p.h> +#include <qwayland-server-wayland.h> #include <QtCore/QSize> @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE -class XCompositeBuffer : public QtWayland::Object<struct wl_buffer> +class XCompositeBuffer : public QtWaylandServer::wl_buffer { public: XCompositeBuffer(Window window, const QSize &size, @@ -63,18 +63,21 @@ public: Window window(); - static struct wl_buffer_interface buffer_interface; - static void delete_resource(struct wl_resource *resource); - bool isYInverted() const { return mInvertedY; } void setInvertedY(bool inverted) { mInvertedY = inverted; } + QSize size() const { return mSize; } + + static XCompositeBuffer *fromResource(struct ::wl_resource *resource) { return static_cast<XCompositeBuffer*>(Resource::fromResource(resource)->buffer); } + +protected: + void buffer_destroy_resource(Resource *) Q_DECL_OVERRIDE; + void buffer_destroy(Resource *) Q_DECL_OVERRIDE; + private: Window mWindow; bool mInvertedY; - - static void buffer_interface_destroy(struct wl_client *client, - struct wl_resource *buffer); + QSize mSize; }; QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp index 10a760750..0f10d38de 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp @@ -45,7 +45,7 @@ #include "xcompositebuffer.h" #include <X11/extensions/Xcomposite.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE XCompositeHandler::XCompositeHandler(QtWayland::Compositor *compositor, Display *display) : QtWaylandServer::qt_xcomposite(compositor->wl_display()) @@ -74,3 +74,5 @@ void XCompositeHandler::xcomposite_create_buffer(Resource *resource, uint32_t id { new XCompositeBuffer(Window(window), QSize(width, height), resource->client(), id); } + +QT_END_NAMESPACE |