diff options
author | Giulio Camuffo <giuliocamuffo@gmail.com> | 2012-11-05 00:12:15 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@digia.com> | 2013-01-10 16:47:53 +0100 |
commit | f7b58cccba239b16d18379afbd4117e4432790c4 (patch) | |
tree | 5a8f713c1cc282030d43252abeace6ce83efb4b4 /src/plugins | |
parent | 1ddfb323388ff079d1e492ca8bb6ea0e08344bd5 (diff) |
Implemented moving and resizing using the decorations.
Change-Id: I4153b72876b272c508264c82ac10def68ee4349d
Reviewed-by: Andy Nichols <andy.nichols@digia.com>
Diffstat (limited to 'src/plugins')
12 files changed, 110 insertions, 30 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index 73768ddd6..caed3dfe0 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -87,25 +87,25 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const return QWaylandWindow::Egl; } -void QWaylandEglWindow::setGeometry(const QRect &rect) +void QWaylandEglWindow::redraw() { createDecoration(); QMargins margins = frameMargins(); - QSize sizeWithMargins = rect.size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); + QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); if (m_waylandEglWindow) { int current_width, current_height; wl_egl_window_get_attached_size(m_waylandEglWindow,¤t_width,¤t_height); if (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) { waitForFrameSync(); - wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), 0, 0); + wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y()); + mOffset = QPoint(); m_resize = true; } } else { m_waylandEglWindow = wl_egl_window_create(mSurface, sizeWithMargins.width(), sizeWithMargins.height()); } - QWaylandWindow::setGeometry(rect); } QRect QWaylandEglWindow::contentsRect() const @@ -122,6 +122,13 @@ QSurfaceFormat QWaylandEglWindow::format() const EGLSurface QWaylandEglWindow::eglSurface() const { + if (!m_waylandEglWindow) { + const_cast<QWaylandEglWindow *>(this)->createDecoration(); + QMargins margins = frameMargins(); + QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); + m_waylandEglWindow = wl_egl_window_create(mSurface, sizeWithMargins.width(), sizeWithMargins.height()); + } + if (!m_eglSurface) { m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true); const_cast<QWaylandEglWindow *>(this)->m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(),m_eglConfig); diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 1e1b99925..4a7b3054a 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -55,7 +55,6 @@ public: QWaylandEglWindow(QWindow *window); ~QWaylandEglWindow(); WindowType windowType() const; - void setGeometry(const QRect &rect); QRect contentsRect() const; @@ -67,12 +66,14 @@ public: void bindContentFBO(); + void redraw(); + protected: void createDecorationInstance(); private: QWaylandEglIntegration *m_eglIntegration; - struct wl_egl_window *m_waylandEglWindow; + mutable struct wl_egl_window *m_waylandEglWindow; const QWaylandWindow *m_parentWindow; diff --git a/src/plugins/platforms/wayland/qwaylanddecoration.cpp b/src/plugins/platforms/wayland/qwaylanddecoration.cpp index f9a580c2a..258a54495 100644 --- a/src/plugins/platforms/wayland/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland/qwaylanddecoration.cpp @@ -183,7 +183,7 @@ void QWaylandDecoration::paint(QPaintDevice *device) p.restore(); } -void QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { Q_UNUSED(global); @@ -198,17 +198,19 @@ void QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo m_wayland_window->shellSurface()->minimize(); } else if (local.y() <= m_margins.top()) { processMouseTop(inputDevice,local,b,mods); - } else if (local.y() > m_window->height() - m_margins.bottom()) { + } else if (local.y() > m_window->height() - m_margins.bottom() + m_margins.top()) { processMouseBottom(inputDevice,local,b,mods); } else if (local.x() <= m_margins.left()) { processMouseLeft(inputDevice,local,b,mods); - } else if (local.x() > m_window->width() - m_margins.right()) { + } else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) { processMouseRight(inputDevice,local,b,mods); } else { restoreMouseCursor(); + return false; } m_mouseButtons = b; + return true; } void QWaylandDecoration::restoreMouseCursor() diff --git a/src/plugins/platforms/wayland/qwaylanddecoration.h b/src/plugins/platforms/wayland/qwaylanddecoration.h index 91d32d561..30a5e31fa 100644 --- a/src/plugins/platforms/wayland/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland/qwaylanddecoration.h @@ -68,7 +68,7 @@ public: virtual void paintDecoration() = 0; - void handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); + bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); void restoreMouseCursor(); bool inMouseButtonPressedState() const; diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 7964f4cb5..33dc0c58d 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -175,10 +175,21 @@ void QWaylandDisplay::createNewScreen(struct wl_output *output) mScreens.append(waylandScreen); } +void QWaylandDisplay::scheduleRedraw(QWaylandWindow *window) +{ + if (!mWindows.contains(window)) + mWindows << window; +} + void QWaylandDisplay::flushRequests() { wl_display_dispatch_pending(mDisplay); wl_display_flush(mDisplay); + + foreach (QWaylandWindow *w, mWindows) { + w->redraw(); + } + mWindows.clear(); } void QWaylandDisplay::readEvents() diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index 5d2374ac4..84558dbff 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -64,6 +64,7 @@ class QWaylandSubSurfaceExtension; class QWaylandOutputExtension; class QWaylandTouchExtension; class QWaylandQtKeyExtension; +class QWaylandWindow; typedef void (*RegistryListener)(void *data, struct wl_registry *registry, @@ -122,6 +123,8 @@ public: void forceRoundTrip(); + void scheduleRedraw(QWaylandWindow *window); + public slots: void createNewScreen(struct wl_output *output); void readEvents(); @@ -147,6 +150,7 @@ private: QList<QPlatformScreen *> mScreens; QList<QWaylandInputDevice *> mInputDevices; QList<Listener> mRegistryListeners; + QList<QWaylandWindow *> mWindows; QWaylandInputDevice *mLastKeyboardFocusInputDevice; QWaylandDataDeviceManager *mDndSelectionHandler; QWaylandSurfaceExtension *mWindowExtension; diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 7bb9480ce..e7ffc6234 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -206,7 +206,7 @@ void QWaylandInputDevice::setCursor(wl_surface *surface, int x, int y) void QWaylandInputDevice::pointer_enter(void *data, struct wl_pointer *pointer, - uint32_t time, struct wl_surface *surface, + uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { Q_UNUSED(pointer); @@ -221,7 +221,8 @@ void QWaylandInputDevice::pointer_enter(void *data, window->handleMouseEnter(); inputDevice->mPointerFocus = window; - inputDevice->mTime = time; + inputDevice->mTime = QWaylandDisplay::currentTimeMillisec(); + inputDevice->mSerial = serial; } void QWaylandInputDevice::pointer_leave(void *data, @@ -318,6 +319,7 @@ void QWaylandInputDevice::pointer_button(void *data, inputDevice->mButtons &= ~qt_button; inputDevice->mTime = time; + inputDevice->mSerial = serial; if (window) { window->handleMouse(inputDevice, diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h index 71bb0385a..6678c25a3 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h @@ -80,6 +80,8 @@ public: void removeMouseButtonFromState(Qt::MouseButton button); + uint32_t serial() const; + private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; @@ -102,6 +104,7 @@ private: QPointF mSurfacePos; QPointF mGlobalPos; uint32_t mTime; + uint32_t mSerial; static const struct wl_seat_listener seatListener; @@ -113,7 +116,7 @@ private: static void pointer_enter(void *data, struct wl_pointer *pointer, - uint32_t time, struct wl_surface *surface, + uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy); static void pointer_leave(void *data, struct wl_pointer *pointer, @@ -202,6 +205,11 @@ private: friend class QWaylandQtKeyExtension; }; +inline uint32_t QWaylandInputDevice::serial() const +{ + return mSerial; +} + QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp index 8403341e3..53a447214 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp @@ -45,6 +45,7 @@ #include "qwaylandwindow.h" #include "qwaylandinputdevice.h" #include "qwaylanddecoration.h" +#include "qwaylandscreen.h" #include <QtCore/QDebug> @@ -64,7 +65,7 @@ QWaylandShellSurface::~QWaylandShellSurface() void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) { wl_shell_surface_resize(m_shell_surface,inputDevice->wl_seat(), - QWaylandDisplay::currentTimeMillisec(), + inputDevice->serial(), edges); } @@ -72,7 +73,7 @@ void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice) { wl_shell_surface_move(m_shell_surface, inputDevice->wl_seat(), - QWaylandDisplay::currentTimeMillisec()); + inputDevice->serial()); } void QWaylandShellSurface::toggleMaximize() diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index d41bfe156..8300d9c9b 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -202,16 +202,23 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons wl_callback_add_listener(mFrameCallback,&frameCallbackListener,this); QMargins margins = windowDecorationMargins(); + bool damageAll = false; if (waylandWindow()->attached() != mFrontBuffer) { delete waylandWindow()->attached(); - waylandWindow()->attach(mFrontBuffer); + waylandWindow()->attachOffset(mFrontBuffer); + damageAll = true; } - QVector<QRect> rects = region.rects(); - for (int i = 0; i < rects.size(); i++) { - QRect rect = rects.at(i); - rect.translate(margins.left(),margins.top()); - waylandWindow()->damage(rect); + if (damageAll) { + //need to damage it all, otherwise the attach offset may screw up + waylandWindow()->damage(QRect(QPoint(0,0),mFrontBuffer->size())); + } else { + QVector<QRect> rects = region.rects(); + for (int i = 0; i < rects.size(); i++) { + QRect rect = rects.at(i); + rect.translate(margins.left(),margins.top()); + waylandWindow()->damage(rect); + } } mFrontBufferIsDirty = false; } @@ -223,7 +230,6 @@ void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) void QWaylandShmBackingStore::resize(const QSize &size) { - QMargins margins = windowDecorationMargins(); QSize sizeWithMargins = size + QSize(margins.left()+margins.right(),margins.top()+margins.bottom()); @@ -254,14 +260,16 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t static_cast<QWaylandShmBackingStore *>(data); if (callback != self->mFrameCallback) // others, like QWaylandWindow, may trigger callbacks too return; - QWaylandWindow *window = self->waylandWindow(); + QWaylandShmWindow *window = self->waylandWindow(); wl_callback_destroy(self->mFrameCallback); self->mFrameCallback = 0; + if (self->mFrontBuffer != window->attached()) { delete window->attached(); - window->attach(self->mFrontBuffer); } + window->attachOffset(self->mFrontBuffer); + if (self->mFrontBufferIsDirty && !self->mPainting) { self->mFrontBufferIsDirty = false; self->mFrameCallback = wl_surface_frame(window->wl_surface()); diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 1e48bfdea..64170d24a 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -154,6 +154,8 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (shellSurface() && window()->transientParent()) shellSurface()->updateTransientParent(window()->transientParent()); + + mDisplay->scheduleRedraw(this); } void QWaylandWindow::setVisible(bool visible) @@ -201,19 +203,45 @@ void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) heightWithoutMargins = qMax(heightWithoutMargins, window()->minimumSize().height()); QRect geometry = QRect(0,0, widthWithoutMargins, heightWithoutMargins); + + int x = 0; + int y = 0; + QSize size = this->geometry().size(); + if (edges == WL_SHELL_SURFACE_RESIZE_LEFT || edges == WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT || + edges == WL_SHELL_SURFACE_RESIZE_TOP_LEFT) { + x = size.width() - geometry.width(); + } + if (edges == WL_SHELL_SURFACE_RESIZE_TOP || edges == WL_SHELL_SURFACE_RESIZE_TOP_LEFT || + edges == WL_SHELL_SURFACE_RESIZE_TOP_RIGHT) { + y = size.height() - geometry.height(); + } + mOffset += QPoint(x, y); + setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(window(), geometry); + QWindowSystemInterface::flushWindowSystemEvents(); +} + +void QWaylandWindow::redraw() +{ + } -void QWaylandWindow::attach(QWaylandBuffer *buffer) +void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { mBuffer = buffer; if (window()->isVisible()) { - wl_surface_attach(mSurface, mBuffer->buffer(),0,0); + wl_surface_attach(mSurface, mBuffer->buffer(), x, y); } } +void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) +{ + attach(buffer, mOffset.x(), mOffset.y()); + mOffset = QPoint(); +} + QWaylandBuffer *QWaylandWindow::attached() const { return mBuffer; @@ -380,10 +408,8 @@ void QWaylandWindow::handleMouseLeave() void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { - if (mWindowDecoration->inMouseButtonPressedState()) { - mWindowDecoration->handleMouse(inputDevice,local,global,b,mods); + if (mWindowDecoration->handleMouse(inputDevice,local,global,b,mods)) return; - } QMargins marg = frameMargins(); QRect windowRect(0 + marg.left(), diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index 3accd3ca8..0e379e5df 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -78,8 +78,10 @@ public: void configure(uint32_t edges, int32_t width, int32_t height); - void attach(QWaylandBuffer *buffer); + void attach(QWaylandBuffer *buffer, int x, int y); + void attachOffset(QWaylandBuffer *buffer); QWaylandBuffer *attached() const; + QPoint attachOffset() const; void damage(const QRect &rect); @@ -115,6 +117,8 @@ public: bool createDecoration(); + virtual void redraw(); + protected: virtual void createDecorationInstance() {} @@ -135,6 +139,7 @@ protected: QWaitCondition mFrameSyncWait; bool mSentInitialResize; + QPoint mOffset; private: void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, @@ -149,5 +154,10 @@ private: }; +inline QPoint QWaylandWindow::attachOffset() const +{ + return mOffset; +} + #endif // QWAYLANDWINDOW_H |