eis: insert an unbind event if we had a bound seat

If our client binds to a seat and then disconnects, insert an unbind
event in the EIS queue to unwind correctly.

Signed-off-by:	Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2021-07-21 11:19:35 +10:00
parent 358a528478
commit cc78331bba
4 changed files with 61 additions and 6 deletions

View file

@ -155,6 +155,7 @@ eis_client_disconnect(struct eis_client *client)
{
struct eis_seat *s, *tmp;
list_for_each_safe(s, tmp, &client->seats, link) {
eis_seat_unbind(s);
eis_seat_remove(s);
}
}
@ -195,7 +196,7 @@ client_seat_bind(struct eis_client *client, uint32_t seatid, uint32_t caps)
list_for_each(seat, &client->seats, link) {
if (seat->id == seatid) {
eis_queue_seat_bind_event(seat, caps);
eis_seat_bind(seat, caps);
return 0;
}
}
@ -210,7 +211,7 @@ client_seat_unbind(struct eis_client *client, uint32_t seatid)
list_for_each(seat, &client->seats, link) {
if (seat->id == seatid) {
eis_queue_seat_unbind_event(seat);
eis_seat_unbind(seat);
return 0;
}
}

View file

@ -84,6 +84,8 @@ struct eis_client {
enum eis_seat_state {
EIS_SEAT_STATE_PENDING,
EIS_SEAT_STATE_ADDED,
EIS_SEAT_STATE_BOUND,
EIS_SEAT_STATE_UNBOUND,
EIS_SEAT_STATE_REMOVED, /* Removed but still waiting for some devices to be removed */
EIS_SEAT_STATE_DEAD, /* Removed from our list */
};
@ -205,6 +207,9 @@ eis_client_suspend_device(struct eis_client *client,
void
eis_seat_bind(struct eis_seat *seat, uint32_t cap);
void
eis_seat_unbind(struct eis_seat *seat);
void
eis_device_set_pointer_range(struct eis_device *device,
uint32_t w, uint32_t h);

View file

@ -86,6 +86,8 @@ eis_seat_add(struct eis_seat *seat)
case EIS_SEAT_STATE_PENDING:
break;
case EIS_SEAT_STATE_ADDED:
case EIS_SEAT_STATE_BOUND:
case EIS_SEAT_STATE_UNBOUND:
case EIS_SEAT_STATE_REMOVED:
case EIS_SEAT_STATE_DEAD:
log_bug_client(eis_client_get_context(client),
@ -97,6 +99,50 @@ eis_seat_add(struct eis_seat *seat)
eis_client_add_seat(client, seat);
}
void
eis_seat_bind(struct eis_seat *seat, uint32_t caps)
{
struct eis_client *client = eis_seat_get_client(seat);
switch (seat->state) {
case EIS_SEAT_STATE_ADDED:
break;
case EIS_SEAT_STATE_PENDING:
case EIS_SEAT_STATE_BOUND:
case EIS_SEAT_STATE_UNBOUND:
case EIS_SEAT_STATE_REMOVED:
case EIS_SEAT_STATE_DEAD:
log_bug_client(eis_client_get_context(client),
"%s: seat cannot be bound\n", __func__);
return;
}
seat->state = EIS_SEAT_STATE_BOUND;
eis_queue_seat_bind_event(seat, caps);
}
void
eis_seat_unbind(struct eis_seat *seat)
{
struct eis_client *client = eis_seat_get_client(seat);
switch (seat->state) {
case EIS_SEAT_STATE_BOUND:
break;
case EIS_SEAT_STATE_ADDED:
case EIS_SEAT_STATE_PENDING:
case EIS_SEAT_STATE_UNBOUND:
case EIS_SEAT_STATE_REMOVED:
case EIS_SEAT_STATE_DEAD:
log_bug_client(eis_client_get_context(client),
"%s: seat cannot be unbound\n", __func__);
return;
}
seat->state = EIS_SEAT_STATE_UNBOUND;
eis_queue_seat_unbind_event(seat);
}
_public_ void
eis_seat_remove(struct eis_seat *seat)
{
@ -105,6 +151,8 @@ eis_seat_remove(struct eis_seat *seat)
switch (seat->state) {
case EIS_SEAT_STATE_PENDING:
case EIS_SEAT_STATE_ADDED:
case EIS_SEAT_STATE_BOUND:
case EIS_SEAT_STATE_UNBOUND:
break;
case EIS_SEAT_STATE_REMOVED:
case EIS_SEAT_STATE_DEAD:
@ -128,6 +176,9 @@ _public_ void
eis_seat_configure_capability(struct eis_seat *seat,
enum eis_device_capability cap)
{
if (seat->state != EIS_SEAT_STATE_PENDING)
return;
switch (cap) {
case EIS_DEVICE_CAP_POINTER:
case EIS_DEVICE_CAP_POINTER_ABSOLUTE:

View file

@ -269,10 +269,8 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_before_received)
* immediately after */
_unref_(eis_event) *bind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
/* FIXME: libeis should insert unbind here?
_unref_(eis_event) *unbind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
*/
_unref_(eis_event) *disconnect =
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);
}
@ -347,10 +345,8 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_after_received)
with_server(peck) {
_unref_(eis_event) *bind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
/* FIXME: libeis should insert unbind here?
_unref_(eis_event) *unbind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
*/
_unref_(eis_event) *disconnect =
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);
}
@ -1313,6 +1309,8 @@ MUNIT_TEST(test_xdotool_rel_motion)
peck_eis_next_event(eis, EIS_EVENT_POINTER_MOTION);
_unref_(eis_event) *close =
peck_eis_next_event(eis, EIS_EVENT_DEVICE_CLOSED);
_unref_(eis_event) *unbind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
_unref_(eis_event) *disconnect =
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);