From 440f69906db3f4c9947a13186a91e842e56d0c7c Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 10 Jun 2011 11:59:01 +0200 Subject: Handle really global selection offers in wayland clipboard. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle selection offer globals properly even if they arrive during the initial blocking read. If such a global arrives so early, the platform integration is not yet available from QApplicationPrivate (as it is just being constructed). Therefore the handling of the selection offer has to be delayed. At the moment selection offers are typically posted as globals and not added to the global list, but that is likely to change in the future. Change-Id: Ib4ae804ad7f19e05978ee08828b88e028a3bf7b2 Reviewed-on: http://codereview.qt.nokia.com/446 Reviewed-by: Qt Sanity Bot Reviewed-by: Jørgen Lind --- src/plugins/platforms/wayland/qwaylanddisplay.cpp | 21 +++++++++++++++++---- src/plugins/platforms/wayland/qwaylanddisplay.h | 4 ++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 83516e9..e6d3968 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -129,6 +129,8 @@ const struct wl_shell_listener QWaylandDisplay::shellListener = { QWaylandDisplay::QWaylandDisplay(void) : argb_visual(0), premultiplied_argb_visual(0), rgb_visual(0) { + qRegisterMetaType("uint32_t"); + mDisplay = wl_display_connect(NULL); if (mDisplay == NULL) { qErrnoWarning(errno, "Failed to create display"); @@ -147,8 +149,6 @@ QWaylandDisplay::QWaylandDisplay(void) blockingReadEvents(); - qRegisterMetaType("uint32_t"); - #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration->initialize(); #endif @@ -291,11 +291,24 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, mInputDevices.append(inputDevice); } else if (interface == "wl_selection_offer") { QPlatformIntegration *plat = QApplicationPrivate::platformIntegration(); - QWaylandClipboard *clipboard = static_cast(plat->clipboard()); - clipboard->createSelectionOffer(id); + mSelectionOfferId = id; + if (plat) + handleSelectionOffer(id); + else + QMetaObject::invokeMethod(this, "handleSelectionOffer", + Qt::QueuedConnection, Q_ARG(uint32_t, id)); } } +void QWaylandDisplay::handleSelectionOffer(uint32_t id) +{ + if (mSelectionOfferId != id) + return; + QPlatformIntegration *plat = QApplicationPrivate::platformIntegration(); + QWaylandClipboard *clipboard = static_cast(plat->clipboard()); + clipboard->createSelectionOffer(id); +} + void QWaylandDisplay::handleVisual(void *data, struct wl_compositor *compositor, uint32_t id, uint32_t token) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index 765be62..ff8c760 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -97,6 +97,9 @@ public slots: void blockingReadEvents(); void flushRequests(); +private slots: + void handleSelectionOffer(uint32_t id); + private: void waitForScreens(); void displayHandleGlobal(uint32_t id, @@ -115,6 +118,7 @@ private: bool mScreensInitialized; uint32_t mSocketMask; + uint32_t mSelectionOfferId; struct wl_visual *argb_visual, *premultiplied_argb_visual, *rgb_visual; -- cgit v1.2.3 From 008d9c9e6e26dcd241ff0341206926f1d55a61bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 22 Jun 2011 10:00:28 +0200 Subject: Update the wayland plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit to sha1 bfea3d6befdb688d5354e6f15a9400ea637febf9 Change-Id: Ie855cfbc6b786f1e738e205d403478614774ad34 Reviewed-on: http://codereview.qt.nokia.com/682 Reviewed-by: Qt Sanity Bot Reviewed-by: Samuel Rødal --- src/plugins/platforms/wayland/qwaylanddisplay.cpp | 27 +++++++++++++++++++---- src/plugins/platforms/wayland/qwaylanddisplay.h | 11 ++++++++- src/plugins/platforms/wayland/qwaylandwindow.cpp | 9 ++++---- src/plugins/platforms/wayland/wayland_sha1.txt | 2 +- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index e6d3968..93c98e3 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -232,17 +232,36 @@ int QWaylandDisplay::sourceUpdate(uint32_t mask, void *data) } void QWaylandDisplay::outputHandleGeometry(void *data, - struct wl_output *output, + wl_output *output, int32_t x, int32_t y, - int32_t width, int32_t height) + int32_t physicalWidth, + int32_t physicalHeight, + int subpixel, + const char *make, const char *model) { QWaylandDisplay *waylandDisplay = static_cast(data); - QRect outputRect = QRect(x, y, width, height); + QRect outputRect = QRect(x, y, physicalWidth, physicalHeight); waylandDisplay->createNewScreen(output,outputRect); } +void QWaylandDisplay::mode(void *data, + struct wl_output *wl_output, + uint32_t flags, + int width, + int height, + int refresh) +{ + Q_UNUSED(data); + Q_UNUSED(wl_output); + Q_UNUSED(flags); + Q_UNUSED(width); + Q_UNUSED(height); + Q_UNUSED(refresh); +} + const struct wl_output_listener QWaylandDisplay::outputListener = { - QWaylandDisplay::outputHandleGeometry + QWaylandDisplay::outputHandleGeometry, + QWaylandDisplay::mode }; const struct wl_compositor_listener QWaylandDisplay::compositorListener = { diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index ff8c760..87a3167 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -132,7 +132,16 @@ private: static void outputHandleGeometry(void *data, struct wl_output *output, int32_t x, int32_t y, - int32_t width, int32_t height); + int32_t width, int32_t height, + int subpixel, + const char *make, + const char *model); + static void mode(void *data, + struct wl_output *wl_output, + uint32_t flags, + int width, + int height, + int refresh); static void handleVisual(void *data, struct wl_compositor *compositor, diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index eda8c94..3afe907 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -58,6 +58,7 @@ QWaylandWindow::QWaylandWindow(QWidget *window) : QPlatformWindow(window) + , mSurface(0) , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display()) , mBuffer(0) , mWaitingForFrameSync(false) @@ -69,8 +70,6 @@ QWaylandWindow::QWaylandWindow(QWidget *window) mDisplay->windowManagerIntegration()->mapClientToProcess(qApp->applicationPid()); mDisplay->windowManagerIntegration()->authenticateWithToken(); #endif - - mSurface = mDisplay->createSurface(this); } QWaylandWindow::~QWaylandWindow() @@ -101,9 +100,7 @@ void QWaylandWindow::setVisible(bool visible) newSurfaceCreated(); } - if (visible) { - wl_surface_map_toplevel(mSurface); - } else { + if (!visible) { wl_surface_destroy(mSurface); mSurface = NULL; } @@ -143,6 +140,8 @@ void QWaylandWindow::damage(const QRegion ®ion) wl_buffer_damage(mBuffer->buffer(), rect.x(), rect.y(), rect.width(), rect.height()); wl_surface_damage(mSurface, rect.x(), rect.y(), rect.width(), rect.height()); + wl_buffer_damage(mBuffer->buffer(), + rect.x(), rect.y(), rect.width(), rect.height()); } } diff --git a/src/plugins/platforms/wayland/wayland_sha1.txt b/src/plugins/platforms/wayland/wayland_sha1.txt index d262437..a696e76 100644 --- a/src/plugins/platforms/wayland/wayland_sha1.txt +++ b/src/plugins/platforms/wayland/wayland_sha1.txt @@ -1,3 +1,3 @@ This version of the Qt Wayland plugin is checked against the following sha1 from the Wayland repository: -eff7fc0d99be2e51eaa351785030c8d374ac71de +bfea3d6befdb688d5354e6f15a9400ea637febf9 -- cgit v1.2.3 From 16308e1d2732eae209a66ef9012bd968279ef01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 23 Jun 2011 10:14:51 +0200 Subject: Make sure to call damage on the buffer when we damage it Change-Id: Id325a1dee322c2b37215e6577870068260f5f7cc Reviewed-on: http://codereview.qt.nokia.com/683 Reviewed-by: Qt Sanity Bot Reviewed-by: Laszlo Agocs --- .../xcomposite_egl/qwaylandxcompositeeglcontext.cpp | 2 +- .../xcomposite_glx/qwaylandxcompositeglxcontext.cpp | 2 +- .../platforms/wayland/qwaylandshmsurface.cpp | 7 ++++++- src/plugins/platforms/wayland/qwaylandwindow.cpp | 21 +++++++++------------ src/plugins/platforms/wayland/qwaylandwindow.h | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp index 72de02a..999a411 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp @@ -91,7 +91,7 @@ void QWaylandXCompositeEGLContext::swapBuffers() QSize size = mWindow->geometry().size(); eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface); - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); + mWindow->damage(QRect(QPoint(0,0),size)); mWindow->waitForFrameSync(); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp index dff6ffa..3d49790 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp @@ -81,7 +81,7 @@ void QWaylandXCompositeGLXContext::swapBuffers() QSize size = mWindow->geometry().size(); glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow); - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); + mWindow->damage(QRect(QPoint(0,0),size)); mWindow->waitForFrameSync(); } diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp index efc56bb..b24c419 100644 --- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp @@ -120,7 +120,12 @@ void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion ®ion, con Q_UNUSED(offset); QWaylandShmWindow *waylandWindow = static_cast(window()->platformWindow()); Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); - waylandWindow->damage(region); + QVector rects = region.rects(); + for (int i = 0; i < rects.size(); i++) { + const QRect rect = rects.at(i); + wl_buffer_damage(mBuffer->buffer(),rect.x(),rect.y(),rect.width(),rect.height()); + waylandWindow->damage(rect); + } } void QWaylandShmWindowSurface::resize(const QSize &size) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 3afe907..e79a712 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -127,28 +127,25 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer) } } -void QWaylandWindow::damage(const QRegion ®ion) +void QWaylandWindow::damage(const QRect &rect) { //We have to do sync stuff before calling damage, or we might //get a frame callback before we get the timestamp - mDisplay->frameCallback(QWaylandWindow::frameCallback, mSurface, this); - mWaitingForFrameSync = true; - - QVector rects = region.rects(); - for (int i = 0; i < rects.size(); i++) { - const QRect rect = rects.at(i); - wl_buffer_damage(mBuffer->buffer(), rect.x(), rect.y(), rect.width(), rect.height()); - wl_surface_damage(mSurface, - rect.x(), rect.y(), rect.width(), rect.height()); - wl_buffer_damage(mBuffer->buffer(), - rect.x(), rect.y(), rect.width(), rect.height()); + if (!mWaitingForFrameSync) { + mDisplay->frameCallback(QWaylandWindow::frameCallback, mSurface, this); + mWaitingForFrameSync = true; } + + wl_surface_damage(mSurface, + rect.x(), rect.y(), rect.width(), rect.height()); } void QWaylandWindow::newSurfaceCreated() { if (mBuffer) { wl_surface_attach(mSurface,mBuffer->buffer(),0,0); + wl_surface_damage(mSurface, + 0,0,mBuffer->size().width(),mBuffer->size().height()); } } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index b8eae96..b91f6b6 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -71,7 +71,7 @@ public: int32_t x, int32_t y, int32_t width, int32_t height); void attach(QWaylandBuffer *buffer); - void damage(const QRegion ®ion); + void damage(const QRect &rect); void waitForFrameSync(); -- cgit v1.2.3 From c5e1b5c1a817000b4d9066cb3c53ac9721c7ba18 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 23 Jun 2011 18:07:20 +0200 Subject: Have the selection offer global handled always without delay. In a previous attempt to solve the problem of selection offer globals arriving too early, the handling was delayed. This solved the issue of crashing but introduced a timing issue, because the offers (the mime types) will arrive immediately after the global and therefore will simply be ignored in case the delayed processing of the selection offer had not yet been done. The visibility of the problem depended on the implementation of the compositor, with recent changes to qt-compositor the issue is very visible. The patch solves the issue properly: The wayland clipboard instance is created right away, as early when needed, and the integration will simply pick up the already created instance. Change-Id: I75aaba4b0590c05cc0091bed7bb3593186c1188f Reviewed-on: http://codereview.qt.nokia.com/687 Reviewed-by: Qt Sanity Bot Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/wayland/qwaylandclipboard.cpp | 10 ++++++++-- src/plugins/platforms/wayland/qwaylandclipboard.h | 5 ++++- src/plugins/platforms/wayland/qwaylanddisplay.cpp | 20 ++++---------------- src/plugins/platforms/wayland/qwaylanddisplay.h | 4 ---- .../platforms/wayland/qwaylandintegration.cpp | 5 +---- src/plugins/platforms/wayland/qwaylandintegration.h | 1 - 6 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp index b7f6ae5..1ef063f 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -50,7 +50,7 @@ #include #include -static QWaylandClipboard *clipboard; +static QWaylandClipboard *clipboard = 0; class QWaylandMimeData : public QInternalMimeData { @@ -162,10 +162,16 @@ void QWaylandSelection::cancelled(void *data, struct wl_selection *selection) delete static_cast(data); } +QWaylandClipboard *QWaylandClipboard::instance(QWaylandDisplay *display) +{ + if (!clipboard) + clipboard = new QWaylandClipboard(display); + return clipboard; +} + QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) : mDisplay(display), mMimeDataIn(0), mOffer(0) { - clipboard = this; } QWaylandClipboard::~QWaylandClipboard() diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.h b/src/plugins/platforms/wayland/qwaylandclipboard.h index f45fb8d..8729434 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.h +++ b/src/plugins/platforms/wayland/qwaylandclipboard.h @@ -61,7 +61,8 @@ public slots: class QWaylandClipboard : public QPlatformClipboard { public: - QWaylandClipboard(QWaylandDisplay *display); + static QWaylandClipboard *instance(QWaylandDisplay *display); + ~QWaylandClipboard(); QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); @@ -75,6 +76,8 @@ public: QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; private: + QWaylandClipboard(QWaylandDisplay *display); + static void offer(void *data, struct wl_selection_offer *selection_offer, const char *type); diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 93c98e3..69ec6ad 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -126,9 +126,12 @@ const struct wl_shell_listener QWaylandDisplay::shellListener = { QWaylandDisplay::shellHandleConfigure, }; +static QWaylandDisplay *display = 0; + QWaylandDisplay::QWaylandDisplay(void) : argb_visual(0), premultiplied_argb_visual(0), rgb_visual(0) { + display = this; qRegisterMetaType("uint32_t"); mDisplay = wl_display_connect(NULL); @@ -309,25 +312,10 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, new QWaylandInputDevice(mDisplay, id); mInputDevices.append(inputDevice); } else if (interface == "wl_selection_offer") { - QPlatformIntegration *plat = QApplicationPrivate::platformIntegration(); - mSelectionOfferId = id; - if (plat) - handleSelectionOffer(id); - else - QMetaObject::invokeMethod(this, "handleSelectionOffer", - Qt::QueuedConnection, Q_ARG(uint32_t, id)); + QWaylandClipboard::instance(display)->createSelectionOffer(id); } } -void QWaylandDisplay::handleSelectionOffer(uint32_t id) -{ - if (mSelectionOfferId != id) - return; - QPlatformIntegration *plat = QApplicationPrivate::platformIntegration(); - QWaylandClipboard *clipboard = static_cast(plat->clipboard()); - clipboard->createSelectionOffer(id); -} - void QWaylandDisplay::handleVisual(void *data, struct wl_compositor *compositor, uint32_t id, uint32_t token) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index 87a3167..4dff24d 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -97,9 +97,6 @@ public slots: void blockingReadEvents(); void flushRequests(); -private slots: - void handleSelectionOffer(uint32_t id); - private: void waitForScreens(); void displayHandleGlobal(uint32_t id, @@ -118,7 +115,6 @@ private: bool mScreensInitialized; uint32_t mSocketMask; - uint32_t mSelectionOfferId; struct wl_visual *argb_visual, *premultiplied_argb_visual, *rgb_visual; diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 8257bca..5df71dc 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -65,7 +65,6 @@ QWaylandIntegration::QWaylandIntegration(bool useOpenGL) , mDisplay(new QWaylandDisplay()) , mUseOpenGL(useOpenGL) , mNativeInterface(new QWaylandNativeInterface) - , mClipboard(0) { } @@ -137,7 +136,5 @@ bool QWaylandIntegration::hasOpenGL() const QPlatformClipboard *QWaylandIntegration::clipboard() const { - if (!mClipboard) - mClipboard = new QWaylandClipboard(mDisplay); - return mClipboard; + return QWaylandClipboard::instance(mDisplay); } diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index c7dc89d..f617d96 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -74,7 +74,6 @@ private: QWaylandDisplay *mDisplay; bool mUseOpenGL; QPlatformNativeInterface *mNativeInterface; - mutable QPlatformClipboard *mClipboard; }; QT_END_NAMESPACE -- cgit v1.2.3