Remove Wayland::Client usage in wl->xwl drags
This commit is contained in:
parent
6c97cd118d
commit
4a16e18808
6 changed files with 103 additions and 101 deletions
|
@ -44,33 +44,5 @@ void Drag::sendClientMessage(xcb_window_t target, xcb_atom_t type, xcb_client_me
|
|||
xcb_flush(xcbConn);
|
||||
}
|
||||
|
||||
DnDAction Drag::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 Drag::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
|
||||
|
|
|
@ -9,9 +9,8 @@
|
|||
#ifndef KWIN_XWL_DRAG
|
||||
#define KWIN_XWL_DRAG
|
||||
|
||||
#include <KWayland/Client/datadevicemanager.h>
|
||||
|
||||
#include <QPoint>
|
||||
#include <QObject>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
|
@ -23,8 +22,6 @@ namespace Xwl
|
|||
{
|
||||
enum class DragEventReply;
|
||||
|
||||
using DnDAction = KWayland::Client::DataDeviceManager::DnDAction;
|
||||
|
||||
/**
|
||||
* An ongoing drag operation.
|
||||
*/
|
||||
|
@ -37,8 +34,6 @@ public:
|
|||
~Drag() override;
|
||||
|
||||
static void sendClientMessage(xcb_window_t target, xcb_atom_t type, xcb_client_message_data_t *data);
|
||||
static DnDAction atomToClientAction(xcb_atom_t atom);
|
||||
static xcb_atom_t clientActionToAtom(DnDAction action);
|
||||
|
||||
virtual bool handleClientMessage(xcb_client_message_event_t *event) = 0;
|
||||
virtual DragEventReply moveFilter(Toplevel *target, const QPoint &pos) = 0;
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <KWayland/Client/datadevice.h>
|
||||
#include <KWayland/Client/datasource.h>
|
||||
|
||||
#include <KWaylandServer/datasource_interface.h>
|
||||
#include <KWaylandServer/datadevice_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
|
@ -33,6 +30,37 @@ namespace KWin
|
|||
namespace Xwl
|
||||
{
|
||||
|
||||
using DnDAction = KWaylandServer::DataDeviceManagerInterface::DnDAction;
|
||||
using DnDActions = KWaylandServer::DataDeviceManagerInterface::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;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
WlToXDrag::WlToXDrag()
|
||||
{
|
||||
m_dsi = waylandServer()->seat()->dragSource()->dragSource();
|
||||
|
@ -129,12 +157,8 @@ Xvisit::Xvisit(WlToXDrag *drag, AbstractClient *target)
|
|||
}
|
||||
free(reply);
|
||||
|
||||
const auto *dd = DataBridge::self()->dataDevice();
|
||||
// proxy drop
|
||||
m_enterConnection = connect(dd, &KWayland::Client::DataDevice::dragEntered,
|
||||
this, &Xvisit::receiveOffer);
|
||||
m_dropConnection = connect(dd, &KWayland::Client::DataDevice::dropped,
|
||||
this, &Xvisit::drop);
|
||||
m_dropConnection = connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::dragDropped, this, &Xvisit::drop);
|
||||
receiveOffer();
|
||||
}
|
||||
|
||||
bool Xvisit::handleClientMessage(xcb_client_message_event_t *event)
|
||||
|
@ -158,9 +182,9 @@ bool Xvisit::handleStatus(xcb_client_message_event_t *event)
|
|||
m_accepts = data->data32[1] & 1;
|
||||
xcb_atom_t actionAtom = data->data32[4];
|
||||
|
||||
auto drag = m_drag->dataSourceIface();
|
||||
if (drag && !drag->mimeTypes().isEmpty()) {
|
||||
drag->accept(m_accepts ? drag->mimeTypes().constFirst() : QString());
|
||||
auto dataSource = m_drag->dataSourceIface();
|
||||
if (dataSource && !dataSource->mimeTypes().isEmpty()) {
|
||||
dataSource->accept(m_accepts ? dataSource->mimeTypes().constFirst() : QString());
|
||||
}
|
||||
// TODO: we could optimize via rectangle in data32[2] and data32[3]
|
||||
|
||||
|
@ -169,7 +193,7 @@ bool Xvisit::handleStatus(xcb_client_message_event_t *event)
|
|||
|
||||
if (!m_state.dropped) {
|
||||
// as long as the drop is not yet done determine requested action
|
||||
m_preferredAction = Drag::atomToClientAction(actionAtom);
|
||||
m_preferredAction = atomToClientAction(actionAtom);
|
||||
determineProposedAction();
|
||||
requestDragAndDropAction();
|
||||
}
|
||||
|
@ -206,11 +230,8 @@ bool Xvisit::handleFinished(xcb_client_message_event_t *event)
|
|||
Q_UNUSED(success);
|
||||
Q_UNUSED(usedActionAtom);
|
||||
|
||||
// data offer might have been deleted already by the DataDevice
|
||||
if (!m_dataOffer.isNull()) {
|
||||
m_dataOffer->dragAndDropFinished();
|
||||
delete m_dataOffer;
|
||||
m_dataOffer = nullptr;
|
||||
if (auto dataSource = m_drag->dataSourceIface()) {
|
||||
dataSource->dndFinished();
|
||||
}
|
||||
doFinish();
|
||||
return true;
|
||||
|
@ -232,14 +253,17 @@ void Xvisit::sendPosition(const QPointF &globalPos)
|
|||
data.data32[0] = DataBridge::self()->dnd()->window();
|
||||
data.data32[2] = (x << 16) | y;
|
||||
data.data32[3] = XCB_CURRENT_TIME;
|
||||
data.data32[4] = Drag::clientActionToAtom(m_proposedAction);
|
||||
data.data32[4] = clientActionToAtom(m_proposedAction);
|
||||
|
||||
Drag::sendClientMessage(m_target->window(), atoms->xdnd_position, &data);
|
||||
}
|
||||
|
||||
void Xvisit::leave()
|
||||
{
|
||||
Q_ASSERT(!m_state.dropped);
|
||||
if (m_state.dropped) {
|
||||
// dropped, but not yet finished, it'll be cleaned up when the drag finishes
|
||||
return;
|
||||
}
|
||||
if (m_state.finished) {
|
||||
// was already finished
|
||||
return;
|
||||
|
@ -253,17 +277,9 @@ void Xvisit::leave()
|
|||
|
||||
void Xvisit::receiveOffer()
|
||||
{
|
||||
if (m_state.finished) {
|
||||
// already ended
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(m_dataOffer.isNull());
|
||||
m_dataOffer = DataBridge::self()->dataDevice()->dragOffer();
|
||||
Q_ASSERT(!m_dataOffer.isNull());
|
||||
|
||||
retrieveSupportedActions();
|
||||
m_actionConnection = connect(m_dataOffer, &KWayland::Client::DataOffer::sourceDragAndDropActionsChanged,
|
||||
auto dragSource = m_drag->dataSourceIface();
|
||||
connect(dragSource, &KWaylandServer::AbstractDataSource::supportedDragAndDropActionsChanged,
|
||||
this, &Xvisit::retrieveSupportedActions);
|
||||
enter();
|
||||
}
|
||||
|
@ -283,8 +299,8 @@ void Xvisit::enter()
|
|||
|
||||
void Xvisit::sendEnter()
|
||||
{
|
||||
auto drag = m_drag->dataSourceIface();
|
||||
if (!drag) {
|
||||
auto dataSource = m_drag->dataSourceIface();
|
||||
if (!dataSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -292,9 +308,7 @@ void Xvisit::sendEnter()
|
|||
data.data32[0] = DataBridge::self()->dnd()->window();
|
||||
data.data32[1] = m_version << 24;
|
||||
|
||||
// TODO: replace this with the mime type getter from m_dataOffer,
|
||||
// then we can get rid of m_drag.
|
||||
const auto mimeTypesNames = drag->mimeTypes();
|
||||
const auto mimeTypesNames = dataSource->mimeTypes();
|
||||
const int mimesCount = mimeTypesNames.size();
|
||||
size_t cnt = 0;
|
||||
size_t totalCnt = 0;
|
||||
|
@ -363,7 +377,7 @@ void Xvisit::sendLeave()
|
|||
|
||||
void Xvisit::retrieveSupportedActions()
|
||||
{
|
||||
m_supportedActions = m_dataOffer->sourceDragAndDropActions();
|
||||
m_supportedActions = m_drag->dataSourceIface()->supportedDragAndDropActions();
|
||||
determineProposedAction();
|
||||
requestDragAndDropAction();
|
||||
}
|
||||
|
@ -386,16 +400,22 @@ void Xvisit::determineProposedAction()
|
|||
|
||||
void Xvisit::requestDragAndDropAction()
|
||||
{
|
||||
if (m_dataOffer.isNull()) {
|
||||
return;
|
||||
}
|
||||
const auto pref = m_preferredAction != DnDAction::None ? m_preferredAction:
|
||||
DnDAction action = m_preferredAction != DnDAction::None ? m_preferredAction:
|
||||
DnDAction::Copy;
|
||||
// we assume the X client supports Move, but this might be wrong - then
|
||||
// the drag just cancels, if the user tries to force it.
|
||||
|
||||
m_dataOffer->setDragAndDropActions(DnDAction::Copy | DnDAction::Move, pref);
|
||||
waylandServer()->dispatch();
|
||||
// As we skip the client data device, we do action negotiation directly then tell the source.
|
||||
if (m_supportedActions.testFlag(action)) {
|
||||
// everything is supported, no changes are needed
|
||||
} else if (m_supportedActions.testFlag(DnDAction::Copy)) {
|
||||
action = DnDAction::Copy;
|
||||
} else if (m_supportedActions.testFlag(DnDAction::Move)) {
|
||||
action = DnDAction::Move;
|
||||
}
|
||||
if (auto dataSource = m_drag->dataSourceIface()) {
|
||||
dataSource->dndAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
void Xvisit::drop()
|
||||
|
|
|
@ -11,19 +11,12 @@
|
|||
|
||||
#include "drag.h"
|
||||
|
||||
#include <KWayland/Client/dataoffer.h>
|
||||
#include <KWaylandServer/datadevicemanager_interface.h>
|
||||
|
||||
#include <QPoint>
|
||||
#include <QPointer>
|
||||
#include <QVector>
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class Surface;
|
||||
}
|
||||
}
|
||||
namespace KWaylandServer
|
||||
{
|
||||
class DataDeviceInterface;
|
||||
|
@ -42,8 +35,6 @@ class X11Source;
|
|||
enum class DragEventReply;
|
||||
class Xvisit;
|
||||
|
||||
using DnDActions = KWayland::Client::DataDeviceManager::DnDActions;
|
||||
|
||||
class WlToXDrag : public Drag
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -125,16 +116,12 @@ private:
|
|||
QPoint cache;
|
||||
} m_pos;
|
||||
|
||||
// Must be QPointer, because KWayland::Client::DataDevice
|
||||
// might delete it.
|
||||
QPointer<KWayland::Client::DataOffer> m_dataOffer;
|
||||
|
||||
// supported by the Wl source
|
||||
DnDActions m_supportedActions = DnDAction::None;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDActions m_supportedActions = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
|
||||
// preferred by the X client
|
||||
DnDAction m_preferredAction = DnDAction::None;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction m_preferredAction = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
|
||||
// decided upon by the compositor
|
||||
DnDAction m_proposedAction = DnDAction::None;
|
||||
KWaylandServer::DataDeviceManagerInterface::DnDAction m_proposedAction = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
|
||||
|
||||
struct {
|
||||
bool entered = false;
|
||||
|
|
|
@ -33,6 +33,37 @@ 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;
|
||||
}
|
||||
|
||||
static QStringList atomToMimeTypes(xcb_atom_t atom)
|
||||
{
|
||||
QStringList mimeTypes;
|
||||
|
@ -438,7 +469,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 = Drag::atomToClientAction(actionAtom);
|
||||
auto action = atomToClientAction(actionAtom);
|
||||
|
||||
if (action == DnDAction::None) {
|
||||
// copy action is always possible in XDND
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
#include "drag.h"
|
||||
|
||||
#include <KWayland/Client/datadevicemanager.h>
|
||||
#include <KWayland/Client/dataoffer.h>
|
||||
|
||||
#include <KWaylandServer/datadevicemanager_interface.h>
|
||||
|
||||
#include <QPoint>
|
||||
#include <QPointer>
|
||||
|
@ -52,8 +49,8 @@ public:
|
|||
DragEventReply moveFilter(Toplevel *target, const QPoint &pos) override;
|
||||
bool handleClientMessage(xcb_client_message_event_t *event) override;
|
||||
|
||||
void setDragAndDropAction(DnDAction action);
|
||||
DnDAction selectedDragAndDropAction();
|
||||
void setDragAndDropAction(KWayland::Client::DataDeviceManager::DnDAction action);
|
||||
KWayland::Client::DataDeviceManager::DnDAction selectedDragAndDropAction();
|
||||
|
||||
bool end() override {
|
||||
return false;
|
||||
|
@ -81,7 +78,7 @@ private:
|
|||
QVector<WlVisit *> m_oldVisits;
|
||||
|
||||
bool m_performed = false;
|
||||
DnDAction m_lastSelectedDragAndDropAction = DnDAction::None;
|
||||
KWayland::Client::DataDeviceManager::DnDAction m_lastSelectedDragAndDropAction = KWayland::Client::DataDeviceManager::DnDAction::None;
|
||||
|
||||
Q_DISABLE_COPY(XToWlDrag)
|
||||
};
|
||||
|
@ -142,7 +139,7 @@ private:
|
|||
uint32_t m_version = 0;
|
||||
|
||||
xcb_atom_t m_actionAtom;
|
||||
DnDAction m_action = DnDAction::None;
|
||||
KWayland::Client::DataDeviceManager::DnDAction m_action = KWayland::Client::DataDeviceManager::DnDAction::None;
|
||||
|
||||
bool m_mapped = false;
|
||||
bool m_entered = false;
|
||||
|
|
Loading…
Reference in a new issue