diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2012-02-13 10:23:41 +0100 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2012-04-11 13:41:59 +0200 |
commit | f984c7985ca26096dd293f18ba4d0b8271fdb4f5 (patch) | |
tree | 76293fd58a3124a2216585951ccb58fa47f14f9a /src/plugins | |
parent | 921fefbf2a5e4078f4dff19c3c664cbbd9b751d1 (diff) |
Client side decoration
Something is alot better than nothing :)
This gives window decorations for QWidgets and other applications that
use QBackingStore
Change-Id: Ic748ee1df88236b20416029e20e26532f7fb4476
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src/plugins')
17 files changed, 768 insertions, 75 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 44e7fdecc..4db506c18 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -70,9 +70,7 @@ QWaylandEglWindow::~QWaylandEglWindow() m_eglSurface = 0; } - if (m_waylandEglWindow) { - wl_egl_window_destroy(m_waylandEglWindow); - } + wl_egl_window_destroy(m_waylandEglWindow); } QWaylandWindow::WindowType QWaylandEglWindow::windowType() const @@ -82,13 +80,14 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const void QWaylandEglWindow::setGeometry(const QRect &rect) { - QWaylandWindow::setGeometry(rect); - if (m_waylandEglWindow){ + int current_width, current_height; + wl_egl_window_get_attached_size(m_waylandEglWindow,¤t_width,¤t_height); + if (current_width != rect.width() || current_height != rect.height()) { + waitForFrameSync(); wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0); - QWindowSystemInterface::handleGeometryChange(window(), rect); } + QWaylandWindow::setGeometry(rect); } - QSurfaceFormat QWaylandEglWindow::format() const { return m_format; @@ -96,9 +95,6 @@ QSurfaceFormat QWaylandEglWindow::format() const EGLSurface QWaylandEglWindow::eglSurface() const { - if (!m_waylandEglWindow) - return 0; - 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/qwaylanddecoration.cpp b/src/plugins/platforms/wayland/qwaylanddecoration.cpp new file mode 100644 index 000000000..749d12611 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddecoration.cpp @@ -0,0 +1,189 @@ +#include "qwaylanddecoration.h" + +#include "qwaylandwindow.h" +#include "qwaylandshmbackingstore.h" +#include "qwaylandshellsurface.h" +#include "qwaylandinputdevice.h" + +#include <QtGui/QGuiApplication> +#include <QtGui/QCursor> +#include <QtGui/QPainter> +#include <QtGui/QRadialGradient> +QWaylandDecoration::QWaylandDecoration(QWindow *window, QWaylandShmBackingStore *backing_store) + : m_window(window) + , m_wayland_window(static_cast<QWaylandWindow *>(window->handle())) + , m_backing_store(backing_store) + , m_margins(3,30,3,3) + , m_mouseButtons(Qt::NoButton) + , m_hasSetCursor(false) +{ + m_wayland_window->setDecoration(this); + QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter); + option.setWrapMode(QTextOption::NoWrap); + m_windowTitle.setTextOption(option); +} + +QWaylandDecoration::~QWaylandDecoration() +{ + m_wayland_window->setDecoration(0); +} + +void QWaylandDecoration::paintDecoration() +{ + QRect surfaceRect(QPoint(), m_backing_store->entireSurface()->size()); + QRect clips[] = + { + QRect(0, 0, surfaceRect.width(), m_margins.top()), + QRect(0, surfaceRect.height() - m_margins.bottom(), surfaceRect.width(), m_margins.bottom()), + QRect(0, m_margins.top(), m_margins.left(), surfaceRect.height() - m_margins.top() - m_margins.bottom()), + QRect(surfaceRect.width() - m_margins.right(), m_margins.top(), m_margins.left(), surfaceRect.height() - m_margins.top() - m_margins.bottom()) + }; + QRect top = clips[0]; + QPainter p(m_backing_store->entireSurface()); + p.setRenderHint(QPainter::Antialiasing); + QPoint gradCenter(top.center()+ QPoint(30,60)); + QRadialGradient grad(gradCenter, top.width() / 2, gradCenter); + QColor base(90, 90, 100); + grad.setColorAt(1, base); + grad.setColorAt(0, base.lighter(123)); + QPainterPath roundedRect; + roundedRect.addRoundedRect(surfaceRect, 6, 6); + for (int i = 0; i < 4; ++i) { + p.save(); + p.setClipRect(clips[i]); + p.fillPath(roundedRect, grad); + p.restore(); + } + + + QString windowTitleText = m_window->windowTitle(); + if (!windowTitleText.isEmpty()) { + if (m_windowTitle.text() != windowTitleText) { + m_windowTitle.setText(windowTitleText); + m_windowTitle.prepare(); + } + p.save(); + p.setClipRect(top); + p.setPen(QColor(0xee,0xee,0xee)); + QSizeF size = m_windowTitle.size(); + int dx = (top.width() - size.width()) /2; + int dy = (top.height()- size.height()) /2; + QPoint windowTitlePoint(top.topLeft().x() + dx, + top.topLeft().y() + dy); + p.drawStaticText(windowTitlePoint,m_windowTitle); + p.restore(); + } +} + +void QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) + +{ + //figure out what area mouse is in + if (local.y() <= m_margins.top()) { + processMouseTop(inputDevice,local,b,mods); + } else if (local.y() > m_window->height() - m_margins.bottom()) { + 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()) { + processMouseRight(inputDevice,local,b,mods); + } else { + restoreMouseCursor(); + } + m_mouseButtons = b; +} + +void QWaylandDecoration::restoreMouseCursor() +{ + if (m_hasSetCursor) { + QGuiApplication::restoreOverrideCursor(); + m_hasSetCursor = false; + } +} + +bool QWaylandDecoration::inMouseButtonPressedState() const +{ + return m_mouseButtons & Qt::NoButton; +} + +void QWaylandDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons) +{ + if (isLeftClicked(buttons)) { + m_wayland_window->shellSurface()->resize(inputDevice, resize); + inputDevice->removeMouseButtonFromState(Qt::LeftButton); + } +} + +void QWaylandDecoration::startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons) +{ + if (isLeftClicked(buttons)) { + m_wayland_window->shellSurface()->move(inputDevice); + inputDevice->removeMouseButtonFromState(Qt::LeftButton); + } +} + +void QWaylandDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + if (local.y() <= m_margins.bottom()) { + if (local.x() <= margins().left()) { + //top left bit + startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b); + } else if (local.x() > m_window->width() - margins().right()) { + //top right bit + startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b); + } else { + //top reszie bit + overrideCursor(Qt::SplitVCursor); + startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b); + } + } else { + restoreMouseCursor(); + startMove(inputDevice,b); + } + +} + +void QWaylandDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + if (local.x() <= margins().left()) { + //bottom left bit + startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b); + } else if (local.x() > m_window->width() - margins().right()) { + //bottom right bit + startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b); + } else { + //bottom bit + overrideCursor(Qt::SplitVCursor); + startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b); + } +} + +void QWaylandDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + Q_UNUSED(local); + Q_UNUSED(mods); + overrideCursor(Qt::SplitHCursor); + startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b); +} + +void QWaylandDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + Q_UNUSED(local); + Q_UNUSED(mods); + overrideCursor(Qt::SplitHCursor); + startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b); +} + +bool QWaylandDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState) +{ + if ((!m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton)) + return true; + return false; +} + +bool QWaylandDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState) +{ + if ((m_mouseButtons & Qt::LeftButton) && !(newMouseButtonState & Qt::LeftButton)) + return true; + return false; +} diff --git a/src/plugins/platforms/wayland/qwaylanddecoration.h b/src/plugins/platforms/wayland/qwaylanddecoration.h new file mode 100644 index 000000000..df237f6f0 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddecoration.h @@ -0,0 +1,80 @@ +#ifndef QWAYLANDDECORATION_H +#define QWAYLANDDECORATION_H + +#include <QtCore/QMargins> +#include <QtCore/QPointF> +#include <QtGui/QGuiApplication> +#include <QtGui/QCursor> +#include <QtGui/QImage> +#include <QtGui/QStaticText> + +#include <wayland-client.h> + +#include <QtCore/QDebug> + +class QWindow; +class QPaintDevice; +class QPainter; +class QEvent; +class QWaylandWindow; +class QWaylandShmBackingStore; +class QWaylandInputDevice; + +class QWaylandDecoration +{ +public: + QWaylandDecoration(QWindow *window, QWaylandShmBackingStore *backing_store); + ~QWaylandDecoration(); + void paintDecoration(); + void 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); + void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons); + QMargins margins() const; +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); + void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); + + bool isLeftClicked(Qt::MouseButtons newMouseButtonState); + bool isLeftReleased(Qt::MouseButtons newMouseButtonState); + + QWindow *m_window; + QWaylandWindow *m_wayland_window; + QWaylandShmBackingStore *m_backing_store; + + QMargins m_margins; + bool m_hasSetCursor; + Qt::CursorShape m_cursorShape; + Qt::MouseButtons m_mouseButtons; + + QStaticText m_windowTitle; + + QImage m_borderImage; +}; + +inline QMargins QWaylandDecoration::margins() const +{ + return m_margins; +} + +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; + } +} + +#endif // QWAYLANDDECORATION_H diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 15551e7c6..be8a09678 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -101,7 +101,6 @@ QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *device) { - qDebug() << "setting last keyboard focus input device" << device; mLastKeyboardFocusInputDevice = device; } diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index ac5ac8b17..2be5946b2 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -121,12 +121,24 @@ struct wl_data_device *QWaylandInputDevice::transferDevice() const return mTransferDevice; } +struct wl_input_device *QWaylandInputDevice::handle() const +{ + return mInputDevice; +} + +void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) +{ + mButtons = mButtons & !button; +} + void QWaylandInputDevice::inputHandleMotion(void *data, struct wl_input_device *input_device, uint32_t time, int32_t surface_x, int32_t surface_y) { Q_UNUSED(input_device); + Q_UNUSED(surface_x); + Q_UNUSED(surface_y); QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mPointerFocus; @@ -142,9 +154,13 @@ void QWaylandInputDevice::inputHandleMotion(void *data, inputDevice->mSurfacePos = pos; inputDevice->mGlobalPos = global; inputDevice->mTime = time; - QWindowSystemInterface::handleMouseEvent(window->window(), - time, pos, global, - inputDevice->mButtons); + + window->handleMouse(inputDevice, + time, + inputDevice->mSurfacePos, + inputDevice->mSurfacePos, + inputDevice->mButtons, + Qt::NoModifier); } void QWaylandInputDevice::inputHandleButton(void *data, @@ -156,11 +172,6 @@ void QWaylandInputDevice::inputHandleButton(void *data, QWaylandWindow *window = inputDevice->mPointerFocus; Qt::MouseButton qt_button; - if (window == NULL) { - /* We destroyed the pointer focus surface, but the server - * didn't get the message yet. */ - return; - } // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton. // The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button. @@ -190,11 +201,15 @@ void QWaylandInputDevice::inputHandleButton(void *data, inputDevice->mButtons &= ~qt_button; inputDevice->mTime = time; - QWindowSystemInterface::handleMouseEvent(window->window(), - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons); + + if (window) { + window->handleMouse(inputDevice, + time, + inputDevice->mSurfacePos, + inputDevice->mSurfacePos, + inputDevice->mButtons, + Qt::NoModifier); + } } void QWaylandInputDevice::inputHandleAxis(void *data, @@ -351,7 +366,7 @@ void QWaylandInputDevice::inputHandlePointerEnter(void *data, Q_ASSERT(surface); QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); - QWindowSystemInterface::handleEnterEvent(window->window()); + window->handleMouseEnter(); inputDevice->mPointerFocus = window; inputDevice->mTime = time; @@ -368,8 +383,9 @@ void QWaylandInputDevice::inputHandlePointerLeave(void *data, Q_ASSERT(surface); QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); - QWindowSystemInterface::handleLeaveEvent(window->window()); + window->handleMouseLeave(); inputDevice->mPointerFocus = 0; + inputDevice->mButtons = Qt::NoButton; inputDevice->mTime = time; } @@ -494,7 +510,8 @@ void QWaylandInputDevice::handleTouchPoint(int id, int x, int y, Qt::TouchPointS return; tp.area = QRectF(0, 0, 8, 8); - tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x, y))); + QMargins margins = win->frameMargins(); + tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top()))); } tp.state = state; diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h index 9d512a69a..7c80c1fca 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h @@ -63,11 +63,13 @@ public: void attach(QWaylandBuffer *buffer, int x, int y); void handleWindowDestroyed(QWaylandWindow *window); struct wl_input_device *wl_input_device() const { return mInputDevice; } - QWaylandWindow *pointerFocus() const { return mPointerFocus; } void setTransferDevice(struct wl_data_device *device); struct wl_data_device *transferDevice() const; + struct wl_input_device *handle() const; + + void removeMouseButtonFromState(Qt::MouseButton button); private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; diff --git a/src/plugins/platforms/wayland/qwaylandshell.cpp b/src/plugins/platforms/wayland/qwaylandshell.cpp index 1118f0d3f..86ff5b12b 100644 --- a/src/plugins/platforms/wayland/qwaylandshell.cpp +++ b/src/plugins/platforms/wayland/qwaylandshell.cpp @@ -51,7 +51,7 @@ QWaylandShell::QWaylandShell(QWaylandDisplay *display, uint32_t id, uint32_t ver m_shell = static_cast<struct wl_shell *>(wl_display_bind(m_display->wl_display(), id, &wl_shell_interface)); } -QWaylandShellSurface *QWaylandShell::createShellSurface(QWaylandWindow *window) +QWaylandShellSurface *QWaylandShell::getShellSurface(QWaylandWindow *window) { Q_ASSERT(window->wl_surface()); struct wl_shell_surface *shell_surface = wl_shell_get_shell_surface(m_shell,window->wl_surface()); diff --git a/src/plugins/platforms/wayland/qwaylandshell.h b/src/plugins/platforms/wayland/qwaylandshell.h index e4dbad57b..2f2a92f4c 100644 --- a/src/plugins/platforms/wayland/qwaylandshell.h +++ b/src/plugins/platforms/wayland/qwaylandshell.h @@ -52,7 +52,7 @@ class QWaylandShell public: QWaylandShell(QWaylandDisplay *display, uint32_t id, uint32_t version); - QWaylandShellSurface *createShellSurface(QWaylandWindow *window); + QWaylandShellSurface *getShellSurface(QWaylandWindow *window); private: struct wl_shell *m_shell; diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp index 79788a31b..69848f282 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp @@ -43,6 +43,10 @@ #include "qwaylanddisplay.h" #include "qwaylandwindow.h" +#include "qwaylandinputdevice.h" +#include "qwaylanddecoration.h" + +#include <QtCore/QDebug> QWaylandShellSurface::QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window) : m_shell_surface(shell_surface) @@ -51,6 +55,38 @@ QWaylandShellSurface::QWaylandShellSurface(struct wl_shell_surface *shell_surfac wl_shell_surface_add_listener(m_shell_surface,&m_shell_surface_listener,this); } +void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) +{ + wl_shell_surface_resize(m_shell_surface,inputDevice->wl_input_device(),QWaylandDisplay::currentTimeMillisec(),edges); +} + +void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice) +{ + wl_shell_surface_move(m_shell_surface,inputDevice->wl_input_device(),QWaylandDisplay::currentTimeMillisec()); +} + +void QWaylandShellSurface::setTopLevel() +{ + wl_shell_surface_set_toplevel(m_shell_surface); +} + +void QWaylandShellSurface::updateTransientParent(QWindow *parent) +{ + QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle()); + if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + return; + + QPoint transientPos = m_window->geometry().topLeft(); + if (parent_wayland_window->decoration()) { + transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left()); + transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); + } + wl_shell_surface_set_transient(m_shell_surface, + parent_wayland_window->shellSurface()->m_shell_surface, + transientPos.x(), + transientPos.y(), + 0); +} void QWaylandShellSurface::configure(void *data, wl_shell_surface *wl_shell_surface, @@ -61,7 +97,7 @@ void QWaylandShellSurface::configure(void *data, { Q_UNUSED(wl_shell_surface); QWaylandShellSurface *shell_surface = static_cast<QWaylandShellSurface *>(data); - shell_surface->m_window->configure(time,edges,0,0,width,height); + shell_surface->m_window->configure(time,edges,width,height); } void QWaylandShellSurface::popup_done(void *data, diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.h b/src/plugins/platforms/wayland/qwaylandshellsurface.h index 4c77b70f8..e7e46ab6d 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.h @@ -42,15 +42,25 @@ #ifndef QWAYLANDSHELLSURFACE_H #define QWAYLANDSHELLSURFACE_H -#include <inttypes.h> +#include <QtCore/QSize> + +#include <wayland-client.h> class QWaylandWindow; +class QWaylandInputDevice; +class QWindow; class QWaylandShellSurface { public: QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window); + void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges); + void move(QWaylandInputDevice *inputDevice); + + void setTopLevel(); + void updateTransientParent(QWindow *parent); + struct wl_shell_surface *handle() const { return m_shell_surface; } private: diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index 6aafd1c98..0d4d06f82 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -45,6 +45,9 @@ #include "qwaylanddisplay.h" #include "qwaylandshmwindow.h" #include "qwaylandscreen.h" +#include "qwaylanddecoration.h" + +#include <QtGui/QPainter> #include <wayland-client.h> #include <unistd.h> @@ -55,27 +58,28 @@ QT_BEGIN_NAMESPACE QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, - const QSize &size, QImage::Format format) + const QSize &size, QImage::Format format) + : mMarginsImage(0) { int stride = size.width() * 4; int alloc = stride * size.height(); char filename[] = "/tmp/wayland-shm-XXXXXX"; int fd = mkstemp(filename); if (fd < 0) - qWarning("open %s failed: %s", filename, strerror(errno)); + qWarning("open %s failed: %s", filename, strerror(errno)); if (ftruncate(fd, alloc) < 0) { - qWarning("ftruncate failed: %s", strerror(errno)); - close(fd); - return; + qWarning("ftruncate failed: %s", strerror(errno)); + close(fd); + return; } uchar *data = (uchar *) - mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unlink(filename); if (data == (uchar *) MAP_FAILED) { - qWarning("mmap /dev/zero failed: %s", strerror(errno)); - close(fd); - return; + qWarning("mmap /dev/zero failed: %s", strerror(errno)); + close(fd); + return; } mImage = QImage(data, size.width(), size.height(), stride, format); @@ -92,57 +96,194 @@ QWaylandShmBuffer::~QWaylandShmBuffer(void) wl_shm_pool_destroy(mShmPool); } +QImage *QWaylandShmBuffer::imageInsideMargins(const QMargins &margins) +{ + if (!margins.isNull() && margins != mMargins) { + if (mMarginsImage) { + delete mMarginsImage; + } + uchar *bits = const_cast<uchar *>(mImage.constBits()); + uchar *b_s_data = bits + margins.top() * mImage.bytesPerLine() + margins.left() * 4; + int b_s_width = mImage.size().width() - margins.left() - margins.right(); + int b_s_height = mImage.size().height() - margins.top() - margins.bottom(); + mMarginsImage = new QImage(b_s_data, b_s_width,b_s_height,mImage.bytesPerLine(),mImage.format()); + } + if (margins.isNull()) { + delete mMarginsImage; + mMarginsImage = 0; + } + + mMargins = margins; + if (!mMarginsImage) + return &mImage; + + return mMarginsImage; + +} + QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window) : QPlatformBackingStore(window) - , mBuffer(0) , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) + , mFrontBuffer(0) + , mBackBuffer(0) + , mFrontBufferIsDirty(false) + , mPainting(false) + , mWindowDecoration(0) + , mFrameCallback(0) { } QWaylandShmBackingStore::~QWaylandShmBackingStore() { +// if (mFrontBuffer == waylandWindow()->attached()) +// waylandWindow()->attach(0); + + if (mFrontBuffer != mBackBuffer) + delete mFrontBuffer; + + delete mBackBuffer; } QPaintDevice *QWaylandShmBackingStore::paintDevice() { - return mBuffer->image(); + if (!mWindowDecoration) + return mBackBuffer->image(); + return mBackBuffer->imageInsideMargins(mWindowDecoration->margins()); } void QWaylandShmBackingStore::beginPaint(const QRegion &) { - QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); - Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); - waylandWindow->waitForFrameSync(); + mPainting = true; + ensureSize(); + + if (waylandWindow()->attached() && mBackBuffer == waylandWindow()->attached()) { + QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); + Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); + waylandWindow->waitForFrameSync(); + } + +} + +void QWaylandShmBackingStore::endPaint() +{ + mPainting = false; +} + +void QWaylandShmBackingStore::ensureSize() +{ + bool decoration = false; + switch (window()->windowType()) { + case Qt::Window: + case Qt::Widget: + case Qt::Dialog: + case Qt::Tool: + case Qt::Drawer: + decoration = true; + break; + default: + break; + } + if (window()->windowFlags() & Qt::FramelessWindowHint) { + decoration = false; + } + + if (decoration) { + if (!mWindowDecoration) { + mWindowDecoration = new QWaylandDecoration(window(), this); + } + } else { + delete mWindowDecoration; + mWindowDecoration = 0; + } + resize(mRequestedSize); } void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(window); Q_UNUSED(offset); - QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window->handle()); - Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); + Q_ASSERT(waylandWindow()->windowType() == QWaylandWindow::Shm); + + mFrontBuffer = mBackBuffer; + + if (mFrameCallback) { + mFrontBufferIsDirty = true; + return; + } + + mFrameCallback = wl_surface_frame(waylandWindow()->wl_surface()); + wl_callback_add_listener(mFrameCallback,&frameCallbackListener,this); + QMargins margins = windowDecorationMargins(); + + if (waylandWindow()->attached() != mFrontBuffer) { + delete waylandWindow()->attached(); + waylandWindow()->attach(mFrontBuffer); + } + QVector<QRect> rects = region.rects(); for (int i = 0; i < rects.size(); i++) { - const QRect rect = rects.at(i); - waylandWindow->damage(rect); + QRect rect = rects.at(i); + rect.translate(margins.left(),margins.top()); + waylandWindow()->damage(rect); } + mFrontBufferIsDirty = false; } void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) { - QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); + mRequestedSize = size; +} + +void QWaylandShmBackingStore::resize(const QSize &size) +{ + + QMargins margins = windowDecorationMargins(); + QSize sizeWithMargins = size + QSize(margins.left()+margins.right(),margins.top()+margins.bottom()); QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format(); - if (mBuffer != NULL && mBuffer->size() == size) - return; + if (mBackBuffer != NULL && mBackBuffer->size() == sizeWithMargins) + return; - if (mBuffer != NULL) - delete mBuffer; + if (mBackBuffer != mFrontBuffer) { + delete mBackBuffer; //we delete the attached buffer when we flush + } + + mBackBuffer = new QWaylandShmBuffer(mDisplay, sizeWithMargins, format); - mBuffer = new QWaylandShmBuffer(mDisplay, size, format); + if (mWindowDecoration) + mWindowDecoration->paintDecoration(); +} - waylandWindow->attach(mBuffer); +QImage *QWaylandShmBackingStore::entireSurface() const +{ + return mBackBuffer->image(); } +void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time) +{ + Q_UNUSED(callback); + Q_UNUSED(time); + QWaylandShmBackingStore *self = + static_cast<QWaylandShmBackingStore *>(data); + QWaylandWindow *window = self->waylandWindow(); + wl_callback_destroy(self->mFrameCallback); + self->mFrameCallback = 0; + if (self->mFrontBuffer != self->waylandWindow()->attached()) { + delete self->waylandWindow()->attached(); + self->waylandWindow()->attach(self->mFrontBuffer); + } + + if (self->mFrontBufferIsDirty && !self->mPainting) { + self->mFrontBufferIsDirty = false; + self->mFrameCallback = wl_surface_frame(self->waylandWindow()->wl_surface()); + wl_callback_add_listener(self->mFrameCallback,&self->frameCallbackListener,self); + self->waylandWindow()->damage(QRect(QPoint(0,0),self->mFrontBuffer->size())); + } +} + +const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener = { + QWaylandShmBackingStore::done +}; + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h index e1940776c..d61df2041 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.h +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h @@ -43,6 +43,10 @@ #define QWAYLANDSHMBACKINGSTORE_H #include "qwaylandbuffer.h" + +#include "qwaylanddecoration.h" +#include "qwaylandwindow.h" + #include <QtGui/QPlatformBackingStore> #include <QtGui/QImage> #include <QtGui/QPlatformWindow> @@ -54,13 +58,17 @@ class QWaylandDisplay; class QWaylandShmBuffer : public QWaylandBuffer { public: QWaylandShmBuffer(QWaylandDisplay *display, - const QSize &size, QImage::Format format); + const QSize &size, QImage::Format format); ~QWaylandShmBuffer(); QSize size() const { return mImage.size(); } QImage *image() { return &mImage; } + + QImage *imageInsideMargins(const QMargins &margins); private: QImage mImage; struct wl_shm_pool *mShmPool; + QMargins mMargins; + QImage *mMarginsImage; }; class QWaylandShmBackingStore : public QPlatformBackingStore @@ -72,13 +80,47 @@ public: QPaintDevice *paintDevice(); void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); + void resize(const QSize &size); void beginPaint(const QRegion &); + void endPaint(); + + QMargins windowDecorationMargins() const; + QImage *entireSurface() const; + void ensureSize(); + + QWaylandWindow *waylandWindow() const; + void iterateBuffer(); private: - QWaylandShmBuffer *mBuffer; QWaylandDisplay *mDisplay; + QWaylandShmBuffer *mFrontBuffer; + QWaylandShmBuffer *mBackBuffer; + bool mFrontBufferIsDirty; + bool mPainting; + + QWaylandDecoration *mWindowDecoration; + QSize mRequestedSize; + Qt::WindowFlags mCurrentWindowFlags; + + static const struct wl_callback_listener frameCallbackListener; + static void done(void *data, + struct wl_callback *callback, + uint32_t time); + struct wl_callback *mFrameCallback; }; +inline QMargins QWaylandShmBackingStore::windowDecorationMargins() const +{ + if (mWindowDecoration) + return mWindowDecoration->margins(); + return QMargins(); +} + +inline QWaylandWindow *QWaylandShmBackingStore::waylandWindow() const +{ + return static_cast<QWaylandWindow *>(window()->handle()); +} + QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/wayland/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland/qwaylandsubsurface.cpp index 642d3b450..404d7e029 100644 --- a/src/plugins/platforms/wayland/qwaylandsubsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandsubsurface.cpp @@ -45,6 +45,8 @@ #include "wayland-sub-surface-extension-client-protocol.h" +#include <QtCore/QDebug> + QWaylandSubSurfaceExtension::QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id) { m_sub_surface_extension = static_cast<struct wl_sub_surface_extension *>( @@ -72,8 +74,33 @@ void QWaylandSubSurface::setParent(const QWaylandWindow *parent) { QWaylandSubSurface *parentSurface = parent? parent->subSurfaceWindow():0; if (parentSurface) { - int x = m_window->geometry().x(); - int y = m_window->geometry().y(); + int x = m_window->geometry().x() + parent->frameMargins().left(); + int y = m_window->geometry().y() + parent->frameMargins().top(); wl_sub_surface_attach_sub_surface(parentSurface->m_sub_surface,m_sub_surface,x,y); } } + +static void setPositionToParent(QWaylandWindow *parentWaylandWindow) +{ + QObjectList children = parentWaylandWindow->window()->children(); + for (int i = 0; i < children.size(); i++) { + QWindow *childWindow = qobject_cast<QWindow *>(children.at(i)); + if (!childWindow) + continue; + + if (childWindow->handle()) { + QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(childWindow->handle()); + waylandWindow->subSurfaceWindow()->setParent(parentWaylandWindow); + setPositionToParent(waylandWindow); + } + } +} + +void QWaylandSubSurface::adjustPositionOfChildren() +{ + QWindow *window = m_window->window(); + if (window->parent()) { + qDebug() << "QWaylandSubSurface::adjustPositionOfChildren not called for toplevel window"; + } + setPositionToParent(m_window); +} diff --git a/src/plugins/platforms/wayland/qwaylandsubsurface.h b/src/plugins/platforms/wayland/qwaylandsubsurface.h index 2b8b039e4..4d3ff19df 100644 --- a/src/plugins/platforms/wayland/qwaylandsubsurface.h +++ b/src/plugins/platforms/wayland/qwaylandsubsurface.h @@ -66,6 +66,8 @@ public: void setParent(const QWaylandWindow *parent); + void adjustPositionOfChildren(); + private: QWaylandWindow *m_window; struct wl_sub_surface *m_sub_surface; diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 0273cd294..9f0d31c6f 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -47,6 +47,9 @@ #include "qwaylandscreen.h" #include "qwaylandshell.h" #include "qwaylandshellsurface.h" +#include "qwaylandextendedsurface.h" +#include "qwaylandsubsurface.h" +#include "qwaylanddecoration.h" #include <QtGui/QWindow> @@ -54,19 +57,21 @@ #include "windowmanager_integration/qwaylandwindowmanagerintegration.h" #endif -#include "qwaylandextendedsurface.h" -#include "qwaylandsubsurface.h" - #include <QCoreApplication> #include <QtGui/QWindowSystemInterface> +#include <QtCore/QDebug> + QWaylandWindow::QWaylandWindow(QWindow *window) : QPlatformWindow(window) , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) , mSurface(mDisplay->createSurface(this)) - , mShellSurface(mDisplay->shell()->createShellSurface(this)) + , mShellSurface(0) , mExtendedWindow(0) , mSubSurfaceWindow(0) + , mWindowDecoration(0) + , mMouseEventsInContentArea(false) + , mMousePressedInContentArea(Qt::NoButton) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) @@ -75,6 +80,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window) static WId id = 1; mWindowId = id++; + if (mDisplay->shell()) + mShellSurface = mDisplay->shell()->getShellSurface(this); if (mDisplay->windowExtension()) mExtendedWindow = mDisplay->windowExtension()->getExtendedWindow(this); if (mDisplay->subSurfaceExtension()) @@ -87,8 +94,12 @@ QWaylandWindow::QWaylandWindow(QWindow *window) if (parent() && mSubSurfaceWindow) { mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(parent())); - } else { - wl_shell_surface_set_toplevel(mShellSurface->handle()); + }else if (window->transientParent()) { + if (window->transientParent()) { + mShellSurface->updateTransientParent(window->transientParent()); + } else { + mShellSurface->setTopLevel(); + } } } @@ -118,6 +129,22 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent) } } +void QWaylandWindow::setWindowTitle(const QString &title) +{ + Q_UNUSED(title); + if (mWindowDecoration && window()->visible()) { + mWindowDecoration->paintDecoration(); + } +} + +void QWaylandWindow::setGeometry(const QRect &rect) +{ + QPlatformWindow::setGeometry(rect); + + if (shellSurface() && window()->transientParent()) + shellSurface()->updateTransientParent(window()->transientParent()); +} + void QWaylandWindow::setVisible(bool visible) { @@ -134,6 +161,7 @@ void QWaylandWindow::setVisible(bool visible) } else { QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); wl_surface_attach(mSurface, 0,0,0); + damage(QRect(QPoint(0,0),geometry().size())); } } @@ -149,15 +177,19 @@ bool QWaylandWindow::isExposed() const void QWaylandWindow::configure(uint32_t time, uint32_t edges, - int32_t x, int32_t y, int32_t width, int32_t height) { Q_UNUSED(time); Q_UNUSED(edges); - QRect geometry = QRect(x, y, width, height); - setGeometry(geometry); + int widthWithoutMargins = qMax(width-(frameMargins().left() +frameMargins().right()),1); + int heightWithoutMargins = qMax(height-(frameMargins().top()+frameMargins().bottom()),1); + widthWithoutMargins = qMax(widthWithoutMargins, window()->minimumSize().width()); + heightWithoutMargins = qMax(heightWithoutMargins, window()->minimumSize().height()); + QRect geometry = QRect(0,0, + widthWithoutMargins, heightWithoutMargins); + setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(window(), geometry); } @@ -167,11 +199,14 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer) if (window()->isVisible()) { wl_surface_attach(mSurface, mBuffer->buffer(),0,0); - if (buffer) - QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); } } +QWaylandBuffer *QWaylandWindow::attached() const +{ + return mBuffer; +} + void QWaylandWindow::damage(const QRect &rect) { //We have to do sync stuff before calling damage, or we might @@ -204,11 +239,20 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *wl_callback, void QWaylandWindow::waitForFrameSync() { + if (!mWaitingForFrameSync) + return; mDisplay->flushRequests(); while (mWaitingForFrameSync) mDisplay->blockingReadEvents(); } +QMargins QWaylandWindow::frameMargins() const +{ + if (mWindowDecoration) + return mWindowDecoration->margins(); + return QPlatformWindow::frameMargins(); +} + QWaylandShellSurface *QWaylandWindow::shellSurface() const { return mShellSurface; @@ -260,3 +304,77 @@ Qt::WindowFlags QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) { return mExtendedWindow->setWindowFlags(flags); } + +QWaylandDecoration *QWaylandWindow::decoration() const +{ + return mWindowDecoration; +} + +void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) +{ + mWindowDecoration = decoration; + if (subSurfaceWindow()) { + subSurfaceWindow()->adjustPositionOfChildren(); + } +} + +void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + if (mWindowDecoration) { + handleMouseEventWithDecoration(inputDevice, timestamp,local,global,b,mods); + return; + } + + QWindowSystemInterface::handleMouseEvent(window(),timestamp,local,global,b,mods); +} + +void QWaylandWindow::handleMouseEnter() +{ + if (!mWindowDecoration) { + QWindowSystemInterface::handleEnterEvent(window()); + } +} + +void QWaylandWindow::handleMouseLeave() +{ + if (mWindowDecoration) { + if (mMouseEventsInContentArea) { + QWindowSystemInterface::handleLeaveEvent(window()); + } + mWindowDecoration->restoreMouseCursor(); + } else { + QWindowSystemInterface::handleLeaveEvent(window()); + } +} + +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); + return; + } + + QPointF localTranslated = local; + QMargins marg = frameMargins(); + QRect windowRect(0 + marg.left(), + 0 + marg.top(), + geometry().size().width() - marg.right(), + geometry().size().height() - marg.bottom()); + if (windowRect.contains(local.toPoint()) || mMousePressedInContentArea != Qt::NoButton) { + localTranslated.setX(localTranslated.x() - marg.left()); + localTranslated.setY(localTranslated.y() - marg.top()); + if (!mMouseEventsInContentArea) { + mWindowDecoration->restoreMouseCursor(); + QWindowSystemInterface::handleEnterEvent(window()); + } + QWindowSystemInterface::handleMouseEvent(window(),timestamp,localTranslated,global,b,mods); + mMouseEventsInContentArea = true; + mMousePressedInContentArea = b; + } else { + if (mMouseEventsInContentArea) { + QWindowSystemInterface::handleLeaveEvent(window()); + mMouseEventsInContentArea = false; + } + mWindowDecoration->handleMouse(inputDevice,local,global,b,mods); + } +} diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index 8fcfd8f2e..a07368b70 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -52,6 +52,7 @@ class QWaylandBuffer; class QWaylandShellSurface; class QWaylandExtendedSurface; class QWaylandSubSurface; +class QWaylandDecoration; struct wl_egl_window; @@ -71,14 +72,22 @@ public: void setVisible(bool visible); void setParent(const QPlatformWindow *parent); + void setWindowTitle(const QString &title); + + void setGeometry(const QRect &rect); + void configure(uint32_t time, uint32_t edges, - int32_t x, int32_t y, int32_t width, int32_t height); + int32_t width, int32_t height); void attach(QWaylandBuffer *buffer); + QWaylandBuffer *attached() const; + void damage(const QRect &rect); void waitForFrameSync(); + QMargins frameMargins() const; + struct wl_surface *wl_surface() const { return mSurface; } QWaylandShellSurface *shellSurface() const; @@ -93,6 +102,18 @@ public: bool isExposed() const; + QWaylandDecoration *decoration() const; + void setDecoration(QWaylandDecoration *decoration); + + + void handleMouse(QWaylandInputDevice *inputDevice, + ulong timestamp, + const QPointF & local, + const QPointF & global, + Qt::MouseButtons b, + Qt::KeyboardModifiers mods); + void handleMouseEnter(); + void handleMouseLeave(); protected: QWaylandDisplay *mDisplay; struct wl_surface *mSurface; @@ -100,6 +121,10 @@ protected: QWaylandExtendedSurface *mExtendedWindow; QWaylandSubSurface *mSubSurfaceWindow; + QWaylandDecoration *mWindowDecoration; + bool mMouseEventsInContentArea; + Qt::MouseButtons mMousePressedInContentArea; + QWaylandBuffer *mBuffer; WId mWindowId; bool mWaitingForFrameSync; @@ -109,6 +134,13 @@ protected: bool mSentInitialResize; private: + void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, + ulong timestamp, + const QPointF & local, + const QPointF & global, + Qt::MouseButtons b, + Qt::KeyboardModifiers mods); + static const wl_callback_listener callbackListener; static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time); diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index 7bc515b5f..92a04c07f 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -30,7 +30,8 @@ SOURCES = main.cpp \ qwaylandsubsurface.cpp \ qwaylandtouch.cpp \ qwaylandqtkey.cpp \ - $$PWD/../../../shared/qwaylandmimehelper.cpp + $$PWD/../../../shared/qwaylandmimehelper.cpp \ + qwaylanddecoration.cpp HEADERS = qwaylandintegration.h \ qwaylandnativeinterface.h \ @@ -53,7 +54,8 @@ HEADERS = qwaylandintegration.h \ qwaylandsubsurface.h \ qwaylandtouch.h \ qwaylandqtkey.h \ - $$PWD/../../../shared/qwaylandmimehelper.h + $$PWD/../../../shared/qwaylandmimehelper.h \ + qwaylanddecoration.h DEFINES += Q_PLATFORM_WAYLAND |