[xwl] Update to kwaylandserver changes

Summary:
Change so we track track and set a DataSource instead of a DataDevice

This means we have to reverse a connection:
- we need to update Seat with our selection only when our selection is
received by the DataDeviceInterface

- we no longer need to track and watch a dataDevice for changes after
the seat emits selectionChange

Change so that we handle an AbstractDataSource. Meaning we can paste
from clipboard managers.

Testing done:
There is an existing xwayland-selections_test
This still passes.

Copied from:
wl-copy(wlr) to firefox (x)
firefox to wl-paste
firefox to kate (wayland)
kate to firefox

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: cblack, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D29332
master
David Edmundson 2020-05-26 09:55:54 +01:00
parent 963491cc5e
commit 1c2f23d31c
6 changed files with 26 additions and 23 deletions

View File

@ -69,11 +69,19 @@ Clipboard::Clipboard(xcb_atom_t atom, QObject *parent)
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::selectionChanged,
this, &Clipboard::wlSelectionChanged);
connect(DataBridge::self()->dataDeviceIface(), &KWaylandServer::DataDeviceInterface::selectionChanged, this, [](KWaylandServer::DataSourceInterface *selection) {
waylandServer()->seat()->setSelection(selection);
});
connect(DataBridge::self()->dataDeviceIface(), &KWaylandServer::DataDeviceInterface::selectionCleared, this, []() {
waylandServer()->seat()->setSelection(nullptr);
});
}
void Clipboard::wlSelectionChanged(KWaylandServer::DataDeviceInterface *ddi)
void Clipboard::wlSelectionChanged(KWaylandServer::AbstractDataSource *dsi)
{
if (ddi && ddi != DataBridge::self()->dataDeviceIface()) {
if (dsi && dsi->client() != DataBridge::self()->dataDeviceIface()->client()->client()) {
// Wayland native client provides new selection
if (!m_checkConnection) {
m_checkConnection = connect(workspace(), &Workspace::clientActivated,
@ -90,7 +98,7 @@ void Clipboard::wlSelectionChanged(KWaylandServer::DataDeviceInterface *ddi)
void Clipboard::checkWlSource()
{
auto ddi = waylandServer()->seat()->selection();
auto dsi = waylandServer()->seat()->selection();
auto removeSource = [this] {
if (wlSource()) {
setWlSource(nullptr);
@ -107,7 +115,7 @@ void Clipboard::checkWlSource()
// Otherwise the Wayland source gets destroyed to shield
// against snooping X clients.
if (!ddi || DataBridge::self()->dataDeviceIface() == ddi) {
if (!dsi || (DataBridge::self()->dataDeviceIface()->client()->client() == dsi->client())) {
// Xwayland source or no source
disconnect(m_checkConnection);
m_checkConnection = QMetaObject::Connection();
@ -124,14 +132,11 @@ void Clipboard::checkWlSource()
// source already exists, nothing more to do
return;
}
auto *wls = new WlSource(this, ddi);
auto *wls = new WlSource(this);
setWlSource(wls);
auto *dsi = ddi->selection();
if (dsi) {
wls->setDataSourceIface(dsi);
}
connect(ddi, &KWaylandServer::DataDeviceInterface::selectionChanged,
wls, &WlSource::setDataSourceIface);
ownSelection(true);
}
@ -174,14 +179,13 @@ void Clipboard::x11OffersChanged(const QStringList &added, const QStringList &re
// also offers directly the currently available types
source->setDataSource(dataSource);
DataBridge::self()->dataDevice()->setSelection(0, dataSource);
waylandServer()->seat()->setSelection(DataBridge::self()->dataDeviceIface());
} else if (auto *dataSource = source->dataSource()) {
for (const QString &mime : added) {
dataSource->offer(mime);
}
}
} else {
waylandServer()->seat()->setSelection(nullptr);
DataBridge::self()->dataDevice()->setSelection(0);
}
waylandServer()->internalClientConection()->flush();

View File

@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWaylandServer
{
class DataDeviceInterface;
class AbstractDataSource;
}
namespace KWin
@ -49,7 +49,7 @@ private:
/**
* React to Wl selection change.
*/
void wlSelectionChanged(KWaylandServer::DataDeviceInterface *ddi);
void wlSelectionChanged(KWaylandServer::AbstractDataSource *dsi);
/**
* Check the current state of the selection and if a source needs
* to be created or destroyed.

View File

@ -35,6 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWaylandServer/compositor_interface.h>
#include <KWaylandServer/seat_interface.h>
#include <KWaylandServer/datasource_interface.h>
#include <QMouseEvent>
@ -200,7 +201,7 @@ void Dnd::startDrag()
// New Wl to X drag, init drag and Wl source.
m_currentDrag = new WlToXDrag();
auto source = new WlSource(this, ddi);
auto source = new WlSource(this);
source->setDataSourceIface(ddi->dragSource());
setWlSource(source);
ownSelection(true);

View File

@ -118,7 +118,7 @@ XToWlDrag::XToWlDrag(X11Source *source)
*dc = connect(waylandServer()->dataDeviceManager(), &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated, this,
[this, dc](KWaylandServer::DataSourceInterface *dsi) {
Q_ASSERT(dsi);
if (dsi->client() != waylandServer()->internalConnection()) {
if (dsi->client() != waylandServer()->internalConnection()->client()) {
return;
}
QObject::disconnect(*dc);

View File

@ -49,14 +49,12 @@ SelectionSource::SelectionSource(Selection *selection)
{
}
WlSource::WlSource(Selection *selection, KWaylandServer::DataDeviceInterface *ddi)
WlSource::WlSource(Selection *selection)
: SelectionSource(selection)
, m_ddi(ddi)
{
Q_ASSERT(ddi);
}
void WlSource::setDataSourceIface(KWaylandServer::DataSourceInterface *dsi)
void WlSource::setDataSourceIface(KWaylandServer::AbstractDataSource *dsi)
{
if (m_dsi == dsi) {
return;
@ -135,7 +133,7 @@ void WlSource::sendTimestamp(xcb_selection_request_event_t *event)
bool WlSource::checkStartTransfer(xcb_selection_request_event_t *event)
{
// check interfaces available
if (!m_ddi || !m_dsi) {
if (!m_dsi) {
return false;
}

View File

@ -41,6 +41,7 @@ namespace KWaylandServer
{
class DataDeviceInterface;
class DataSourceInterface;
class AbstractDataSource;
}
namespace KWin
@ -93,8 +94,8 @@ class WlSource : public SelectionSource
Q_OBJECT
public:
WlSource(Selection *selection, KWaylandServer::DataDeviceInterface *ddi);
void setDataSourceIface(KWaylandServer::DataSourceInterface *dsi);
WlSource(Selection *selection);
void setDataSourceIface(KWaylandServer::AbstractDataSource *dsi);
bool handleSelectionRequest(xcb_selection_request_event_t *event);
void sendTargets(xcb_selection_request_event_t *event);
@ -109,8 +110,7 @@ Q_SIGNALS:
private:
bool checkStartTransfer(xcb_selection_request_event_t *event);
KWaylandServer::DataDeviceInterface *m_ddi = nullptr;
KWaylandServer::DataSourceInterface *m_dsi = nullptr;
KWaylandServer::AbstractDataSource *m_dsi = nullptr;
QVector<QString> m_offers;
QMetaObject::Connection m_offerConnection;