summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wayland/qwaylandwindow.cpp
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2012-02-13 10:23:41 +0100
committerJørgen Lind <jorgen.lind@nokia.com>2012-04-11 13:41:59 +0200
commitf984c7985ca26096dd293f18ba4d0b8271fdb4f5 (patch)
tree76293fd58a3124a2216585951ccb58fa47f14f9a /src/plugins/platforms/wayland/qwaylandwindow.cpp
parent921fefbf2a5e4078f4dff19c3c664cbbd9b751d1 (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.cpp140
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);
+ }
+}