summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@digia.com>2013-01-15 18:42:42 +0100
committerAndy Nichols <andy.nichols@digia.com>2013-01-18 14:09:35 +0100
commit3f8c8e0f5c9828634621238c145c7e62298a66ba (patch)
tree22a153819ccee353b78191356f4770acf72effb2 /src
parent7bd2d367a3eafc403a6c2d3264c5812119768f60 (diff)
Fix the pointer cursor handling (QtCompositor side)
We now use the wayland-cursor library for handling pointer cursors. This required some API changes in QtCompositor, as cursors are now represented by wl_surfaces instead of just wl_buffer data. This means that when a new cursor is set by a client, you will receive a surface which you can generate cursors from. This Surface will be painted to when the cursor is changed. This also means that not all WaylandSurfaces are window surfaces, so it's important that you check that a WaylandSurface has a shell surface before treating it like a window surface. An API has been added for checking if there is a shellSurface available in a WaylandSurface. The qwindow compositor example demonstrates the correct usage of these new API's. Change-Id: Ife6b417f1048fd926a3499a139de07bceaebc727 Reviewed-by: Jørgen Lind <jorgen.lind@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/compositor/compositor_api/waylandcompositor.cpp6
-rw-r--r--src/compositor/compositor_api/waylandcompositor.h2
-rw-r--r--src/compositor/compositor_api/waylandsurface.cpp9
-rw-r--r--src/compositor/compositor_api/waylandsurface.h2
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.cpp6
-rw-r--r--src/compositor/wayland_wrapper/wlinputdevice.cpp55
-rw-r--r--src/compositor/wayland_wrapper/wlinputdevice.h10
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.cpp3
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.h4
9 files changed, 49 insertions, 48 deletions
diff --git a/src/compositor/compositor_api/waylandcompositor.cpp b/src/compositor/compositor_api/waylandcompositor.cpp
index 97cde3023..38c404745 100644
--- a/src/compositor/compositor_api/waylandcompositor.cpp
+++ b/src/compositor/compositor_api/waylandcompositor.cpp
@@ -243,12 +243,12 @@ void WaylandCompositor::sendDragEndEvent()
m_compositor->sendDragEndEvent();
}
-void WaylandCompositor::changeCursor(const QImage &image, int hotspotX, int hotspotY)
+void WaylandCompositor::setCursorSurface(WaylandSurface *surface, int hotspotX, int hotspotY)
{
- Q_UNUSED(image);
+ Q_UNUSED(surface);
Q_UNUSED(hotspotX);
Q_UNUSED(hotspotY);
- qDebug() << "changeCursor" << image.size() << hotspotX << hotspotY;
+ qDebug() << "changeCursor" << surface->size() << hotspotX << hotspotY;
}
void WaylandCompositor::enableSubSurfaceExtension()
diff --git a/src/compositor/compositor_api/waylandcompositor.h b/src/compositor/compositor_api/waylandcompositor.h
index ec09681cd..3df737d19 100644
--- a/src/compositor/compositor_api/waylandcompositor.h
+++ b/src/compositor/compositor_api/waylandcompositor.h
@@ -107,7 +107,7 @@ public:
void sendDragMoveEvent(const QPoint &global, const QPoint &local, WaylandSurface *surface);
void sendDragEndEvent();
- virtual void changeCursor(const QImage &image, int hotspotX, int hotspotY);
+ virtual void setCursorSurface(WaylandSurface *surface, int hotspotX, int hotspotY);
void enableSubSurfaceExtension();
diff --git a/src/compositor/compositor_api/waylandsurface.cpp b/src/compositor/compositor_api/waylandsurface.cpp
index 972ae451b..e30c148ad 100644
--- a/src/compositor/compositor_api/waylandsurface.cpp
+++ b/src/compositor/compositor_api/waylandsurface.cpp
@@ -323,6 +323,15 @@ QString WaylandSurface::title() const
return d->surface->title();
}
+bool WaylandSurface::hasShellSurface() const
+{
+ Q_D(const WaylandSurface);
+ if (d->surface->shellSurface())
+ return true;
+
+ return false;
+}
+
/*!
* \return True if WL_SHELL_SURFACE_TRANSIENT_INACTIVE was set for this surface, meaning it should not receive keyboard focus.
*/
diff --git a/src/compositor/compositor_api/waylandsurface.h b/src/compositor/compositor_api/waylandsurface.h
index ff3eb47fa..e21f124aa 100644
--- a/src/compositor/compositor_api/waylandsurface.h
+++ b/src/compositor/compositor_api/waylandsurface.h
@@ -151,6 +151,8 @@ public:
QString title() const;
+ bool hasShellSurface() const;
+
bool transientInactive() const;
signals:
diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp
index 8c1b05736..9266bc678 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/wlcompositor.cpp
@@ -150,13 +150,13 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
m_data_device_manager = new DataDeviceManager(this);
+ wl_display_init_shm(m_display->handle());
+
wl_display_add_global(m_display->handle(),&wl_output_interface, &m_output_global,OutputGlobal::output_bind_func);
m_shell = new Shell();
wl_display_add_global(m_display->handle(), &wl_shell_interface, m_shell, Shell::bind_func);
- wl_display_init_shm(m_display->handle());
-
m_outputExtension = new OutputExtensionGlobal(this);
m_surfaceExtension = new SurfaceExtensionGlobal(this);
m_qtkeyExtension = new QtKeyExtensionGlobal(this);
@@ -218,7 +218,7 @@ void Compositor::createSurface(struct wl_client *client, uint32_t id)
Surface *surface = new Surface(client,id, this);
m_surfaces << surface;
-
+ //BUG: This may not be an on-screen window surface though
m_qt_compositor->surfaceCreated(surface->waylandSurface());
}
diff --git a/src/compositor/wayland_wrapper/wlinputdevice.cpp b/src/compositor/wayland_wrapper/wlinputdevice.cpp
index 2a04e56c0..c951ecf05 100644
--- a/src/compositor/wayland_wrapper/wlinputdevice.cpp
+++ b/src/compositor/wayland_wrapper/wlinputdevice.cpp
@@ -62,8 +62,6 @@
namespace Wayland {
-static QImage *currentCursor;
-
InputDevice::InputDevice(WaylandInputDevice *handle, Compositor *compositor)
: m_handle(handle)
, m_compositor(compositor)
@@ -234,6 +232,25 @@ void InputDevice::bind_func(struct wl_client *client, void *data,
wl_seat_send_capabilities(resource, caps);
}
+const struct wl_pointer_interface InputDevice::pointer_interface = {
+ InputDevice::set_cursor
+};
+
+void InputDevice::set_cursor(wl_client *client, wl_resource *resource,
+ uint32_t serial, wl_resource *surface_resource,
+ int32_t hotspot_x, int32_t hotspot_y)
+{
+ Q_UNUSED(client);
+ Q_UNUSED(serial);
+
+ wl_pointer *pointer = reinterpret_cast<wl_pointer *>(resource->data);
+ InputDevice *inputDevice = wayland_cast<InputDevice>(pointer->seat);
+ Wayland::Surface *surface = reinterpret_cast<Wayland::Surface *>(surface_resource->data);
+
+ surface->setCursorSurface(true);
+ inputDevice->m_compositor->waylandCompositor()->setCursorSurface(surface->waylandSurface(), hotspot_x, hotspot_y);
+}
+
const struct wl_seat_interface InputDevice::seat_interface = {
get_pointer,
get_keyboard,
@@ -626,38 +643,4 @@ DataDevice *InputDevice::dataDevice(struct wl_client *client) const
return 0;
}
-const struct wl_pointer_interface InputDevice::pointer_interface = {
- InputDevice::pointer_attach
-};
-
-void InputDevice::pointer_attach(struct wl_client *client,
- struct wl_resource *device_resource,
- uint32_t serial,
- struct wl_resource *buffer_resource, int32_t x, int32_t y)
-{
- Q_UNUSED(client);
- Q_UNUSED(serial);
-
- wl_pointer *pointer = reinterpret_cast<wl_pointer *>(device_resource->data);
- InputDevice *inputDevice = wayland_cast<InputDevice>(pointer->seat);
- wl_buffer *buffer = reinterpret_cast<wl_buffer *>(buffer_resource);
-
- if (buffer && wl_buffer_is_shm(buffer)) {
- int stride = wl_shm_buffer_get_stride(buffer);
- uint format = wl_shm_buffer_get_format(buffer);
- (void) format;
- void *data = wl_shm_buffer_get_data(buffer);
- const uchar *char_data = static_cast<const uchar *>(data);
- if (char_data) {
- QImage *img = new QImage(char_data, buffer->width, buffer->height, stride, QImage::Format_ARGB32_Premultiplied);
- inputDevice->m_compositor->waylandCompositor()->changeCursor(*img, x, y);
- delete currentCursor;
- currentCursor = img;
- }
- } else {
- inputDevice->m_compositor->waylandCompositor()->changeCursor(QImage(), x, y);
- }
-}
-
-
}
diff --git a/src/compositor/wayland_wrapper/wlinputdevice.h b/src/compositor/wayland_wrapper/wlinputdevice.h
index 5d4d4510e..afd7ff51d 100644
--- a/src/compositor/wayland_wrapper/wlinputdevice.h
+++ b/src/compositor/wayland_wrapper/wlinputdevice.h
@@ -134,10 +134,12 @@ private:
static void bind_func(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
- static void pointer_attach(struct wl_client *client,
- struct wl_resource *device_base,
- uint32_t serial,
- struct wl_resource *buffer, int32_t x, int32_t y);
+ static void set_cursor(struct wl_client *client,
+ struct wl_resource *device_base,
+ uint32_t serial,
+ struct wl_resource *surface,
+ int32_t hotspot_x,
+ int32_t hotspot_y);
const static struct wl_pointer_interface pointer_interface;
static void get_pointer(struct wl_client *client,
diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp
index d0586a90b..6781f29b9 100644
--- a/src/compositor/wayland_wrapper/wlsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlsurface.cpp
@@ -86,6 +86,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor)
, m_subSurface(0)
, m_shellSurface(0)
, m_transientInactive(false)
+ , m_isCursorSurface(false)
{
wl_list_init(&m_frame_callback_list);
addClientResource(client, &base()->resource, id, &wl_surface_interface,
@@ -413,7 +414,7 @@ void Surface::attach(struct wl_buffer *buffer)
if (last) {
if (last->waylandBufferHandle() == buffer)
return;
- if (!last->damageRect().isValid()) {
+ if (!last->damageRect().isValid() || isCursorSurface() ){
last->disown();
m_bufferQueue.takeLast();
}
diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h
index 8ec87fa36..5c11c6bc4 100644
--- a/src/compositor/wayland_wrapper/wlsurface.h
+++ b/src/compositor/wayland_wrapper/wlsurface.h
@@ -132,6 +132,9 @@ public:
bool transientInactive() const { return m_transientInactive; }
void setTransientInactive(bool v) { m_transientInactive = v; }
+ bool isCursorSurface() const { return m_isCursorSurface; }
+ void setCursorSurface(bool isCursor) { m_isCursorSurface = isCursor; }
+
private:
Q_DISABLE_COPY(Surface)
@@ -163,6 +166,7 @@ private:
QString m_className;
QString m_title;
bool m_transientInactive;
+ bool m_isCursorSurface;
inline SurfaceBuffer *currentSurfaceBuffer() const;
bool advanceBufferQueue();