Skip to content

Commit

Permalink
core: make selection source/offer use CFileDescriptor
Browse files Browse the repository at this point in the history
make data selection source and offers use CFileDescriptor and its
associated use in xwm and protocols
  • Loading branch information
gulafaran committed Jan 22, 2025
1 parent cbb22cf commit 808d8b7
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 58 deletions.
11 changes: 4 additions & 7 deletions src/protocols/DataDeviceWlr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,20 @@ CWLRDataOffer::CWLRDataOffer(SP<CZwlrDataControlOfferV1> resource_, SP<IDataSour
resource->setOnDestroy([this](CZwlrDataControlOfferV1* r) { PROTO::dataWlr->destroyResource(this); });

resource->setReceive([this](CZwlrDataControlOfferV1* r, const char* mime, int32_t fd) {
Hyprutils::OS::CFileDescriptor sendFd(fd);
if (!source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
close(fd);
return;
}

if (dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
close(fd);
return;
}

LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get());

source->send(mime, fd);
source->send(mime, std::move(sendFd));
});
}

Expand Down Expand Up @@ -77,15 +76,13 @@ std::vector<std::string> CWLRDataSource::mimes() {
return mimeTypes;
}

void CWLRDataSource::send(const std::string& mime, uint32_t fd) {
void CWLRDataSource::send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CWLRDataSource::sendAskSend with non-existent mime");
close(fd);
return;
}

resource->sendSend(mime.c_str(), fd);
close(fd);
resource->sendSend(mime.c_str(), fd.get());
}

void CWLRDataSource::accepted(const std::string& mime) {
Expand Down
3 changes: 2 additions & 1 deletion src/protocols/DataDeviceWlr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "WaylandProtocol.hpp"
#include "wlr-data-control-unstable-v1.hpp"
#include "types/DataDevice.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CWLRDataControlManagerResource;
class CWLRDataSource;
Expand Down Expand Up @@ -39,7 +40,7 @@ class CWLRDataSource : public IDataSource {
bool good();

virtual std::vector<std::string> mimes();
virtual void send(const std::string& mime, uint32_t fd);
virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
Expand Down
11 changes: 4 additions & 7 deletions src/protocols/PrimarySelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,20 @@ CPrimarySelectionOffer::CPrimarySelectionOffer(SP<CZwpPrimarySelectionOfferV1> r
resource->setOnDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); });

resource->setReceive([this](CZwpPrimarySelectionOfferV1* r, const char* mime, int32_t fd) {
Hyprutils::OS::CFileDescriptor sendFd(fd);
if (!source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
close(fd);
return;
}

if (dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
close(fd);
return;
}

LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get());

source->send(mime, fd);
source->send(mime, std::move(sendFd));
});
}

Expand Down Expand Up @@ -78,15 +77,13 @@ std::vector<std::string> CPrimarySelectionSource::mimes() {
return mimeTypes;
}

void CPrimarySelectionSource::send(const std::string& mime, uint32_t fd) {
void CPrimarySelectionSource::send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CPrimarySelectionSource::sendAskSend with non-existent mime");
close(fd);
return;
}

resource->sendSend(mime.c_str(), fd);
close(fd);
resource->sendSend(mime.c_str(), fd.get());
}

void CPrimarySelectionSource::accepted(const std::string& mime) {
Expand Down
3 changes: 2 additions & 1 deletion src/protocols/PrimarySelection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "WaylandProtocol.hpp"
#include "primary-selection-unstable-v1.hpp"
#include "types/DataDevice.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CPrimarySelectionOffer;
class CPrimarySelectionSource;
Expand Down Expand Up @@ -39,7 +40,7 @@ class CPrimarySelectionSource : public IDataSource {
bool good();

virtual std::vector<std::string> mimes();
virtual void send(const std::string& mime, uint32_t fd);
virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
Expand Down
11 changes: 4 additions & 7 deletions src/protocols/core/DataDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@ CWLDataOfferResource::CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataS
});

