oeffis: Make ConnectToEIS call async

A blocking call can be  problematic when done from inside Xwayland
to the compositor as the compositor could be doing a blocking X call
at the same time. In this instance we found it's likely to happen
because this call will happen shortly after the user accepted the
This is not a problem for the other calls because the portal API
is async for these via request response signalling.
This commit is contained in:
David Redondo 2024-07-31 07:05:48 +00:00 committed by Peter Hutterer
parent 865d7152e0
commit e8a844355f

View file

@ -327,43 +327,31 @@ xdp_session_path(char *sender_name, char *token)
return xaprintf("/org/freedesktop/portal/desktop/session/%s/%s", sender_name, token);
}
static void
portal_connect_to_eis(struct oeffis *oeffis)
static int
connect_to_eis_returned(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_unref_(sd_bus_message) *response = NULL;
sd_bus *bus = oeffis->bus;
int eisfd;
struct oeffis *oeffis = userdata;
int rc = sd_bus_message_get_errno(m);
int rc = 0;
with_signals_blocked(SIGALRM) {
rc = sd_bus_call_method(bus, oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"ConnectToEIS",
&error,
&response,
"oa{sv}",
oeffis->session_path,
0);
if (rc > 0) {
oeffis_disconnect(oeffis, "Error calling ConnectToEIS: %s", strerror(rc));
return rc;
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to call ConnectToEIS: %s", strerror(-rc));
return;
}
rc = sd_bus_message_read(response, "h", &eisfd);
rc = sd_bus_message_read(m, "h", &eisfd);
if (rc < 0) {
oeffis_disconnect(oeffis, "Unable to get fd from portal: %s", strerror(-rc));
return;
return -rc;
}
/* the fd is owned by the message */
rc = xerrno(xdup(eisfd));
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to dup fd: %s", strerror(-rc));
return;
return -rc;
} else {
eisfd = rc;
int flags = fcntl(eisfd, F_GETFL, 0);
@ -373,8 +361,36 @@ portal_connect_to_eis(struct oeffis *oeffis)
log_debug("Got fd %d from portal", eisfd);
rc = oeffis_set_eis_fd(oeffis, eisfd);
if (rc < 0)
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to set the fd: %s", strerror(-rc));
return -rc;
}
return 0;
}
static void
portal_connect_to_eis(struct oeffis *oeffis)
{
sd_bus *bus = oeffis->bus;
int rc = 0;
with_signals_blocked(SIGALRM) {
rc = sd_bus_call_method_async(bus, NULL, oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"ConnectToEIS",
&connect_to_eis_returned,
oeffis,
"oa{sv}",
oeffis->session_path,
0);
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to call ConnectToEIS: %s", strerror(-rc));
return;
}
}
static int