mirror of
https://github.com/hyprwm/Hyprland
synced 2025-01-23 19:29:48 +01:00
xwayland: fix sending large clipboard data (#9134)
This commit is contained in:
parent
c90dbfab6f
commit
fda5626594
2 changed files with 35 additions and 21 deletions
|
@ -1168,6 +1168,11 @@ void CXWM::setClipboardToWayland(SXSelection& sel) {
|
||||||
g_pSeatManager->setCurrentSelection(sel.dataSource);
|
g_pSeatManager->setCurrentSelection(sel.dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int writeDataSource(int fd, uint32_t mask, void* data) {
|
||||||
|
auto selection = (SXSelection*)data;
|
||||||
|
return selection->onWrite();
|
||||||
|
}
|
||||||
|
|
||||||
void CXWM::getTransferData(SXSelection& sel) {
|
void CXWM::getTransferData(SXSelection& sel) {
|
||||||
Debug::log(LOG, "[xwm] getTransferData");
|
Debug::log(LOG, "[xwm] getTransferData");
|
||||||
|
|
||||||
|
@ -1179,26 +1184,9 @@ void CXWM::getTransferData(SXSelection& sel) {
|
||||||
sel.transfer.reset();
|
sel.transfer.reset();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
char* property = (char*)xcb_get_property_value(sel.transfer->propertyReply);
|
sel.onWrite();
|
||||||
int remainder = xcb_get_property_value_length(sel.transfer->propertyReply) - sel.transfer->propertyStart;
|
if (sel.transfer)
|
||||||
|
sel.transfer->eventSource = wl_event_loop_add_fd(g_pCompositor->m_sWLEventLoop, sel.transfer->wlFD, WL_EVENT_WRITABLE, ::writeDataSource, &sel);
|
||||||
ssize_t len = write(sel.transfer->wlFD, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len < remainder) {
|
|
||||||
sel.transfer->propertyStart += len;
|
|
||||||
Debug::log(ERR, "[xwm] wl client read partially: len {}", len);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
|
|
||||||
close(sel.transfer->wlFD);
|
|
||||||
sel.transfer.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1370,7 +1358,8 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
|
||||||
fcntl(p[0], F_SETFD, FD_CLOEXEC);
|
fcntl(p[0], F_SETFD, FD_CLOEXEC);
|
||||||
fcntl(p[0], F_SETFL, O_NONBLOCK);
|
fcntl(p[0], F_SETFL, O_NONBLOCK);
|
||||||
fcntl(p[1], F_SETFD, FD_CLOEXEC);
|
fcntl(p[1], F_SETFD, FD_CLOEXEC);
|
||||||
fcntl(p[1], F_SETFL, O_NONBLOCK);
|
// the wayland client might not expect a non-blocking fd
|
||||||
|
// fcntl(p[1], F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
transfer->wlFD = p[0];
|
transfer->wlFD = p[0];
|
||||||
|
|
||||||
|
@ -1383,6 +1372,30 @@ bool SXSelection::sendData(xcb_selection_request_event_t* e, std::string mime) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SXSelection::onWrite() {
|
||||||
|
char* property = (char*)xcb_get_property_value(transfer->propertyReply);
|
||||||
|
int remainder = xcb_get_property_value_length(transfer->propertyReply) - transfer->propertyStart;
|
||||||
|
|
||||||
|
ssize_t len = write(transfer->wlFD, property + transfer->propertyStart, remainder);
|
||||||
|
if (len == -1) {
|
||||||
|
Debug::log(ERR, "[xwm] write died in transfer get");
|
||||||
|
close(transfer->wlFD);
|
||||||
|
transfer.reset();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < remainder) {
|
||||||
|
transfer->propertyStart += len;
|
||||||
|
Debug::log(LOG, "[xwm] wl client read partially: len {}", len);
|
||||||
|
} else {
|
||||||
|
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
|
||||||
|
close(transfer->wlFD);
|
||||||
|
transfer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
SXTransfer::~SXTransfer() {
|
SXTransfer::~SXTransfer() {
|
||||||
if (wlFD)
|
if (wlFD)
|
||||||
close(wlFD);
|
close(wlFD);
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct SXSelection {
|
||||||
void onKeyboardFocus();
|
void onKeyboardFocus();
|
||||||
bool sendData(xcb_selection_request_event_t* e, std::string mime);
|
bool sendData(xcb_selection_request_event_t* e, std::string mime);
|
||||||
int onRead(int fd, uint32_t mask);
|
int onRead(int fd, uint32_t mask);
|
||||||
|
int onWrite();
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener setSelection;
|
CHyprSignalListener setSelection;
|
||||||
|
|
Loading…
Reference in a new issue