Use a direct connection for X to wayland drags
We already use a direct DataSource object for transfer. Use of the new public SeatInterface::startDrag allows us to start our drag directly.
This commit is contained in:
parent
400dd31db6
commit
65f168e144
11 changed files with 123 additions and 254 deletions
|
@ -18,16 +18,11 @@
|
|||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/datadevicemanager.h>
|
||||
#include <KWayland/Client/seat.h>
|
||||
|
||||
#include <KWaylandServer/clientconnection.h>
|
||||
#include <KWaylandServer/datadevicemanager_interface.h>
|
||||
#include <KWaylandServer/datadevice_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
|
||||
using namespace KWayland::Client;
|
||||
using namespace KWaylandServer;
|
||||
|
||||
namespace KWin
|
||||
|
@ -46,31 +41,7 @@ DataBridge::DataBridge(QObject *parent)
|
|||
: QObject(parent)
|
||||
{
|
||||
s_self = this;
|
||||
|
||||
DataDeviceManager *dataDeviceManager = waylandServer()->internalDataDeviceManager();
|
||||
Seat *seat = waylandServer()->internalSeat();
|
||||
m_dataDevice = dataDeviceManager->getDataDevice(seat, this);
|
||||
|
||||
const DataDeviceManagerInterface *dataDeviceManagerInterface =
|
||||
waylandServer()->dataDeviceManager();
|
||||
|
||||
auto *dc = new QMetaObject::Connection();
|
||||
*dc = connect(dataDeviceManagerInterface, &DataDeviceManagerInterface::dataDeviceCreated, this,
|
||||
[this, dc](DataDeviceInterface *dataDeviceInterface) {
|
||||
if (m_dataDeviceInterface) {
|
||||
return;
|
||||
}
|
||||
if (dataDeviceInterface->client() != *waylandServer()->internalConnection()) {
|
||||
return;
|
||||
}
|
||||
QObject::disconnect(*dc);
|
||||
delete dc;
|
||||
m_dataDeviceInterface = dataDeviceInterface;
|
||||
init();
|
||||
}
|
||||
);
|
||||
|
||||
waylandServer()->dispatch();
|
||||
init();
|
||||
}
|
||||
|
||||
DataBridge::~DataBridge()
|
||||
|
@ -83,7 +54,6 @@ void DataBridge::init()
|
|||
m_clipboard = new Clipboard(atoms->clipboard, this);
|
||||
m_dnd = new Dnd(atoms->xdnd_selection, this);
|
||||
m_primary = new Primary(atoms->primary, this);
|
||||
waylandServer()->dispatch();
|
||||
kwinApp()->installNativeEventFilter(this);
|
||||
}
|
||||
|
||||
|
@ -98,9 +68,6 @@ bool DataBridge::nativeEventFilter(const QByteArray &eventType, void *message, l
|
|||
|
||||
DragEventReply DataBridge::dragMoveFilter(Toplevel *target, const QPoint &pos)
|
||||
{
|
||||
if (!m_dnd) {
|
||||
return DragEventReply::Wayland;
|
||||
}
|
||||
return m_dnd->dragMoveFilter(target, pos);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,6 @@
|
|||
#include <QObject>
|
||||
#include <QPoint>
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class DataDevice;
|
||||
}
|
||||
}
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class DataDeviceInterface;
|
||||
|
@ -56,14 +49,6 @@ public:
|
|||
|
||||
DragEventReply dragMoveFilter(Toplevel *target, const QPoint &pos);
|
||||
|
||||
KWayland::Client::DataDevice *dataDevice() const
|
||||
{
|
||||
return m_dataDevice;
|
||||
}
|
||||
KWaylandServer::DataDeviceInterface *dataDeviceIface() const
|
||||
{
|
||||
return m_dataDeviceInterface;
|
||||
}
|
||||
Dnd *dnd() const
|
||||
{
|
||||
return m_dnd;
|
||||
|
@ -78,10 +63,6 @@ private:
|
|||
Dnd *m_dnd = nullptr;
|
||||
Primary *m_primary = nullptr;
|
||||
|
||||
/* Internal data device interface */
|
||||
KWayland::Client::DataDevice *m_dataDevice = nullptr;
|
||||
KWaylandServer::DataDeviceInterface *m_dataDeviceInterface = nullptr;
|
||||
|
||||
KWIN_SINGLETON(DataBridge)
|
||||
};
|
||||
|
||||
|
|
|
@ -26,5 +26,31 @@ void XwlDataSource::setMimeTypes(const QStringList &mimeTypes)
|
|||
{
|
||||
m_mimeTypes = mimeTypes;
|
||||
}
|
||||
|
||||
void XwlDataSource::accept(const QString &mimeType)
|
||||
{
|
||||
m_accepted = !mimeType.isEmpty();
|
||||
}
|
||||
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDActions XwlDataSource::supportedDragAndDropActions() const
|
||||
{
|
||||
return m_supportedDndActions;
|
||||
}
|
||||
|
||||
void XwlDataSource::setSupportedDndActions(KWaylandServer::DataDeviceManagerInterface::DnDActions dndActions)
|
||||
{
|
||||
m_supportedDndActions = dndActions;
|
||||
Q_EMIT supportedDragAndDropActionsChanged();
|
||||
}
|
||||
|
||||
void XwlDataSource::dndAction(KWaylandServer::DataDeviceManagerInterface::DnDAction action)
|
||||
{
|
||||
m_dndAction = action;
|
||||
}
|
||||
|
||||
bool XwlDataSource::isAccepted() const
|
||||
{
|
||||
return m_accepted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,35 @@ public:
|
|||
void cancel() override;
|
||||
QStringList mimeTypes() const override;
|
||||
void setMimeTypes(const QStringList &mimeTypes);
|
||||
|
||||
void accept(const QString &mimeType) override;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDActions supportedDragAndDropActions() const override;
|
||||
void setSupportedDndActions(KWaylandServer::DataDeviceManagerInterface::DnDActions dndActions);
|
||||
|
||||
void dndAction(KWaylandServer::DataDeviceManagerInterface::DnDAction action) override;
|
||||
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction selectedDragAndDropAction() {
|
||||
return m_dndAction;
|
||||
}
|
||||
|
||||
void dropPerformed() override {
|
||||
Q_EMIT dropped();
|
||||
}
|
||||
void dndFinished() override {
|
||||
Q_EMIT finished();
|
||||
}
|
||||
bool isAccepted() const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void dataRequested(const QString &mimeType, qint32 fd);
|
||||
void dropped();
|
||||
void finished();
|
||||
|
||||
private:
|
||||
QStringList m_mimeTypes;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDActions m_supportedDndActions;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction m_dndAction = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
|
||||
bool m_accepted = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
#include "xwayland.h"
|
||||
#include "xwldrophandler.h"
|
||||
|
||||
#include <KWayland/Client/compositor.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
#include <KWaylandServer/compositor_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
#include <KWaylandServer/datasource_interface.h>
|
||||
|
@ -80,44 +77,6 @@ Dnd::Dnd(xcb_atom_t atom, QObject *parent)
|
|||
|
||||
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragStarted, this, &Dnd::startDrag);
|
||||
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragEnded, this, &Dnd::endDrag);
|
||||
|
||||
const auto *comp = waylandServer()->compositor();
|
||||
m_surface = waylandServer()->internalCompositor()->createSurface(this);
|
||||
m_surface->setInputRegion(nullptr);
|
||||
m_surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||
auto *dc = new QMetaObject::Connection();
|
||||
*dc = connect(comp, &KWaylandServer::CompositorInterface::surfaceCreated, this,
|
||||
[this, dc](KWaylandServer::SurfaceInterface *si) {
|
||||
// TODO: how to make sure that it is the iface of m_surface?
|
||||
if (m_surfaceIface || si->client() != waylandServer()->internalConnection()) {
|
||||
return;
|
||||
}
|
||||
QObject::disconnect(*dc);
|
||||
delete dc;
|
||||
m_surfaceIface = si;
|
||||
connect(workspace(), &Workspace::clientActivated, this,
|
||||
[this](AbstractClient *ac) {
|
||||
if (!ac || !ac->inherits("KWin::X11Client")) {
|
||||
return;
|
||||
}
|
||||
auto *surface = ac->surface();
|
||||
if (surface) {
|
||||
surface->setDataProxy(m_surfaceIface);
|
||||
} else {
|
||||
auto *dc = new QMetaObject::Connection();
|
||||
*dc = connect(ac, &AbstractClient::surfaceChanged, this, [this, ac, dc] {
|
||||
if (auto *surface = ac->surface()) {
|
||||
surface->setDataProxy(m_surfaceIface);
|
||||
QObject::disconnect(*dc);
|
||||
delete dc;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
waylandServer()->dispatch();
|
||||
}
|
||||
|
||||
void Dnd::doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event)
|
||||
|
@ -153,7 +112,6 @@ void Dnd::doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event)
|
|||
if (!source) {
|
||||
return;
|
||||
}
|
||||
DataBridge::self()->dataDeviceIface()->updateProxy(originSurface);
|
||||
m_currentDrag = new XToWlDrag(source);
|
||||
}
|
||||
|
||||
|
@ -161,7 +119,6 @@ void Dnd::x11OffersChanged(const QStringList &added, const QStringList &removed)
|
|||
{
|
||||
Q_UNUSED(added);
|
||||
Q_UNUSED(removed);
|
||||
// TODO: handled internally
|
||||
}
|
||||
|
||||
bool Dnd::handleClientMessage(xcb_client_message_event_t *event)
|
||||
|
@ -179,17 +136,14 @@ bool Dnd::handleClientMessage(xcb_client_message_event_t *event)
|
|||
|
||||
DragEventReply Dnd::dragMoveFilter(Toplevel *target, const QPoint &pos)
|
||||
{
|
||||
// This filter only is used when a drag is in process.
|
||||
Q_ASSERT(m_currentDrag);
|
||||
return m_currentDrag->moveFilter(target, pos);
|
||||
}
|
||||
|
||||
void Dnd::startDrag()
|
||||
{
|
||||
auto *ddi = waylandServer()->seat()->dragSource();
|
||||
if (ddi == DataBridge::self()->dataDeviceIface()) {
|
||||
// X to Wl drag, started by us, is in progress.
|
||||
Q_ASSERT(m_currentDrag);
|
||||
auto dragSource = waylandServer()->seat()->dragSource();
|
||||
if (qobject_cast<XwlDataSource*>(dragSource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -199,7 +153,7 @@ void Dnd::startDrag()
|
|||
// New Wl to X drag, init drag and Wl source.
|
||||
m_currentDrag = new WlToXDrag();
|
||||
auto source = new WlSource(this);
|
||||
source->setDataSourceIface(ddi->dragSource());
|
||||
source->setDataSourceIface(dragSource);
|
||||
setWlSource(source);
|
||||
ownSelection(true);
|
||||
}
|
||||
|
@ -223,5 +177,36 @@ void Dnd::clearOldDrag(Drag *drag)
|
|||
delete drag;
|
||||
}
|
||||
|
||||
using DnDAction = KWaylandServer::DataDeviceManagerInterface::DnDAction;
|
||||
using DnDActions = KWaylandServer::DataDeviceManagerInterface::DnDActions;
|
||||
|
||||
DnDAction Dnd::atomToClientAction(xcb_atom_t atom)
|
||||
{
|
||||
if (atom == atoms->xdnd_action_copy) {
|
||||
return DnDAction::Copy;
|
||||
} else if (atom == atoms->xdnd_action_move) {
|
||||
return DnDAction::Move;
|
||||
} else if (atom == atoms->xdnd_action_ask) {
|
||||
// we currently do not support it - need some test client first
|
||||
return DnDAction::None;
|
||||
// return DnDAction::Ask;
|
||||
}
|
||||
return DnDAction::None;
|
||||
}
|
||||
|
||||
xcb_atom_t Dnd::clientActionToAtom(DnDAction action)
|
||||
{
|
||||
if (action == DnDAction::Copy) {
|
||||
return atoms->xdnd_action_copy;
|
||||
} else if (action == DnDAction::Move) {
|
||||
return atoms->xdnd_action_move;
|
||||
} else if (action == DnDAction::Ask) {
|
||||
// we currently do not support it - need some test client first
|
||||
return XCB_ATOM_NONE;
|
||||
// return atoms->xdnd_action_ask;
|
||||
}
|
||||
return XCB_ATOM_NONE;
|
||||
}
|
||||
|
||||
} // namespace Xwl
|
||||
} // namespace KWin
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "selection.h"
|
||||
|
||||
#include <KWaylandServer/datadevicemanager_interface.h>
|
||||
#include <QPoint>
|
||||
|
||||
namespace KWaylandServer
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
|
||||
SPDX-FileCopyrightText: 2021 David Edmundson <davidedmundson@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 David Redondo <kde@david-redondo.de>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
@ -12,18 +14,17 @@
|
|||
#include "dnd.h"
|
||||
#include "selection_source.h"
|
||||
#include "xwayland.h"
|
||||
#include "datasource.h"
|
||||
|
||||
#include "abstract_client.h"
|
||||
#include "atoms.h"
|
||||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <KWayland/Client/datadevice.h>
|
||||
#include <KWayland/Client/datasource.h>
|
||||
|
||||
#include <KWaylandServer/datasource_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
#include <KWaylandServer/surface_interface.h>
|
||||
#include <KWaylandServer/datadevice_interface.h>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QTimer>
|
||||
|
@ -33,36 +34,8 @@ namespace KWin
|
|||
namespace Xwl
|
||||
{
|
||||
|
||||
using DnDAction = KWayland::Client::DataDeviceManager::DnDAction;
|
||||
using DnDActions = KWayland::Client::DataDeviceManager::DnDActions;
|
||||
|
||||
static DnDAction atomToClientAction(xcb_atom_t atom)
|
||||
{
|
||||
if (atom == atoms->xdnd_action_copy) {
|
||||
return DnDAction::Copy;
|
||||
} else if (atom == atoms->xdnd_action_move) {
|
||||
return DnDAction::Move;
|
||||
} else if (atom == atoms->xdnd_action_ask) {
|
||||
// we currently do not support it - need some test client first
|
||||
return DnDAction::None;
|
||||
// return DnDAction::Ask;
|
||||
}
|
||||
return DnDAction::None;
|
||||
}
|
||||
|
||||
xcb_atom_t clientActionToAtom(DnDAction action)
|
||||
{
|
||||
if (action == DnDAction::Copy) {
|
||||
return atoms->xdnd_action_copy;
|
||||
} else if (action == DnDAction::Move) {
|
||||
return atoms->xdnd_action_move;
|
||||
} else if (action == DnDAction::Ask) {
|
||||
// we currently do not support it - need some test client first
|
||||
return XCB_ATOM_NONE;
|
||||
// return atoms->xdnd_action_ask;
|
||||
}
|
||||
return XCB_ATOM_NONE;
|
||||
}
|
||||
using DnDAction = KWaylandServer::DataDeviceManagerInterface::DnDAction;
|
||||
using DnDActions = KWaylandServer::DataDeviceManagerInterface::DnDActions;
|
||||
|
||||
static QStringList atomToMimeTypes(xcb_atom_t atom)
|
||||
{
|
||||
|
@ -103,9 +76,7 @@ XToWlDrag::XToWlDrag(X11Source *source)
|
|||
Q_UNUSED(fd);
|
||||
m_dataRequests << QPair<xcb_timestamp_t, bool>(m_source->timestamp(), false);
|
||||
});
|
||||
auto *ddm = waylandServer()->internalDataDeviceManager();
|
||||
m_dataSource = ddm->createDataSource(this);
|
||||
connect(m_dataSource, &KWayland::Client::DataSource::dragAndDropPerformed, this, [this] {
|
||||
connect(&m_selectionSource, &XwlDataSource::dropped, this, [this] {
|
||||
m_performed = true;
|
||||
if (m_visit) {
|
||||
connect(m_visit, &WlVisit::finish, this, [this](WlVisit *visit) {
|
||||
|
@ -124,43 +95,22 @@ XToWlDrag::XToWlDrag(X11Source *source)
|
|||
}
|
||||
});
|
||||
}
|
||||
// Dave do we need this async finish check anymore?
|
||||
checkForFinished();
|
||||
});
|
||||
connect(m_dataSource, &KWayland::Client::DataSource::dragAndDropFinished, this, [this] {
|
||||
// this call is not reliably initiated by Wayland clients
|
||||
connect(&m_selectionSource, &XwlDataSource::finished, this, [this] {
|
||||
checkForFinished();
|
||||
});
|
||||
connect(&m_selectionSource, &XwlDataSource::dataRequested, source, &X11Source::startTransfer);
|
||||
|
||||
// source does _not_ take ownership of m_dataSource
|
||||
source->setDataSource(m_dataSource);
|
||||
|
||||
auto *dc = new QMetaObject::Connection();
|
||||
*dc = connect(waylandServer()->dataDeviceManager(), &KWaylandServer::DataDeviceManagerInterface::dataSourceCreated, this,
|
||||
[this, dc](KWaylandServer::DataSourceInterface *dsi) {
|
||||
Q_ASSERT(dsi);
|
||||
if (dsi->client() != waylandServer()->internalConnection()->client()) {
|
||||
return;
|
||||
}
|
||||
QObject::disconnect(*dc);
|
||||
delete dc;
|
||||
connect(dsi, &KWaylandServer::DataSourceInterface::mimeTypeOffered, this, &XToWlDrag::offerCallback);
|
||||
}
|
||||
);
|
||||
// Start drag with serial of last left pointer button press.
|
||||
// This means X to Wl drags can only be executed with the left pointer button being pressed.
|
||||
// For touch and (maybe) other pointer button drags we have to revisit this.
|
||||
//
|
||||
// Until then we accept the restriction for Xwayland clients.
|
||||
DataBridge::self()->dataDevice()->startDrag(waylandServer()->seat()->pointerButtonSerial(Qt::LeftButton),
|
||||
m_dataSource,
|
||||
DataBridge::self()->dnd()->surface());
|
||||
waylandServer()->dispatch();
|
||||
auto *seat = waylandServer()->seat();
|
||||
int serial = waylandServer()->seat()->pointerButtonSerial(Qt::LeftButton);
|
||||
// we know we are the focussed surface as dnd checks
|
||||
seat->startDrag(&m_selectionSource, seat->focusedPointerSurface(), serial);
|
||||
}
|
||||
|
||||
XToWlDrag::~XToWlDrag()
|
||||
{
|
||||
delete m_dataSource;
|
||||
m_dataSource = nullptr;
|
||||
}
|
||||
|
||||
DragEventReply XToWlDrag::moveFilter(Toplevel *target, const QPoint &pos)
|
||||
|
@ -194,7 +144,7 @@ DragEventReply XToWlDrag::moveFilter(Toplevel *target, const QPoint &pos)
|
|||
if (hasCurrent) {
|
||||
// last received enter event is now void,
|
||||
// wait for the next one
|
||||
seat->setDragTarget(nullptr);
|
||||
seat->setDragTarget(nullptr, nullptr);
|
||||
}
|
||||
return DragEventReply::Ignore;
|
||||
}
|
||||
|
@ -220,18 +170,12 @@ bool XToWlDrag::handleClientMessage(xcb_client_message_event_t *event)
|
|||
|
||||
void XToWlDrag::setDragAndDropAction(DnDAction action)
|
||||
{
|
||||
m_dataSource->setDragAndDropActions(action);
|
||||
m_selectionSource.setSupportedDndActions(action);
|
||||
}
|
||||
|
||||
DnDAction XToWlDrag::selectedDragAndDropAction()
|
||||
{
|
||||
// Take the last received action only from before the drag was performed,
|
||||
// because the action gets reset as soon as the drag is performed
|
||||
// (this seems to be a bug in KWayland -> TODO).
|
||||
if (!m_performed) {
|
||||
m_lastSelectedDragAndDropAction = m_dataSource->selectedDragAndDropAction();
|
||||
}
|
||||
return m_lastSelectedDragAndDropAction;
|
||||
return m_selectionSource.selectedDragAndDropAction();
|
||||
}
|
||||
|
||||
void XToWlDrag::setOffers(const Mimes &offers)
|
||||
|
@ -250,32 +194,25 @@ void XToWlDrag::setOffers(const Mimes &offers)
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: make sure that offers are not changed in between visits
|
||||
|
||||
m_offersPending = m_offers = offers;
|
||||
m_offers = offers;
|
||||
QStringList mimeTypes;
|
||||
mimeTypes.reserve(offers.size());
|
||||
for (const auto &mimePair : offers) {
|
||||
m_dataSource->offer(mimePair.first);
|
||||
mimeTypes.append(mimePair.first);
|
||||
}
|
||||
m_selectionSource.setMimeTypes(mimeTypes);
|
||||
setDragTarget();
|
||||
}
|
||||
|
||||
using Mime = QPair<QString, xcb_atom_t>;
|
||||
|
||||
void XToWlDrag::offerCallback(const QString &mime)
|
||||
{
|
||||
m_offersPending.erase(std::remove_if(m_offersPending.begin(), m_offersPending.end(),
|
||||
[mime](const Mime &m) { return m.first == mime; }));
|
||||
if (m_offersPending.isEmpty() && m_visit && m_visit->entered()) {
|
||||
setDragTarget();
|
||||
}
|
||||
}
|
||||
|
||||
void XToWlDrag::setDragTarget()
|
||||
{
|
||||
auto *ac = m_visit->target();
|
||||
|
||||
workspace()->activateClient(ac);
|
||||
auto seat = waylandServer()->seat();
|
||||
auto dropTarget = seat->dropHandlerForSurface(ac->surface());
|
||||
|
||||
if (!dropTarget || !ac->surface()) {
|
||||
return;
|
||||
}
|
||||
|
@ -470,7 +407,7 @@ bool WlVisit::handlePosition(xcb_client_message_event_t *event)
|
|||
|
||||
xcb_atom_t actionAtom = m_version > 1 ? data->data32[4] :
|
||||
atoms->xdnd_action_copy;
|
||||
auto action = atomToClientAction(actionAtom);
|
||||
auto action = Dnd::atomToClientAction(actionAtom);
|
||||
|
||||
if (action == DnDAction::None) {
|
||||
// copy action is always possible in XDND
|
||||
|
|
|
@ -10,21 +10,14 @@
|
|||
#define KWIN_XWL_DRAG_X
|
||||
|
||||
#include "drag.h"
|
||||
#include "datasource.h"
|
||||
|
||||
#include <KWayland/Client/datadevicemanager.h>
|
||||
#include <KWaylandServer/datadevicemanager_interface.h>
|
||||
|
||||
#include <QPoint>
|
||||
#include <QPointer>
|
||||
#include <QVector>
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class DataSource;
|
||||
}
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class Toplevel;
|
||||
|
@ -49,8 +42,8 @@ public:
|
|||
DragEventReply moveFilter(Toplevel *target, const QPoint &pos) override;
|
||||
bool handleClientMessage(xcb_client_message_event_t *event) override;
|
||||
|
||||
void setDragAndDropAction(KWayland::Client::DataDeviceManager::DnDAction action);
|
||||
KWayland::Client::DataDeviceManager::DnDAction selectedDragAndDropAction();
|
||||
void setDragAndDropAction(KWaylandServer::DataDeviceManagerInterface::DnDAction action);
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction selectedDragAndDropAction();
|
||||
|
||||
bool end() override {
|
||||
return false;
|
||||
|
@ -61,15 +54,13 @@ public:
|
|||
|
||||
private:
|
||||
void setOffers(const Mimes &offers);
|
||||
void offerCallback(const QString &mime);
|
||||
void setDragTarget();
|
||||
|
||||
bool checkForFinished();
|
||||
|
||||
KWayland::Client::DataSource *m_dataSource;
|
||||
|
||||
Mimes m_offers;
|
||||
Mimes m_offersPending;
|
||||
|
||||
XwlDataSource m_selectionSource;
|
||||
|
||||
X11Source *m_source;
|
||||
QVector<QPair<xcb_timestamp_t, bool> > m_dataRequests;
|
||||
|
@ -78,7 +69,7 @@ private:
|
|||
QVector<WlVisit *> m_oldVisits;
|
||||
|
||||
bool m_performed = false;
|
||||
KWayland::Client::DataDeviceManager::DnDAction m_lastSelectedDragAndDropAction = KWayland::Client::DataDeviceManager::DnDAction::None;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction m_lastSelectedDragAndDropAction = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
|
||||
|
||||
Q_DISABLE_COPY(XToWlDrag)
|
||||
};
|
||||
|
@ -139,7 +130,7 @@ private:
|
|||
uint32_t m_version = 0;
|
||||
|
||||
xcb_atom_t m_actionAtom;
|
||||
KWayland::Client::DataDeviceManager::DnDAction m_action = KWayland::Client::DataDeviceManager::DnDAction::None;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction m_action = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
|
||||
|
||||
bool m_mapped = false;
|
||||
bool m_entered = false;
|
||||
|
|
|
@ -13,11 +13,6 @@
|
|||
#include "atoms.h"
|
||||
#include "wayland_server.h"
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/datadevicemanager.h>
|
||||
#include <KWayland/Client/datadevice.h>
|
||||
#include <KWayland/Client/datasource.h>
|
||||
|
||||
#include <KWaylandServer/datadevice_interface.h>
|
||||
#include <KWaylandServer/datasource_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
|
@ -51,9 +46,13 @@ void WlSource::setDataSourceIface(KWaylandServer::AbstractDataSource *dsi)
|
|||
for (const auto &mime : dsi->mimeTypes()) {
|
||||
m_offers << mime;
|
||||
}
|
||||
|
||||
// TODO, this can probably be removed after some testing
|
||||
// all mime types should be constant after a data source is set
|
||||
m_offerConnection = connect(dsi,
|
||||
&KWaylandServer::DataSourceInterface::mimeTypeOffered,
|
||||
this, &WlSource::receiveOffer);
|
||||
|
||||
m_dsi = dsi;
|
||||
}
|
||||
|
||||
|
@ -155,7 +154,6 @@ bool WlSource::checkStartTransfer(xcb_selection_request_event_t *event)
|
|||
}
|
||||
|
||||
m_dsi->requestData(*mimeIt, p[1]);
|
||||
waylandServer()->dispatch();
|
||||
|
||||
Q_EMIT transferReady(new xcb_selection_request_event_t(*event), p[0]);
|
||||
return true;
|
||||
|
@ -250,26 +248,8 @@ void X11Source::handleTargets()
|
|||
free(reply);
|
||||
}
|
||||
|
||||
void X11Source::setDataSource(KWayland::Client::DataSource *dataSource)
|
||||
{
|
||||
Q_ASSERT(dataSource);
|
||||
if (m_dataSource) {
|
||||
delete m_dataSource;
|
||||
}
|
||||
|
||||
m_dataSource = dataSource;
|
||||
|
||||
for (const Mime &offer : qAsConst(m_offers)) {
|
||||
dataSource->offer(offer.first);
|
||||
}
|
||||
|
||||
connect(dataSource, &KWayland::Client::DataSource::sendDataRequested,
|
||||
this, &X11Source::startTransfer);
|
||||
}
|
||||
|
||||
void X11Source::setOffers(const Mimes &offers)
|
||||
{
|
||||
// TODO: share code with handleTargets and emit signals accordingly?
|
||||
m_offers = offers;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,6 @@ class QSocketNotifier;
|
|||
struct xcb_selection_request_event_t;
|
||||
struct xcb_xfixes_selection_notify_event_t;
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class DataSource;
|
||||
}
|
||||
}
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class DataDeviceInterface;
|
||||
|
@ -119,16 +112,6 @@ class X11Source : public SelectionSource
|
|||
public:
|
||||
X11Source(Selection *selection, xcb_xfixes_selection_notify_event_t *event);
|
||||
|
||||
/**
|
||||
* @param ds must exist.
|
||||
*
|
||||
* X11Source does not take ownership of it in general, but if the function
|
||||
* is called again, it will delete the previous data source.
|
||||
*/
|
||||
void setDataSource(KWayland::Client::DataSource *dataSource);
|
||||
KWayland::Client::DataSource *dataSource() const {
|
||||
return m_dataSource;
|
||||
}
|
||||
void getTargets();
|
||||
|
||||
Mimes offers() const {
|
||||
|
@ -151,7 +134,6 @@ private:
|
|||
void handleTargets();
|
||||
|
||||
xcb_window_t m_owner;
|
||||
KWayland::Client::DataSource *m_dataSource = nullptr;
|
||||
|
||||
Mimes m_offers;
|
||||
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/datadevicemanager.h>
|
||||
#include <KWayland/Client/datadevice.h>
|
||||
#include <KWayland/Client/datasource.h>
|
||||
|
||||
#include <KWaylandServer/datadevice_interface.h>
|
||||
#include <KWaylandServer/datasource_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
|
|
Loading…
Reference in a new issue