diff options
author | Andy Nichols <andy.nichols@digia.com> | 2013-01-15 18:42:42 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@digia.com> | 2013-01-18 14:09:35 +0100 |
commit | 3f8c8e0f5c9828634621238c145c7e62298a66ba (patch) | |
tree | 22a153819ccee353b78191356f4770acf72effb2 /src | |
parent | 7bd2d367a3eafc403a6c2d3264c5812119768f60 (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.cpp | 6 | ||||
-rw-r--r-- | src/compositor/compositor_api/waylandcompositor.h | 2 | ||||
-rw-r--r-- | src/compositor/compositor_api/waylandsurface.cpp | 9 | ||||
-rw-r--r-- | src/compositor/compositor_api/waylandsurface.h | 2 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/wlcompositor.cpp | 6 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/wlinputdevice.cpp | 55 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/wlinputdevice.h | 10 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/wlsurface.cpp | 3 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/wlsurface.h | 4 |
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(); |