databridge: move global to Xwayland

This commit is contained in:
Xaver Hugl 2022-08-03 12:07:09 +02:00
parent fde7d44941
commit 53815e2b28
11 changed files with 56 additions and 52 deletions

View file

@ -29,25 +29,11 @@ namespace KWin
namespace Xwl
{
KWIN_SINGLETON_FACTORY(DataBridge)
void DataBridge::destroy()
DataBridge::DataBridge()
{
delete s_self;
}
DataBridge::DataBridge(QObject *parent)
: QObject(parent)
{
s_self = this;
init();
}
DataBridge::~DataBridge()
{
s_self = nullptr;
}
void DataBridge::init()
{
m_clipboard = new Clipboard(atoms->clipboard, this);

View file

@ -43,9 +43,7 @@ class DataBridge : public QObject, public QAbstractNativeEventFilter
Q_OBJECT
public:
static void destroy();
~DataBridge() override;
explicit DataBridge();
DragEventReply dragMoveFilter(Window *target, const QPoint &pos);
@ -66,8 +64,6 @@ private:
Clipboard *m_clipboard = nullptr;
Dnd *m_dnd = nullptr;
Primary *m_primary = nullptr;
KWIN_SINGLETON(DataBridge)
};
} // namespace Xwl

View file

@ -47,7 +47,7 @@ XwlDropHandler *Dnd::dropHandler() const
Dnd::Dnd(xcb_atom_t atom, QObject *parent)
: Selection(atom, parent)
, m_dropHandler(new XwlDropHandler)
, m_dropHandler(new XwlDropHandler(this))
{
xcb_connection_t *xcbConn = kwinApp()->x11Connection();
@ -110,7 +110,7 @@ void Dnd::doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event)
if (!source) {
return;
}
m_currentDrag = new XToWlDrag(source);
m_currentDrag = new XToWlDrag(source, this);
}
void Dnd::x11OffersChanged(const QStringList &added, const QStringList &removed)
@ -149,7 +149,7 @@ void Dnd::startDrag()
Q_ASSERT(!m_currentDrag);
// New Wl to X drag, init drag and Wl source.
m_currentDrag = new WlToXDrag();
m_currentDrag = new WlToXDrag(this);
auto source = new WlSource(this);
source->setDataSourceIface(dragSource);
connect(dragSource, &KWaylandServer::AbstractDataSource::aboutToBeDestroyed, this, [this, source] {

View file

@ -35,6 +35,11 @@ namespace KWin
namespace Xwl
{
WlToXDrag::WlToXDrag(Dnd *dnd)
: m_dnd(dnd)
{
}
DragEventReply WlToXDrag::moveFilter(Window *target, const QPoint &pos)
{
Q_UNUSED(target)
@ -44,11 +49,12 @@ DragEventReply WlToXDrag::moveFilter(Window *target, const QPoint &pos)
bool WlToXDrag::handleClientMessage(xcb_client_message_event_t *event)
{
return DataBridge::self()->dnd()->dropHandler()->handleClientMessage(event);
return m_dnd->dropHandler()->handleClientMessage(event);
}
Xvisit::Xvisit(Window *target, KWaylandServer::AbstractDataSource *dataSource, QObject *parent)
Xvisit::Xvisit(Window *target, KWaylandServer::AbstractDataSource *dataSource, Dnd *dnd, QObject *parent)
: QObject(parent)
, m_dnd(dnd)
, m_target(target)
, m_dataSource(dataSource)
{
@ -170,7 +176,7 @@ void Xvisit::sendPosition(const QPointF &globalPos)
m_pos.pending = true;
xcb_client_message_data_t data = {};
data.data32[0] = DataBridge::self()->dnd()->window();
data.data32[0] = m_dnd->window();
data.data32[2] = (x << 16) | y;
data.data32[3] = XCB_CURRENT_TIME;
data.data32[4] = Dnd::clientActionToAtom(m_proposedAction);
@ -223,7 +229,7 @@ void Xvisit::sendEnter()
}
xcb_client_message_data_t data = {};
data.data32[0] = DataBridge::self()->dnd()->window();
data.data32[0] = m_dnd->window();
data.data32[1] = m_version << 24;
const auto mimeTypesNames = m_dataSource->mimeTypes();
@ -267,7 +273,7 @@ void Xvisit::sendEnter()
xcb_change_property(kwinApp()->x11Connection(),
XCB_PROP_MODE_REPLACE,
DataBridge::self()->dnd()->window(),
m_dnd->window(),
atoms->xdnd_type_list,
XCB_ATOM_ATOM,
32, cnt, targets.data());
@ -278,7 +284,7 @@ void Xvisit::sendEnter()
void Xvisit::sendDrop(uint32_t time)
{
xcb_client_message_data_t data = {};
data.data32[0] = DataBridge::self()->dnd()->window();
data.data32[0] = m_dnd->window();
data.data32[2] = time;
Drag::sendClientMessage(m_target->window(), atoms->xdnd_drop, &data);
@ -291,7 +297,7 @@ void Xvisit::sendDrop(uint32_t time)
void Xvisit::sendLeave()
{
xcb_client_message_data_t data = {};
data.data32[0] = DataBridge::self()->dnd()->window();
data.data32[0] = m_dnd->window();
Drag::sendClientMessage(m_target->window(), atoms->xdnd_leave, &data);
}

View file

@ -33,6 +33,7 @@ namespace Xwl
class X11Source;
enum class DragEventReply;
class Xvisit;
class Dnd;
class WlToXDrag : public Drag
{
@ -40,10 +41,12 @@ class WlToXDrag : public Drag
using Drag::Drag;
public:
explicit WlToXDrag(Dnd *dnd);
DragEventReply moveFilter(Window *target, const QPoint &pos) override;
bool handleClientMessage(xcb_client_message_event_t *event) override;
private:
Dnd *const m_dnd;
Q_DISABLE_COPY(WlToXDrag)
};
@ -55,7 +58,7 @@ class Xvisit : public QObject
public:
// TODO: handle ask action
Xvisit(Window *target, KWaylandServer::AbstractDataSource *dataSource, QObject *parent);
Xvisit(Window *target, KWaylandServer::AbstractDataSource *dataSource, Dnd *dnd, QObject *parent);
bool handleClientMessage(xcb_client_message_event_t *event);
bool handleStatus(xcb_client_message_event_t *event);
@ -92,6 +95,7 @@ private:
void doFinish();
void stopConnections();
Dnd *const m_dnd;
Window *m_target;
QPointer<KWaylandServer::AbstractDataSource> m_dataSource;
uint32_t m_version = 0;

View file

@ -54,10 +54,11 @@ static QStringList atomToMimeTypes(xcb_atom_t atom)
return mimeTypes;
}
XToWlDrag::XToWlDrag(X11Source *source)
: m_source(source)
XToWlDrag::XToWlDrag(X11Source *source, Dnd *dnd)
: m_dnd(dnd)
, m_source(source)
{
connect(DataBridge::self()->dnd(), &Dnd::transferFinished, this, [this](xcb_timestamp_t eventTime) {
connect(m_dnd, &Dnd::transferFinished, this, [this](xcb_timestamp_t eventTime) {
// we use this mechanism, because the finished call is not
// reliable done by Wayland clients
auto it = std::find_if(m_dataRequests.begin(), m_dataRequests.end(), [eventTime](const QPair<xcb_timestamp_t, bool> &req) {
@ -154,7 +155,7 @@ DragEventReply XToWlDrag::moveFilter(Window *target, const QPoint &pos)
}
// new Wl native target
auto *ac = static_cast<Window *>(target);
m_visit = new WlVisit(ac, this);
m_visit = new WlVisit(ac, this, m_dnd);
connect(m_visit, &WlVisit::offersReceived, this, &XToWlDrag::setOffers);
return DragEventReply::Ignore;
}
@ -252,15 +253,16 @@ bool XToWlDrag::checkForFinished()
return transfersFinished;
}
WlVisit::WlVisit(Window *target, XToWlDrag *drag)
WlVisit::WlVisit(Window *target, XToWlDrag *drag, Dnd *dnd)
: QObject(drag)
, m_dnd(dnd)
, m_target(target)
, m_drag(drag)
{
xcb_connection_t *xcbConn = kwinApp()->x11Connection();
m_window = xcb_generate_id(xcbConn);
DataBridge::self()->dnd()->overwriteRequestorWindow(m_window);
m_dnd->overwriteRequestorWindow(m_window);
const uint32_t dndValues[] = {XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE};
xcb_create_window(xcbConn,
@ -300,7 +302,7 @@ WlVisit::~WlVisit()
bool WlVisit::leave()
{
DataBridge::self()->dnd()->overwriteRequestorWindow(XCB_WINDOW_NONE);
m_dnd->overwriteRequestorWindow(XCB_WINDOW_NONE);
unmapProxyWindow();
return m_finished;
}

View file

@ -27,6 +27,7 @@ namespace Xwl
class X11Source;
enum class DragEventReply;
class WlVisit;
class Dnd;
using Mimes = QVector<QPair<QString, xcb_atom_t>>;
@ -35,7 +36,7 @@ class XToWlDrag : public Drag
Q_OBJECT
public:
explicit XToWlDrag(X11Source *source);
explicit XToWlDrag(X11Source *source, Dnd *dnd);
~XToWlDrag() override;
DragEventReply moveFilter(Window *target, const QPoint &pos) override;
@ -55,6 +56,7 @@ private:
bool checkForFinished();
Dnd *const m_dnd;
Mimes m_offers;
XwlDataSource m_selectionSource;
@ -76,7 +78,7 @@ class WlVisit : public QObject
Q_OBJECT
public:
WlVisit(Window *target, XToWlDrag *drag);
WlVisit(Window *target, XToWlDrag *drag, Dnd *dnd);
~WlVisit() override;
bool handleClientMessage(xcb_client_message_event_t *event);
@ -123,6 +125,7 @@ private:
void doFinish();
void unmapProxyWindow();
Dnd *const m_dnd;
Window *m_target;
xcb_window_t m_window;

View file

@ -159,7 +159,7 @@ void Xwayland::handleXwaylandFinished()
// events will be dispatched before blocking; otherwise we will simply hang...
uninstallSocketNotifier();
DataBridge::destroy();
m_dataBridge.reset();
m_selectionOwner.reset();
destroyX11Connection();
@ -189,7 +189,7 @@ void Xwayland::handleXwaylandReady()
Xcb::defineCursor(kwinApp()->x11RootWindow(), mouseCursor->x11Cursor(Qt::ArrowCursor));
}
DataBridge::create(this);
m_dataBridge = std::make_unique<DataBridge>();
auto env = m_app->processStartupEnvironment();
env.insert(QStringLiteral("DISPLAY"), m_launcher->displayName());
@ -296,20 +296,20 @@ void Xwayland::destroyX11Connection()
DragEventReply Xwayland::dragMoveFilter(Window *target, const QPoint &pos)
{
DataBridge *bridge = DataBridge::self();
if (!bridge) {
if (m_dataBridge) {
return m_dataBridge->dragMoveFilter(target, pos);
} else {
return DragEventReply::Wayland;
}
return bridge->dragMoveFilter(target, pos);
}
KWaylandServer::AbstractDropHandler *Xwayland::xwlDropHandler()
{
DataBridge *bridge = DataBridge::self();
if (bridge) {
return bridge->dnd()->dropHandler();
if (m_dataBridge) {
return m_dataBridge->dnd()->dropHandler();
} else {
return nullptr;
}
return nullptr;
}
} // namespace Xwl

View file

@ -14,6 +14,8 @@
#include "xwayland_interface.h"
#include <memory>
class KSelectionOwner;
class QSocketNotifier;
@ -26,6 +28,7 @@ namespace Xwl
{
class XrandrEventFilter;
class XwaylandLauncher;
class DataBridge;
class KWIN_EXPORT Xwayland : public XwaylandInterface
{
@ -76,6 +79,7 @@ private:
Application *m_app;
std::unique_ptr<KSelectionOwner> m_selectionOwner;
std::unique_ptr<DataBridge> m_dataBridge;
XrandrEventFilter *m_xrandrEventsFilter = nullptr;
XwaylandLauncher *m_launcher;

View file

@ -20,8 +20,9 @@
namespace KWin::Xwl
{
XwlDropHandler::XwlDropHandler()
XwlDropHandler::XwlDropHandler(Dnd *dnd)
: KWaylandServer::AbstractDropHandler(nullptr)
, m_dnd(dnd)
{
}
@ -70,7 +71,7 @@ void XwlDropHandler::updateDragTarget(KWaylandServer::SurfaceInterface *surface,
m_xvisit = nullptr;
}
if (client) {
m_xvisit = new Xvisit(client, waylandServer()->seat()->dragSource(), this);
m_xvisit = new Xvisit(client, waylandServer()->seat()->dragSource(), m_dnd, this);
}
}
}

View file

@ -21,12 +21,13 @@ namespace Xwl
{
class Xvisit;
class Dnd;
class XwlDropHandler : public KWaylandServer::AbstractDropHandler
{
Q_OBJECT
public:
XwlDropHandler();
XwlDropHandler(Dnd *dnd);
void updateDragTarget(KWaylandServer::SurfaceInterface *surface, quint32 serial) override;
bool handleClientMessage(xcb_client_message_event_t *event);
@ -34,6 +35,7 @@ public:
private:
void drop() override;
Xvisit *m_xvisit = nullptr;
Dnd *const m_dnd;
QVector<Xvisit *> m_previousVisits;
};
}