resource->setReceive([this](CWlDataOffer* r, const char* mime, uint32_t fd) {
Hyprutils::OS::CFileDescriptor sendFd(fd);
if (!source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
close(fd);
return;
}

if (dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
close(fd);
return;
}

Expand All @@ -58,7 +57,7 @@ CWLDataOfferResource::CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataS
source->accepted(mime ? mime : "");
}

source->send(mime ? mime : "", fd);
source->send(mime ? mime : "", std::move(sendFd));

recvd = true;

Expand Down Expand Up @@ -182,15 +181,13 @@ std::vector<std::string> CWLDataSourceResource::mimes() {
return mimeTypes;
}

void CWLDataSourceResource::send(const std::string& mime, uint32_t fd) {
void CWLDataSourceResource::send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CWLDataSourceResource::sendAskSend with non-existent mime");
close(fd);
return;
}

resource->sendSend(mime.c_str(), fd);
close(fd);
resource->sendSend(mime.c_str(), fd.get());
}

void CWLDataSourceResource::cancelled() {
Expand Down
3 changes: 2 additions & 1 deletion src/protocols/core/DataDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../types/DataDevice.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CWLDataDeviceResource;
class CWLDataDeviceManagerResource;
Expand Down Expand Up @@ -64,7 +65,7 @@ class CWLDataSourceResource : public IDataSource {
bool good();

virtual std::vector<std::string> mimes();
virtual void send(const std::string& mime, uint32_t fd);
virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual bool hasDnd();
Expand Down
9 changes: 5 additions & 4 deletions src/protocols/types/DataDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <wayland-server-protocol.h>
#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/math/Math.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

class CWLDataOfferResource;
class CX11DataOffer;
Expand All @@ -24,10 +25,10 @@ class IDataSource {
IDataSource() = default;
virtual ~IDataSource() = default;

virtual std::vector<std::string> mimes() = 0;
virtual void send(const std::string& mime, uint32_t fd) = 0;
virtual void accepted(const std::string& mime) = 0;
virtual void cancelled() = 0;
virtual std::vector<std::string> mimes() = 0;
virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) = 0;
virtual void accepted(const std::string& mime) = 0;
virtual void cancelled() = 0;
virtual bool hasDnd();
virtual bool dndDone();
virtual void sendDndFinished();
Expand Down
12 changes: 6 additions & 6 deletions src/xwayland/XDataSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ std::vector<std::string> CXDataSource::mimes() {
return mimeTypes;
}

void CXDataSource::send(const std::string& mime, uint32_t fd) {
void CXDataSource::send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd) {
xcb_atom_t mimeAtom = 0;

if (mime == "text/plain")
Expand All @@ -64,11 +64,10 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) {

if (!mimeAtom) {
Debug::log(ERR, "[XDataSource] mime atom not found");
close(fd);
return;
}

Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd);
Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get());

selection.transfer = std::make_unique<SXTransfer>(selection);
selection.transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection);
Expand All @@ -80,8 +79,9 @@ void CXDataSource::send(const std::string& mime, uint32_t fd) {

xcb_flush(g_pXWayland->pWM->connection);

fcntl(fd, F_SETFL, O_WRONLY | O_NONBLOCK);
selection.transfer->wlFD = fd;
//TODO: make CFileDescriptor setflags take SETFL aswell
fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK);
selection.transfer->wlFD = std::move(fd);
}

