databridge: move global to Xwayland
This commit is contained in:
parent
fde7d44941
commit
53815e2b28
11 changed files with 56 additions and 52 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue