summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorGiulio Camuffo <giuliocamuffo@gmail.com>2012-11-05 00:12:15 +0100
committerAndy Nichols <andy.nichols@digia.com>2013-01-10 16:47:53 +0100
commitf7b58cccba239b16d18379afbd4117e4432790c4 (patch)
tree5a8f713c1cc282030d43252abeace6ce83efb4b4 /src/plugins
parent1ddfb323388ff079d1e492ca8bb6ea0e08344bd5 (diff)
Implemented moving and resizing using the decorations.
Change-Id: I4153b72876b272c508264c82ac10def68ee4349d Reviewed-by: Andy Nichols <andy.nichols@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp15
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h5
-rw-r--r--src/plugins/platforms/wayland/qwaylanddecoration.cpp8
-rw-r--r--src/plugins/platforms/wayland/qwaylanddecoration.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp11
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h4
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp6
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h10
-rw-r--r--src/plugins/platforms/wayland/qwaylandshellsurface.cpp5
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp26
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp36
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h12
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,&current_width,&current_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 &region, 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