xwayland/xwm: prevent onWrite infinite loop and clean orphan transfers (#13122)

Fixes #11411

- Add return 0 after erasing completed non-incremental transfer to stop event source polling
- Add removeTransfer() helper to SXSelection for cleaning transfers by window ID
- Add removeTransfersForWindow() helper to CXWM for cleaning all selections at once
- Clean orphan transfers in handleDestroy before surface removal
- Clean orphan transfers in handlePropertyNotify on missing window or failed reply
- Add m_dndSelection to handleSelectionPropertyNotify cleanup loop
- Initialize SXTransfer members with safe defaults to prevent undefined behavior
- Fix race condition in getTransferData by using window ID lookup instead of index
This commit is contained in:
Zynix 2026-01-29 16:50:17 +03:00 committed by GitHub
parent 7d209b2941
commit c92fb5e85f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 11 deletions

View file

@ -35,9 +35,9 @@ struct SXTransfer {
xcb_selection_request_event_t request;
int propertyStart;
xcb_get_property_reply_t* propertyReply;
xcb_window_t incomingWindow;
int propertyStart = 0;
xcb_get_property_reply_t* propertyReply = nullptr;
xcb_window_t incomingWindow = 0;
bool getIncomingSelectionProp(bool erase);
};
@ -54,6 +54,7 @@ struct SXSelection {
bool sendData(xcb_selection_request_event_t* e, std::string mime);
int onRead(int fd, uint32_t mask);
int onWrite();
void removeTransfer(xcb_window_t window);
struct {
CHyprSignalListener setSelection;
@ -164,6 +165,8 @@ class CXWM {
void handleFocusOut(xcb_focus_out_event_t* e);
void handleError(xcb_value_error_t* e);
void removeTransfersForWindow(xcb_window_t window);
bool handleSelectionEvent(xcb_generic_event_t* e);
void handleSelectionNotify(xcb_selection_notify_event_t* e);
bool handleSelectionPropertyNotify(xcb_property_notify_event_t* e);