diff options
Diffstat (limited to 'src/compositor/wayland_wrapper/qwldatadevice.cpp')
-rw-r--r-- | src/compositor/wayland_wrapper/qwldatadevice.cpp | 196 |
1 files changed, 144 insertions, 52 deletions
diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index 89fa7a08e..f7ba9c4e6 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -40,11 +40,17 @@ #include "qwldatadevice_p.h" +#include "qwlcompositor_p.h" #include "qwldatasource_p.h" #include "qwldataoffer_p.h" +#include "qwlinputdevice_p.h" +#include "qwlkeyboard_p.h" +#include "qwlpointer_p.h" +#include "qwlsurface_p.h" +#include "qwltouch_p.h" #include "qwldatadevicemanager_p.h" -#include <stdlib.h> +#include "qwaylanddrag.h" #include <QDebug> @@ -52,78 +58,164 @@ QT_BEGIN_NAMESPACE namespace QtWayland { -void DataDevice::start_drag(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *source, - struct wl_resource *surface, - struct wl_resource *icon, - uint32_t time) +DataDevice::DataDevice(InputDevice *inputDevice) + : wl_data_device() + , m_compositor(inputDevice->compositor()) + , m_inputDevice(inputDevice) + , m_selectionSource(0) + , m_dragClient(0) + , m_dragDataSource(0) + , m_dragFocus(0) + , m_dragFocusResource(0) + , m_dragIcon(0) { - Q_UNUSED(client); - Q_UNUSED(surface); - Q_UNUSED(icon); - Q_UNUSED(time); - DataDevice *data_device = static_cast<DataDevice *>(resource->data); - DataSource *data_source = static_cast<DataSource *>(source->data); - Q_UNUSED(data_device); - Q_UNUSED(data_source); } -void DataDevice::set_selection(struct wl_client *client, - struct wl_resource *data_device_resource, - struct wl_resource *source, - uint32_t time) +void DataDevice::setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource) { - Q_UNUSED(client); - Q_UNUSED(time); - DataDevice *data_device = static_cast<DataDevice *>(data_device_resource->data); - DataSource *data_source = static_cast<DataSource *>(source->data); + if (!focusResource) + return; - data_device->m_data_device_manager->setCurrentSelectionSource(data_source); + Resource *resource = resourceMap().value(focusResource->client()); + if (!resource) + return; + + if (m_selectionSource) { + DataOffer *offer = new DataOffer(m_selectionSource, resource); + send_selection(resource->handle, offer->resource()->handle); + } } -const struct wl_data_device_interface DataDevice::data_device_interface = { - DataDevice::start_drag, - DataDevice::set_selection -}; +void DataDevice::setDragFocus(Surface *focus, const QPointF &localPosition) +{ + if (m_dragFocusResource) { + send_leave(m_dragFocusResource->handle); + m_dragFocus = 0; + m_dragFocusResource = 0; + } + + if (!focus) + return; + + if (!m_dragDataSource && m_dragClient != focus->resource()->client()) + return; + + Resource *resource = resourceMap().value(focus->resource()->client()); -DataDevice::DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id) - : m_data_device_manager(data_device_manager) - , m_sent_selection_time(0) + if (!resource) + return; + + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + + DataOffer *offer = m_dragDataSource ? new DataOffer(m_dragDataSource, resource) : 0; + + if (m_dragDataSource && !offer) + return; + + send_enter(resource->handle, serial, focus->resource()->handle, + wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), + offer->resource()->handle); + + m_dragFocus = focus; + m_dragFocusResource = resource; +} + +Surface *DataDevice::dragIcon() const { + return m_dragIcon; +} - //static int i = 0; - //qDebug() << "data device" << ++i; - m_data_device_resource = - wl_client_add_object(client,&wl_data_device_interface,&data_device_interface,id, this); +void DataDevice::sourceDestroyed(DataSource *source) +{ + if (m_selectionSource == source) + m_selectionSource = 0; } -void DataDevice::sendSelectionFocus() +void DataDevice::focus() { - if (m_data_device_manager->offerFromCompositorToClient(m_data_device_resource)) - return; + Surface *focus = m_compositor->pickSurface(m_pointer->currentPosition()); - DataSource *source = m_data_device_manager->currentSelectionSource(); - if (!source || !source->client()) { - m_data_device_manager->offerRetainedSelection(m_data_device_resource); - return; + if (focus != m_dragFocus) + setDragFocus(focus, m_compositor->mapToSurface(focus, m_pointer->currentPosition())); +} + +void DataDevice::motion(uint32_t time) +{ + if (m_dragIcon) { + m_dragIcon->setPos(m_pointer->currentPosition()); + } + + if (m_dragFocusResource && m_dragFocus) { + const QPointF &surfacePoint = m_compositor->mapToSurface(m_dragFocus, m_pointer->currentPosition()); + qDebug() << Q_FUNC_INFO << m_pointer->currentPosition() << surfacePoint; + send_motion(m_dragFocusResource->handle, time, + wl_fixed_from_double(surfacePoint.x()), wl_fixed_from_double(surfacePoint.y())); } - if (source->time() > m_sent_selection_time) { //this makes sure we don't resend - if (source->client() != m_data_device_resource->client) { //don't send selection to the client that owns the selection - DataOffer *data_offer = source->dataOffer(); - wl_resource *client_resource = - data_offer->addDataDeviceResource(m_data_device_resource); - //qDebug() << "sending data_offer for source" << source; - wl_data_device_send_selection(m_data_device_resource,client_resource); - m_sent_selection_time = source->time(); +} + +void DataDevice::button(uint32_t time, Qt::MouseButton button, uint32_t state) +{ + Q_UNUSED(time); + + if (m_dragFocusResource && + m_pointer->grabButton() == button && + state == Pointer::button_state_released) + send_drop(m_dragFocusResource->handle); + + if (!m_pointer->buttonPressed() && + state == Pointer::button_state_released) { + + if (m_dragIcon) { + m_dragIcon = 0; + Q_EMIT m_inputDevice->dragHandle()->iconChanged(); } + + setDragFocus(0, QPointF()); + m_pointer->endGrab(); + } +} + +void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) +{ + if (m_inputDevice->pointerDevice()->grabSerial() == serial) { + if (!m_inputDevice->pointerDevice()->buttonPressed() || + m_inputDevice->pointerDevice()->focusSurface() != Surface::fromResource(origin)) + return; + + m_dragClient = resource->client(); + m_dragDataSource = source != 0 ? DataSource::fromResource(source) : 0; + m_dragIcon = icon != 0 ? Surface::fromResource(icon) : 0; + Q_EMIT m_inputDevice->dragHandle()->iconChanged(); + + m_inputDevice->pointerDevice()->setFocus(0, QPointF()); + m_inputDevice->pointerDevice()->startGrab(this); } } -struct wl_resource *DataDevice::dataDeviceResource() const +void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *source, uint32_t serial) { - return m_data_device_resource; + Q_UNUSED(serial); + + DataSource *dataSource = source ? DataSource::fromResource(source) : 0; + + if (m_selectionSource) + m_selectionSource->cancel(); + + m_selectionSource = dataSource; + m_compositor->dataDeviceManager()->setCurrentSelectionSource(m_selectionSource); + if (m_selectionSource) + m_selectionSource->setDevice(this); + + QtWaylandServer::wl_keyboard::Resource *focusResource = m_inputDevice->keyboardDevice()->focusResource(); + Resource *resource = focusResource ? resourceMap().value(focusResource->client()) : 0; + + if (resource && m_selectionSource) { + DataOffer *offer = new DataOffer(m_selectionSource, resource); + send_selection(resource->handle, offer->resource()->handle); + } else if (resource) { + send_selection(resource->handle, 0); + } } } |