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/platforms/wayland/qwaylandwindow.cpp | |
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/platforms/wayland/qwaylandwindow.cpp')
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandwindow.cpp | 140 |
1 files changed, 129 insertions, 11 deletions
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); + } +} |