summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornyx <nnyyxxxx@protonmail.com>2025-02-19 10:29:39 -0500
committerGitHub <noreply@github.com>2025-02-19 16:29:39 +0100
commit6d25ef09cd6a33bcd589bd0f1e88e86fcff2dc67 (patch)
tree0f17f4360ac146d3c64fc55b3e122720aa321321
parent0137a5f6cdd24d5a10f813572791f1e641221a5b (diff)
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
-rw-r--r--src/xwayland/XWM.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp
index a4e3289b..0899261a 100644
--- a/src/xwayland/XWM.cpp
+++ b/src/xwayland/XWM.cpp
@@ -589,9 +589,18 @@ void CXWM::handleSelectionNotify(xcb_selection_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;
}
@@ -1205,8 +1214,10 @@ void CXWM::getTransferData(SXSelection& sel) {
}
if (transfer->propertyReply->type == HYPRATOMS["INCR"]) {
- Debug::log(ERR, "[xwm] Transfer is INCR, which we don't support :(");
- sel.transfers.erase(it);
+ transfer->incremental = true;
+ transfer->propertyStart = 0;
+ free(transfer->propertyReply);
+ transfer->propertyReply = nullptr;
return;
}
@@ -1426,6 +1437,8 @@ int SXSelection::onWrite() {
ssize_t len = write(transfer->wlFD.get(), property + transfer->propertyStart, remainder);
if (len == -1) {
+ if (errno == EAGAIN)
+ return 1;
Debug::log(ERR, "[xwm] write died in transfer get");
transfers.erase(it);
return 0;
@@ -1436,7 +1449,13 @@ int SXSelection::onWrite() {
Debug::log(LOG, "[xwm] wl client read partially: len {}", len);
} else {
Debug::log(LOG, "[xwm] cb transfer to wl client complete, read {} bytes", len);
- transfers.erase(it);
+ if (!transfer->incremental) {
+ transfers.erase(it);
+ } else {
+ free(transfer->propertyReply);
+ transfer->propertyReply = nullptr;
+ transfer->propertyStart = 0;
+ }
}
return 1;