summaryrefslogtreecommitdiffstats
path: root/src/compositor/wayland_wrapper
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2012-01-17 15:32:32 +0200
committerJørgen Lind <jorgen.lind@nokia.com>2012-01-17 17:30:52 +0100
commitd458c31998f5e4fcf85cf31e4b9033fd18f77052 (patch)
tree112f8830e3b87a36012c7b4dd638680b64bf0ac7 /src/compositor/wayland_wrapper
parentc4d4ca361744c689a6dd9b2436931fdcb5aa6df8 (diff)
Implement selection offers from compositor to clients.
It is a hack but works beautifully. It allows the compositor to participate in copy-paste which becomes mandatory when there is UI running in the compositor process. Change-Id: I1993d8705a26159eff0c9947244b66e954b9f460 Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src/compositor/wayland_wrapper')
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri8
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.cpp3
-rw-r--r--src/compositor/wayland_wrapper/wldatadevice.cpp4
-rw-r--r--src/compositor/wayland_wrapper/wldatadevicemanager.cpp74
-rw-r--r--src/compositor/wayland_wrapper/wldatadevicemanager.h18
5 files changed, 102 insertions, 5 deletions
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index 4c1f6ee13..843f3d6d4 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -20,7 +20,8 @@ HEADERS += \
$$PWD/wlextendedsurface.h \
$$PWD/wlextendedoutput.h \
$$PWD/wlsubsurface.h \
- $$PWD/wltouch.h
+ $$PWD/wltouch.h \
+ $$PWD/../../shared/qwaylandmimehelper.h
SOURCES += \
$$PWD/wlcompositor.cpp \
@@ -37,5 +38,8 @@ SOURCES += \
$$PWD/wlextendedsurface.cpp \
$$PWD/wlextendedoutput.cpp \
$$PWD/wlsubsurface.cpp \
- $$PWD/wltouch.cpp
+ $$PWD/wltouch.cpp \
+ $$PWD/../../shared/qwaylandmimehelper.cpp
+
+INCLUDEPATH += $$PWD/../../shared
diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp
index 3c453d0a1..23e225255 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/wlcompositor.cpp
@@ -402,8 +402,7 @@ void Compositor::feedRetainedSelectionData(QMimeData *data)
void Compositor::overrideSelection(QMimeData *data)
{
- Q_UNUSED(data);
- // ### TODO implement
+ m_data_device_manager->overrideSelection(*data);
}
bool Compositor::isDragging() const
diff --git a/src/compositor/wayland_wrapper/wldatadevice.cpp b/src/compositor/wayland_wrapper/wldatadevice.cpp
index f4b2f2b46..bdabf29a4 100644
--- a/src/compositor/wayland_wrapper/wldatadevice.cpp
+++ b/src/compositor/wayland_wrapper/wldatadevice.cpp
@@ -103,7 +103,9 @@ DataDevice::DataDevice(DataDeviceManager *data_device_manager, struct wl_client
void DataDevice::sendSelectionFocus()
{
- //do for all clipboards
+ if (m_data_device_manager->offerFromCompositorToClient(m_data_device_resource))
+ return;
+
DataSource *source = m_data_device_manager->currentSelectionSource();
if (!source) {
return;
diff --git a/src/compositor/wayland_wrapper/wldatadevicemanager.cpp b/src/compositor/wayland_wrapper/wldatadevicemanager.cpp
index ba8510bc5..d3e3fb784 100644
--- a/src/compositor/wayland_wrapper/wldatadevicemanager.cpp
+++ b/src/compositor/wayland_wrapper/wldatadevicemanager.cpp
@@ -45,11 +45,14 @@
#include "wlinputdevice.h"
#include "wlcompositor.h"
#include "wldataoffer.h"
+#include "wlsurface.h"
+#include "qwaylandmimehelper.h"
#include <QtCore/QDebug>
#include <QtCore/QSocketNotifier>
#include <fcntl.h>
#include <QtCore/private/qcore_unix_p.h>
+#include <QtCore/QFile>
namespace Wayland {
@@ -57,6 +60,7 @@ DataDeviceManager::DataDeviceManager(Compositor *compositor)
: m_compositor(compositor)
, m_current_selection_source(0)
, m_retainedReadNotifier(0)
+ , m_compositorOwnsSelection(false)
{
wl_display_add_global(compositor->wl_display(), &wl_data_device_manager_interface, this, DataDeviceManager::bind_func_drag);
}
@@ -69,6 +73,8 @@ void DataDeviceManager::setCurrentSelectionSource(DataSource *source)
return;
}
+ m_compositorOwnsSelection = false;
+
finishReadFromClient();
m_current_selection_source = source;
@@ -210,4 +216,72 @@ struct wl_data_device_manager_interface DataDeviceManager::drag_interface = {
DataDeviceManager::get_data_device
};
+void DataDeviceManager::overrideSelection(const QMimeData &mimeData)
+{
+ QStringList formats = mimeData.formats();
+ if (formats.isEmpty())
+ return;
+
+ m_retainedData.clear();
+ foreach (const QString &format, formats)
+ m_retainedData.setData(format, mimeData.data(format));
+
+ m_compositor->feedRetainedSelectionData(&m_retainedData);
+
+ m_compositorOwnsSelection = true;
+
+ InputDevice *dev = m_compositor->defaultInputDevice();
+ Surface *focusSurface = dev->keyboardFocus();
+ if (focusSurface)
+ offerFromCompositorToClient(
+ dev->dataDevice(focusSurface->base()->resource.client)->dataDeviceResource());
+}
+
+bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource)
+{
+ if (!m_compositorOwnsSelection)
+ return false;
+
+ wl_client *client = clientDataDeviceResource->client;
+ qDebug("compositor offers %d types to %p", m_retainedData.formats().count(), client);
+
+ struct wl_resource *selectionOffer =
+ wl_client_new_object(client, &wl_data_offer_interface, &compositor_offer_interface, this);
+ wl_resource_post_event(clientDataDeviceResource, WL_DATA_DEVICE_DATA_OFFER, selectionOffer);
+ foreach (const QString &format, m_retainedData.formats()) {
+ QByteArray ba = format.toLatin1();
+ wl_resource_post_event(selectionOffer, WL_DATA_OFFER_OFFER, ba.constData());
+ }
+ wl_resource_post_event(clientDataDeviceResource, WL_DATA_DEVICE_SELECTION, selectionOffer);
+
+ return true;
+}
+
+void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *)
+{
+}
+
+void DataDeviceManager::comp_receive(wl_client *client, wl_resource *resource, const char *mime_type, int32_t fd)
+{
+ DataDeviceManager *self = static_cast<DataDeviceManager *>(resource->data);
+ qDebug("client %p wants data for type %s from compositor", client, mime_type);
+ QByteArray content = QWaylandMimeHelper::getByteArray(&self->m_retainedData, QString::fromLatin1(mime_type));
+ if (!content.isEmpty()) {
+ QFile f;
+ if (f.open(fd, QIODevice::WriteOnly))
+ f.write(content);
+ }
+ close(fd);
+}
+
+void DataDeviceManager::comp_destroy(wl_client *, wl_resource *)
+{
+}
+
+const struct wl_data_offer_interface DataDeviceManager::compositor_offer_interface = {
+ DataDeviceManager::comp_accept,
+ DataDeviceManager::comp_receive,
+ DataDeviceManager::comp_destroy
+};
+
} //namespace
diff --git a/src/compositor/wayland_wrapper/wldatadevicemanager.h b/src/compositor/wayland_wrapper/wldatadevicemanager.h
index af26cb0e9..75844d207 100644
--- a/src/compositor/wayland_wrapper/wldatadevicemanager.h
+++ b/src/compositor/wayland_wrapper/wldatadevicemanager.h
@@ -71,6 +71,9 @@ public:
void sourceDestroyed(DataSource *source);
+ void overrideSelection(const QMimeData &mimeData);
+ bool offerFromCompositorToClient(wl_resource *clientDataDeviceResource);
+
private slots:
void readFromClient(int fd);
@@ -102,6 +105,21 @@ private:
int m_retainedReadIndex;
QByteArray m_retainedReadBuf;
+ bool m_compositorOwnsSelection;
+
+
+ static void comp_accept(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t time,
+ const char *type);
+ static void comp_receive(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *mime_type,
+ int32_t fd);
+ static void comp_destroy(struct wl_client *client,
+ struct wl_resource *resource);
+
+ static const struct wl_data_offer_interface compositor_offer_interface;
};
}