void CXDataSource::accepted(const std::string& mime) {
Expand All @@ -100,4 +100,4 @@ eDataSourceType CXDataSource::type() {
return DATA_SOURCE_TYPE_X11;
}

#endif
#endif
5 changes: 3 additions & 2 deletions src/xwayland/XDataSource.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "../protocols/types/DataDevice.hpp"
#include <hyprutils/os/FileDescriptor.hpp>

struct SXSelection;

Expand All @@ -9,7 +10,7 @@ class CXDataSource : public IDataSource {
CXDataSource(SXSelection&);

virtual std::vector<std::string> mimes();
virtual void send(const std::string& mime, uint32_t fd);
virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
virtual void accepted(const std::string& mime);
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
Expand All @@ -19,4 +20,4 @@ class CXDataSource : public IDataSource {
SXSelection& selection;
std::vector<std::string> mimeTypes; // these two have shared idx
std::vector<uint32_t> mimeAtoms; //
};
};
13 changes: 4 additions & 9 deletions src/xwayland/XWM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1175,17 +1175,15 @@ void CXWM::getTransferData(SXSelection& sel) {

if (sel.transfer->propertyReply->type == HYPRATOMS["INCR"]) {
Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :(");
close(sel.transfer->wlFD);
sel.transfer.reset();
return;
} else {
char* property = (char*)xcb_get_property_value(sel.transfer->propertyReply);
int remainder = xcb_get_property_value_length(sel.transfer->propertyReply) - sel.transfer->propertyStart;

ssize_t len = write(sel.transfer->wlFD, property + sel.transfer->propertyStart, remainder);
ssize_t len = write(sel.transfer->wlFD.get(), property + sel.transfer->propertyStart, remainder);
if (len == -1) {
Debug::log(ERR, "[xwm] write died in transfer get");
close(sel.transfer->wlFD);
sel.transfer.reset();
return;
}
Expand All @@ -1196,7 +1194,6 @@ void CXWM::getTransferData(SXSelection& sel) {
return;
} else {
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
close(sel.transfer->wlFD);
sel.transfer.reset();
}
}
Expand Down Expand Up @@ -1372,20 +1369,18 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
fcntl(p[1], F_SETFD, FD_CLOEXEC);
fcntl(p[1], F_SETFL, O_NONBLOCK);

transfer->wlFD = p[0];
transfer->wlFD = Hyprutils::OS::CFileDescriptor(p[0]);

Debug::log(LOG, "[xwm] sending wayland selection to xwayland with mime {}, target {}, fds {} {}", mime, e->target, p[0], p[1]);

selection->send(mime, p[1]);
selection->send(mime, Hyprutils::OS::CFileDescriptor(p[1]));

transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD, WL_EVENT_READABLE, ::readDataSource, this);
transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, transfer->wlFD.get(), WL_EVENT_READABLE, ::readDataSource, this);

return true;
}

SXTransfer::~SXTransfer() {
if (wlFD)
close(wlFD);
if (eventSource)
wl_event_source_remove(eventSource);
if (incomingWindow)
Expand Down
27 changes: 14 additions & 13 deletions src/xwayland/XWM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <xcb/xfixes.h>
#include <xcb/composite.h>
#include <xcb/xcb_errors.h>
#include <hyprutils/os/FileDescriptor.hpp>

struct wl_event_source;
class CXWaylandSurfaceResource;
Expand All @@ -18,25 +19,25 @@ struct SXSelection;
struct SXTransfer {
~SXTransfer();

SXSelection& selection;
bool out = true;
SXSelection& selection;
bool out = true;

bool incremental = false;
bool flushOnDelete = false;
bool propertySet = false;
bool incremental = false;
bool flushOnDelete = false;
bool propertySet = false;

int wlFD = -1;
wl_event_source* eventSource = nullptr;
Hyprutils::OS::CFileDescriptor wlFD;
wl_event_source* eventSource = nullptr;

std::vector<uint8_t> data;
std::vector<uint8_t> data;

xcb_selection_request_event_t request;
xcb_selection_request_event_t request;

int propertyStart;
xcb_get_property_reply_t* propertyReply;
xcb_window_t incomingWindow;
int propertyStart;
xcb_get_property_reply_t* propertyReply;
xcb_window_t incomingWindow;

bool getIncomingSelectionProp(bool erase);
bool getIncomingSelectionProp(bool erase);
};

struct SXSelection {
Expand Down

0 comments on commit 808d8b7

Please sign in to comment.