summaryrefslogtreecommitdiffstats
path: root/src/compositor/wayland_wrapper
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/compositor/wayland_wrapper
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/compositor/wayland_wrapper')
-rw-r--r--src/compositor/wayland_wrapper/wlshellsurface.cpp256
-rw-r--r--src/compositor/wayland_wrapper/wlshellsurface.h72
-rw-r--r--src/compositor/wayland_wrapper/wlsubsurface.cpp7
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.cpp6
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.h3
5 files changed, 331 insertions, 13 deletions
diff --git a/src/compositor/wayland_wrapper/wlshellsurface.cpp b/src/compositor/wayland_wrapper/wlshellsurface.cpp
index ea4b54b62..9e37a330f 100644
--- a/src/compositor/wayland_wrapper/wlshellsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlshellsurface.cpp
@@ -43,6 +43,7 @@
#include "wlcompositor.h"
#include "wlsurface.h"
#include "wlinputdevice.h"
+#include "wlsubsurface.h"
#include <QtCore/qglobal.h>
#include <QtCore/QDebug>
@@ -75,22 +76,92 @@ const struct wl_shell_interface Shell::shell_interface = {
};
ShellSurface::ShellSurface(wl_client *client, uint32_t id, Surface *surface)
+ : m_surface(surface)
+ , m_resizeGrabber(0)
+ , m_moveGrabber(0)
+ , m_transientParent(0)
+ , m_xOffset(0)
+ , m_yOffset(0)
{
m_shellSurface = wl_client_add_object(client,&wl_shell_surface_interface,&shell_surface_interface,id,this);
surface->setShellSurface(this);
+}
+
+void ShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height)
+{
+ wl_resource_post_event(m_shellSurface,WL_SHELL_SURFACE_CONFIGURE, Compositor::currentTimeMsecs(),edges,width,height);
+}
+
+Surface *ShellSurface::surface() const
+{
+ return m_surface;
+}
+
+void ShellSurface::adjustPosInResize()
+{
+ if (m_transientParent)
+ return;
+ if (!m_resizeGrabber || !(m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP_LEFT))
+ return;
+
+ int bottomLeftX = m_resizeGrabber->base()->x + m_resizeGrabber->width;
+ int bottomLeftY = m_resizeGrabber->base()->y + m_resizeGrabber->height;
+ qreal x = surface()->pos().x();
+ qreal y = surface()->pos().y();
+ if (m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP)
+ y = bottomLeftY - surface()->size().height();
+ if (m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT)
+ x = bottomLeftX - surface()->size().width();
+ QPointF newPos(x,y);
+ surface()->setPos(newPos);
+}
+
+void ShellSurface::adjustPosToTransientParent()
+{
+ if (!m_transientParent ||
+ (m_surface->subSurface() && m_surface->subSurface()->parent()))
+ return;
+
+ m_surface->setPos(m_transientParent->surface()->pos() + QPoint(m_xOffset,m_yOffset));
+}
+void ShellSurface::resetResizeGrabber()
+{
+ m_resizeGrabber = 0;
+}
+
+void ShellSurface::resetMoveGrabber()
+{
+ m_moveGrabber = 0;
+}
+
+ShellSurface *ShellSurface::transientParent() const
+{
+ return m_transientParent;
}
void ShellSurface::move(struct wl_client *client,
struct wl_resource *shell_surface_resource,
- struct wl_resource *input_device,
+ struct wl_resource *input_device_super,
uint32_t time)
{
Q_UNUSED(client);
- Q_UNUSED(shell_surface_resource);
- Q_UNUSED(input_device);
Q_UNUSED(time);
+ ShellSurface *self = static_cast<ShellSurface *>(shell_surface_resource->data);
+ InputDevice *input_device = static_cast<InputDevice *>(input_device_super->data);
+ if (self->m_resizeGrabber || self->m_moveGrabber) {
+ qDebug() << "invalid state";
+ return;
+ }
+
+ self->m_moveGrabber = new ShellSurfaceMoveGrabber(self);
+ self->m_moveGrabber->base()->x = input_device->base()->x;
+ self->m_moveGrabber->base()->y = input_device->base()->y;
+ self->m_moveGrabber->offset_x = input_device->base()->x - self->surface()->pos().x();
+ self->m_moveGrabber->offset_y = input_device->base()->y - self->surface()->pos().y();
+
+ wl_input_device_start_pointer_grab(input_device->base(),self->m_moveGrabber->base(),Compositor::currentTimeMsecs());
}
void ShellSurface::resize(struct wl_client *client,
@@ -103,18 +174,31 @@ void ShellSurface::resize(struct wl_client *client,
Q_UNUSED(client);
Q_UNUSED(time);
Q_UNUSED(edges);
- ShellSurface *shell_surface = static_cast<ShellSurface *>(shell_surface_resource->data);
- Q_UNUSED(shell_surface);
+ ShellSurface *self = static_cast<ShellSurface *>(shell_surface_resource->data);
InputDevice *input_device = static_cast<InputDevice *>(input_device_super->data);
- Q_UNUSED(input_device);
+ if (self->m_moveGrabber || self->m_resizeGrabber) {
+ qDebug() << "invalid state2";
+ return;
+ }
+ self->m_resizeGrabber = new ShellSurfaceResizeGrabber(self);
+ self->m_resizeGrabber->base()->x = input_device->base()->x;
+ self->m_resizeGrabber->base()->y = input_device->base()->y;
+ self->m_resizeGrabber->resize_edges = wl_shell_surface_resize(edges);
+ self->m_resizeGrabber->width = self->surface()->size().width();
+ self->m_resizeGrabber->height = self->surface()->size().height();
+ wl_input_device_start_pointer_grab(input_device->base(),self->m_resizeGrabber->base(),Compositor::currentTimeMsecs());
}
void ShellSurface::set_toplevel(struct wl_client *client,
struct wl_resource *shell_surface_resource)
{
Q_UNUSED(client);
- Q_UNUSED(shell_surface_resource);
+ ShellSurface *self = static_cast<ShellSurface *>(shell_surface_resource->data);
+ self->m_transientParent = 0;
+ self->m_xOffset = 0;
+ self->m_yOffset = 0;
+
}
void ShellSurface::set_transient(struct wl_client *client,
@@ -129,8 +213,10 @@ void ShellSurface::set_transient(struct wl_client *client,
Q_UNUSED(flags);
ShellSurface *shell_surface = static_cast<ShellSurface *>(shell_surface_resource->data);
ShellSurface *parent_shell_surface = static_cast<ShellSurface *>(parent_shell_surface_resource->data);
- QPointF point = parent_shell_surface->m_surface->pos() + QPoint(x,y);
- shell_surface->m_surface->setPos(point);
+ shell_surface->m_transientParent = parent_shell_surface;
+ shell_surface->m_xOffset = x;
+ shell_surface->m_yOffset = y;
+
}
void ShellSurface::set_fullscreen(struct wl_client *client,
@@ -177,4 +263,156 @@ const struct wl_shell_surface_interface ShellSurface::shell_surface_interface =
ShellSurface::set_maximized
};
+Qt::MouseButton toQtButton(uint32_t button)
+{
+#ifndef BTN_LEFT
+ static const uint32_t BTN_LEFT = 0x110;
+ static const uint32_t BTN_RIGHT = 0x111;
+ static const uint32_t BTN_MIDDLE = 0x112;
+#endif
+ switch (button) {
+ case BTN_LEFT:
+ return Qt::LeftButton;
+ case BTN_RIGHT:
+ return Qt::RightButton;
+ case BTN_MIDDLE:
+ return Qt::MiddleButton;
+ default:
+ return Qt::NoButton;
+ }
+}
+
+ShellSurfaceGrabber::ShellSurfaceGrabber(ShellSurface *shellSurface, const struct wl_pointer_grab_interface *interface)
+ : shell_surface(shellSurface)
+{
+ base()->interface = interface;
+ base()->focus = shell_surface->surface()->base();
+}
+
+ShellSurfaceGrabber::~ShellSurfaceGrabber()
+{
+}
+
+
+void ShellSurfaceGrabber::destroy(wl_listener *listener, wl_resource *resource, uint32_t time)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(time);
+ //ShellSurfaceGrabber *shell_surface_grabber = container_of(listener, ShellSurfaceGrabber,surface_destroy_listener);
+ Q_ASSERT(false); //hasn't been enabled yet
+ //wl_input_device_end_grab(shell_surface_grabber->base()->input_device,Compositor::currentTimeMsecs());
+}
+
+
+ShellSurfaceResizeGrabber::ShellSurfaceResizeGrabber(ShellSurface *shellSurface)
+ : ShellSurfaceGrabber(shellSurface,&resize_grabber_interface)
+{
+}
+
+void ShellSurfaceResizeGrabber::focus(wl_pointer_grab *grab, uint32_t time, wl_surface *surface, int32_t x, int32_t y)
+{
+}
+
+void ShellSurfaceResizeGrabber::motion(wl_pointer_grab *grab, uint32_t time, int32_t x, int32_t y)
+{
+ //Should be more structured
+ ShellSurfaceResizeGrabber *resize_grabber = reinterpret_cast<ShellSurfaceResizeGrabber *>(grab);
+ ShellSurface *shell_surface = resize_grabber->shell_surface;
+ InputDevice *input_device = reinterpret_cast<InputDevice *>(grab->input_device);
+ int width_delta = grab->x - input_device->base()->x;
+ int height_delta = grab->y - input_device->base()->y;
+ int new_width = resize_grabber->width;
+ int new_height = resize_grabber->height;
+ if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP_LEFT) {
+ if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP) {
+ if (new_height + height_delta > 0) {
+ new_height += height_delta;
+ } else {
+ new_height = 1;
+ }
+ }
+ if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
+ if (new_width + width_delta > 0) {
+ new_width += width_delta;
+ } else {
+ new_width = 1;
+ }
+ }
+ }
+
+ if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
+ if (new_height - height_delta > 0) {
+ new_height -= height_delta;
+ } else {
+ new_height = 1;
+ }
+ }
+ if (resize_grabber->resize_edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
+ if (new_width - width_delta > 0) {
+ new_width -= width_delta;
+ } else {
+ new_width =1;
+ }
+ }
+
+ shell_surface->sendConfigure(resize_grabber->resize_edges,new_width,new_height);
+}
+
+void ShellSurfaceResizeGrabber::button(wl_pointer_grab *grab, uint32_t time, uint32_t button, int32_t state)
+{
+ Q_UNUSED(time)
+ ShellSurfaceResizeGrabber *self = reinterpret_cast<ShellSurfaceResizeGrabber *>(grab);
+ ShellSurface *shell_surface = self->shell_surface;
+ if (toQtButton(button) == Qt::LeftButton && !state) {
+ wl_input_device_end_pointer_grab(grab->input_device,Compositor::currentTimeMsecs());
+ shell_surface->resetResizeGrabber();
+ delete self;
+ }
+}
+
+const struct wl_pointer_grab_interface ShellSurfaceResizeGrabber::resize_grabber_interface = {
+ ShellSurfaceResizeGrabber::focus,
+ ShellSurfaceResizeGrabber::motion,
+ ShellSurfaceResizeGrabber::button
+};
+
+ShellSurfaceMoveGrabber::ShellSurfaceMoveGrabber(ShellSurface *shellSurface)
+ : ShellSurfaceGrabber(shellSurface,&move_grabber_interface)
+{
+}
+
+void ShellSurfaceMoveGrabber::focus(wl_pointer_grab *grab, uint32_t time, wl_surface *surface, int32_t x, int32_t y)
+{
+}
+
+void ShellSurfaceMoveGrabber::motion(wl_pointer_grab *grab, uint32_t time, int32_t x, int32_t y)
+{
+ ShellSurfaceMoveGrabber *shell_surface_grabber = reinterpret_cast<ShellSurfaceMoveGrabber *>(grab);
+ ShellSurface *shell_surface = shell_surface_grabber->shell_surface;
+ InputDevice *input_device = reinterpret_cast<InputDevice *>(grab->input_device);
+ QPointF pos(input_device->base()->x - shell_surface_grabber->offset_x,
+ input_device->base()->y - shell_surface_grabber->offset_y);
+ shell_surface->surface()->setPos(pos);
+ shell_surface->surface()->damage(QRect(QPoint(0,0),shell_surface->surface()->size()));
+}
+
+void ShellSurfaceMoveGrabber::button(wl_pointer_grab *grab, uint32_t time, uint32_t button, int32_t state)
+{
+ Q_UNUSED(time)
+ ShellSurfaceResizeGrabber *self = reinterpret_cast<ShellSurfaceResizeGrabber *>(grab);
+ ShellSurface *shell_surface = self->shell_surface;
+ if (toQtButton(button) == Qt::LeftButton && !state) {
+ wl_input_device_set_pointer_focus(grab->input_device,0,Compositor::currentTimeMsecs(),0,0);
+ wl_input_device_end_pointer_grab(grab->input_device,Compositor::currentTimeMsecs());
+ shell_surface->resetMoveGrabber();
+ delete self;
+ }
+}
+
+const struct wl_pointer_grab_interface ShellSurfaceMoveGrabber::move_grabber_interface = {
+ ShellSurfaceMoveGrabber::focus,
+ ShellSurfaceMoveGrabber::motion,
+ ShellSurfaceMoveGrabber::button
+};
+
}
diff --git a/src/compositor/wayland_wrapper/wlshellsurface.h b/src/compositor/wayland_wrapper/wlshellsurface.h
index a4eacd7b1..dc6491471 100644
--- a/src/compositor/wayland_wrapper/wlshellsurface.h
+++ b/src/compositor/wayland_wrapper/wlshellsurface.h
@@ -41,12 +41,17 @@
#ifndef WLSHELLSURFACE_H
#define WLSHELLSURFACE_H
+#include "waylandobject.h"
+
#include <wayland-server.h>
namespace Wayland {
class Compositor;
class Surface;
+class ShellSurface;
+class ShellSurfaceResizeGrabber;
+class ShellSurfaceMoveGrabber;
class Shell
{
@@ -68,11 +73,28 @@ class ShellSurface
{
public:
ShellSurface(struct wl_client *client, uint32_t id, Surface *surface);
+ void sendConfigure(uint32_t edges, int32_t width, int32_t height);
+
+ Surface *surface() const;
+ void adjustPosInResize();
+ void adjustPosToTransientParent();
+ void resetResizeGrabber();
+ void resetMoveGrabber();
+
+ ShellSurface *transientParent() const;
private:
struct wl_resource *m_shellSurface;
Surface *m_surface;
+ ShellSurfaceResizeGrabber *m_resizeGrabber;
+ ShellSurfaceMoveGrabber *m_moveGrabber;
+
+ ShellSurface *m_transientParent;
+
+ int32_t m_xOffset;
+ int32_t m_yOffset;
+
static void move(struct wl_client *client,
struct wl_resource *shell_surface_resource,
struct wl_resource *input_device_super,
@@ -108,9 +130,59 @@ private:
struct wl_resource *output);
static const struct wl_shell_surface_interface shell_surface_interface;
+};
+
+class ShellSurfaceGrabber : public Object<wl_pointer_grab>
+{
+public:
+ ShellSurfaceGrabber(ShellSurface *shellSurface, const struct wl_pointer_grab_interface *interface);
+ ~ShellSurfaceGrabber();
+
+ struct wl_listener surface_destroy_listener;
+ static void destroy(struct wl_listener *listener,
+ struct wl_resource *resource, uint32_t time);
+
+ ShellSurface *shell_surface;
+};
+class ShellSurfaceResizeGrabber : public ShellSurfaceGrabber
+{
+public:
+ ShellSurfaceResizeGrabber(ShellSurface *shellSurface);
+
+
+ enum wl_shell_surface_resize resize_edges;
+ int32_t width;
+ int32_t height;
+
+ static void focus(struct wl_pointer_grab *grab, uint32_t time,
+ struct wl_surface *surface, int32_t x, int32_t y);
+ static void motion(struct wl_pointer_grab *grab,
+ uint32_t time, int32_t x, int32_t y);
+ static void button(struct wl_pointer_grab *grab,
+ uint32_t time, uint32_t mouse_grabber_button, int32_t state);
+ static const struct wl_pointer_grab_interface resize_grabber_interface;
};
+class ShellSurfaceMoveGrabber : public ShellSurfaceGrabber
+{
+public:
+ ShellSurfaceMoveGrabber(ShellSurface *shellSurface);
+
+ int32_t offset_x;
+ int32_t offset_y;
+
+ static void focus(struct wl_pointer_grab *grab, uint32_t time,
+ struct wl_surface *surface, int32_t x, int32_t y);
+ static void motion(struct wl_pointer_grab *grab,
+ uint32_t time, int32_t x, int32_t y);
+ static void button(struct wl_pointer_grab *grab,
+ uint32_t time, uint32_t mouse_grabber_button, int32_t state);
+ static const struct wl_pointer_grab_interface move_grabber_interface;
+};
+
+
+
}
#endif // WLSHELLSURFACE_H
diff --git a/src/compositor/wayland_wrapper/wlsubsurface.cpp b/src/compositor/wayland_wrapper/wlsubsurface.cpp
index 564045896..379c23c9d 100644
--- a/src/compositor/wayland_wrapper/wlsubsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlsubsurface.cpp
@@ -91,9 +91,10 @@ SubSurface::~SubSurface()
void SubSurface::setSubSurface(SubSurface *subSurface, int x, int y)
{
- Q_ASSERT(!m_sub_surfaces.contains(subSurface->m_surface->waylandSurface()));
- m_sub_surfaces.append(subSurface->m_surface->waylandSurface());
- subSurface->setParent(this);
+ if (!m_sub_surfaces.contains(subSurface->m_surface->waylandSurface())) {
+ m_sub_surfaces.append(subSurface->m_surface->waylandSurface());
+ subSurface->setParent(this);
+ }
subSurface->m_surface->setPos(QPointF(x,y));
}
diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp
index e280ba05a..7afed8daf 100644
--- a/src/compositor/wayland_wrapper/wlsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlsurface.cpp
@@ -146,6 +146,9 @@ bool Surface::visible() const
QPointF Surface::pos() const
{
+ if (m_shellSurface) {
+ m_shellSurface->adjustPosToTransientParent();
+ }
return m_position;
}
@@ -168,6 +171,9 @@ void Surface::setSize(const QSize &size)
m_opaqueRegion = QRegion();
m_inputRegion = QRegion(QRect(QPoint(), size));
m_size = size;
+ if (m_shellSurface) {
+ m_shellSurface->adjustPosInResize();
+ }
m_waylandSurface->sizeChanged();
}
}
diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h
index 294a467d2..cd069598e 100644
--- a/src/compositor/wayland_wrapper/wlsurface.h
+++ b/src/compositor/wayland_wrapper/wlsurface.h
@@ -118,6 +118,8 @@ public:
Compositor *compositor() const;
+ void damage(const QRect &rect);
+
static const struct wl_surface_interface surface_interface;
private:
@@ -157,7 +159,6 @@ private:
bool postBuffer();
void attach(struct wl_buffer *buffer);
- void damage(const QRect &rect);
static void surface_destroy(struct wl_client *client, struct wl_resource *_surface);
static void surface_attach(struct wl_client *client, struct wl_resource *surface,