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