[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
This commit is contained in:
parent
963491cc5e
commit
1c2f23d31c
6 changed files with 26 additions and 23 deletions
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue