mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-03 13:41:59 -07:00
xwayland: add INCR support for clipboard transfers (#9434)
add INCR protocol support for large transfers fix write handling for partial transfers fix an issue where wayland windows could die from a paste from an xwayland window
This commit is contained in:
@@ -589,9 +589,18 @@ void CXWM::handleSelectionNotify(xcb_selection_notify_event_t* e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CXWM::handleSelectionPropertyNotify(xcb_property_notify_event_t* e) {
|
bool CXWM::handleSelectionPropertyNotify(xcb_property_notify_event_t* e) {
|
||||||
// Debug::log(LOG, "[xwm] Selection property notify for {} target {}", e->atom, e->window);
|
if (e->state != XCB_PROPERTY_DELETE)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Debug::log(ERR, "[xwm] FIXME: CXWM::handleSelectionPropertyNotify stub");
|
auto it = std::ranges::find_if(clipboard.transfers, [e](const auto& t) { return t->incomingWindow == e->window; });
|
||||||
|
if (it != clipboard.transfers.end()) {
|
||||||
|
if (!(*it)->getIncomingSelectionProp(true)) {
|
||||||
|
clipboard.transfers.erase(it);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
getTransferData(clipboard);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1205,8 +1214,10 @@ void CXWM::getTransferData(SXSelection& sel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (transfer->propertyReply->type == HYPRATOMS["INCR"]) {
|
if (transfer->propertyReply->type == HYPRATOMS["INCR"]) {
|
||||||
Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :(");
|
transfer->incremental = true;
|
||||||
sel.transfers.erase(it);
|
transfer->propertyStart = 0;
|
||||||
|
free(transfer->propertyReply);
|
||||||
|
transfer->propertyReply = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1426,6 +1437,8 @@ int SXSelection::onWrite() {
|
|||||||
|
|
||||||
ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder);
|
ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
return 1;
|
||||||
Debug::log(ERR, "[xwm] write died in transfer get");
|
Debug::log(ERR, "[xwm] write died in transfer get");
|
||||||
transfers.erase(it);
|
transfers.erase(it);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1436,7 +1449,13 @@ int SXSelection::onWrite() {
|
|||||||
Debug::log(LOG, "[xwm] wl client read partially: len {}", len);
|
Debug::log(LOG, "[xwm] wl client read partially: len {}", len);
|
||||||
} else {
|
} else {
|
||||||
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
|
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
|
||||||
|
if (!transfer->incremental) {
|
||||||
transfers.erase(it);
|
transfers.erase(it);
|
||||||
|
} else {
|
||||||
|
free(transfer->propertyReply);
|
||||||
|
transfer->propertyReply = nullptr;
|
||||||
|
transfer->propertyStart = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
Reference in New Issue
Block a user