xwayland: notify requestor when we fail to respond to their request
We already mostly did this, but there were a couple of branches (`calloc` failures) where we'd bail without letting the other side know. Refs swaywm/sway#4007. Likely not going to be a real improvement there (if `calloc` fails you're already pretty screwed), but it does address a theoretical possibility.
This commit is contained in:
parent
7bb9d48dd1
commit
afeb941ca0
|
@ -265,15 +265,14 @@ static struct wl_array *xwm_selection_source_get_mime_types(
|
||||||
/**
|
/**
|
||||||
* Read the Wayland selection and send it to an Xwayland client.
|
* Read the Wayland selection and send it to an Xwayland client.
|
||||||
*/
|
*/
|
||||||
static void xwm_selection_send_data(struct wlr_xwm_selection *selection,
|
static bool xwm_selection_send_data(struct wlr_xwm_selection *selection,
|
||||||
xcb_selection_request_event_t *req, const char *mime_type) {
|
xcb_selection_request_event_t *req, const char *mime_type) {
|
||||||
// Check MIME type
|
// Check MIME type
|
||||||
struct wl_array *mime_types =
|
struct wl_array *mime_types =
|
||||||
xwm_selection_source_get_mime_types(selection);
|
xwm_selection_source_get_mime_types(selection);
|
||||||
if (mime_types == NULL) {
|
if (mime_types == NULL) {
|
||||||
wlr_log(WLR_ERROR, "not sending selection: no MIME type list available");
|
wlr_log(WLR_ERROR, "not sending selection: no MIME type list available");
|
||||||
xwm_selection_send_notify(selection->xwm, req, false);
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -288,16 +287,16 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection,
|
||||||
if (!found) {
|
if (!found) {
|
||||||
wlr_log(WLR_ERROR, "not sending selection: "
|
wlr_log(WLR_ERROR, "not sending selection: "
|
||||||
"requested an unsupported MIME type %s", mime_type);
|
"requested an unsupported MIME type %s", mime_type);
|
||||||
xwm_selection_send_notify(selection->xwm, req, false);
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_xwm_selection_transfer *transfer =
|
struct wlr_xwm_selection_transfer *transfer =
|
||||||
calloc(1, sizeof(struct wlr_xwm_selection_transfer));
|
calloc(1, sizeof(struct wlr_xwm_selection_transfer));
|
||||||
if (transfer == NULL) {
|
if (transfer == NULL) {
|
||||||
wlr_log(WLR_ERROR, "Allocation failed");
|
wlr_log(WLR_ERROR, "Allocation failed");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer->selection = selection;
|
transfer->selection = selection;
|
||||||
transfer->request = *req;
|
transfer->request = *req;
|
||||||
wl_array_init(&transfer->source_data);
|
wl_array_init(&transfer->source_data);
|
||||||
|
@ -305,9 +304,9 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection,
|
||||||
int p[2];
|
int p[2];
|
||||||
if (pipe(p) == -1) {
|
if (pipe(p) == -1) {
|
||||||
wlr_log_errno(WLR_ERROR, "pipe() failed");
|
wlr_log_errno(WLR_ERROR, "pipe() failed");
|
||||||
xwm_selection_send_notify(selection->xwm, req, false);
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -345,6 +344,8 @@ static void xwm_selection_send_data(struct wlr_xwm_selection *selection,
|
||||||
wlr_log(WLR_DEBUG, "Transfer %p still queued", outgoing);
|
wlr_log(WLR_DEBUG, "Transfer %p still queued", outgoing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xwm_selection_send_targets(struct wlr_xwm_selection *selection,
|
static void xwm_selection_send_targets(struct wlr_xwm_selection *selection,
|
||||||
|
@ -416,12 +417,12 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm,
|
||||||
xwm_get_selection(xwm, req->selection);
|
xwm_get_selection(xwm, req->selection);
|
||||||
if (selection == NULL) {
|
if (selection == NULL) {
|
||||||
wlr_log(WLR_DEBUG, "received selection request for unknown selection");
|
wlr_log(WLR_DEBUG, "received selection request for unknown selection");
|
||||||
return;
|
goto fail_notify_requestor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection->window != req->owner) {
|
if (selection->window != req->owner) {
|
||||||
wlr_log(WLR_DEBUG, "received selection request with invalid owner");
|
wlr_log(WLR_DEBUG, "received selection request with invalid owner");
|
||||||
return;
|
goto fail_notify_requestor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No xwayland surface focused, deny access to clipboard
|
// No xwayland surface focused, deny access to clipboard
|
||||||
|
@ -430,8 +431,7 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm,
|
||||||
wlr_log(WLR_DEBUG, "denying read access to selection %u (%s): "
|
wlr_log(WLR_DEBUG, "denying read access to selection %u (%s): "
|
||||||
"no xwayland surface focused", selection->atom, selection_name);
|
"no xwayland surface focused", selection->atom, selection_name);
|
||||||
free(selection_name);
|
free(selection_name);
|
||||||
xwm_selection_send_notify(xwm, req, false);
|
goto fail_notify_requestor;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->target == xwm->atoms[TARGETS]) {
|
if (req->target == xwm->atoms[TARGETS]) {
|
||||||
|
@ -446,12 +446,22 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm,
|
||||||
if (mime_type == NULL) {
|
if (mime_type == NULL) {
|
||||||
wlr_log(WLR_ERROR, "ignoring selection request: unknown atom %u",
|
wlr_log(WLR_ERROR, "ignoring selection request: unknown atom %u",
|
||||||
req->target);
|
req->target);
|
||||||
xwm_selection_send_notify(xwm, req, false);
|
goto fail_notify_requestor;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
xwm_selection_send_data(selection, req, mime_type);
|
|
||||||
|
bool send_success = xwm_selection_send_data(selection, req, mime_type);
|
||||||
free(mime_type);
|
free(mime_type);
|
||||||
|
if (!send_success) {
|
||||||
|
goto fail_notify_requestor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail_notify_requestor:
|
||||||
|
// Something went wrong, and there won't be any data being sent to the
|
||||||
|
// requestor, so let them know.
|
||||||
|
xwm_selection_send_notify(xwm, req, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xwm_handle_selection_destroy_notify(struct wlr_xwm *xwm,
|
void xwm_handle_selection_destroy_notify(struct wlr_xwm *xwm,
|
||||||
|
|
Loading…
Reference in New Issue