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; struct eis_seat *s, *tmp;
list_for_each_safe(s, tmp, &client->seats, link) { list_for_each_safe(s, tmp, &client->seats, link) {
eis_seat_unbind(s);
eis_seat_remove(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) { list_for_each(seat, &client->seats, link) {
if (seat->id == seatid) { if (seat->id == seatid) {
eis_queue_seat_bind_event(seat, caps); eis_seat_bind(seat, caps);
return 0; return 0;
} }
} }
@ -210,7 +211,7 @@ client_seat_unbind(struct eis_client *client, uint32_t seatid)
list_for_each(seat, &client->seats, link) { list_for_each(seat, &client->seats, link) {
if (seat->id == seatid) { if (seat->id == seatid) {
eis_queue_seat_unbind_event(seat); eis_seat_unbind(seat);
return 0; return 0;
} }
} }

View file

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

View file

@ -86,6 +86,8 @@ eis_seat_add(struct eis_seat *seat)
case EIS_SEAT_STATE_PENDING: case EIS_SEAT_STATE_PENDING:
break; break;
case EIS_SEAT_STATE_ADDED: case EIS_SEAT_STATE_ADDED:
case EIS_SEAT_STATE_BOUND:
case EIS_SEAT_STATE_UNBOUND:
case EIS_SEAT_STATE_REMOVED: case EIS_SEAT_STATE_REMOVED:
case EIS_SEAT_STATE_DEAD: case EIS_SEAT_STATE_DEAD:
log_bug_client(eis_client_get_context(client), 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); 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 _public_ void
eis_seat_remove(struct eis_seat *seat) eis_seat_remove(struct eis_seat *seat)
{ {
@ -105,6 +151,8 @@ eis_seat_remove(struct eis_seat *seat)
switch (seat->state) { switch (seat->state) {
case EIS_SEAT_STATE_PENDING: case EIS_SEAT_STATE_PENDING:
case EIS_SEAT_STATE_ADDED: case EIS_SEAT_STATE_ADDED:
case EIS_SEAT_STATE_BOUND:
case EIS_SEAT_STATE_UNBOUND:
break; break;
case EIS_SEAT_STATE_REMOVED: case EIS_SEAT_STATE_REMOVED:
case EIS_SEAT_STATE_DEAD: case EIS_SEAT_STATE_DEAD:
@ -128,6 +176,9 @@ _public_ void
eis_seat_configure_capability(struct eis_seat *seat, eis_seat_configure_capability(struct eis_seat *seat,
enum eis_device_capability cap) enum eis_device_capability cap)
{ {
if (seat->state != EIS_SEAT_STATE_PENDING)
return;
switch (cap) { switch (cap) {
case EIS_DEVICE_CAP_POINTER: case EIS_DEVICE_CAP_POINTER:
case EIS_DEVICE_CAP_POINTER_ABSOLUTE: case EIS_DEVICE_CAP_POINTER_ABSOLUTE:

View file

@ -269,10 +269,8 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_before_received)
* immediately after */ * immediately after */
_unref_(eis_event) *bind = _unref_(eis_event) *bind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND); peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
/* FIXME: libeis should insert unbind here?
_unref_(eis_event) *unbind = _unref_(eis_event) *unbind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND); peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
*/
_unref_(eis_event) *disconnect = _unref_(eis_event) *disconnect =
peck_eis_next_event(eis, EIS_EVENT_CLIENT_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) { with_server(peck) {
_unref_(eis_event) *bind = _unref_(eis_event) *bind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND); peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
/* FIXME: libeis should insert unbind here?
_unref_(eis_event) *unbind = _unref_(eis_event) *unbind =
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND); peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
*/
_unref_(eis_event) *disconnect = _unref_(eis_event) *disconnect =
peck_eis_next_event(eis, EIS_EVENT_CLIENT_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); peck_eis_next_event(eis, EIS_EVENT_POINTER_MOTION);
_unref_(eis_event) *close = _unref_(eis_event) *close =
peck_eis_next_event(eis, EIS_EVENT_DEVICE_CLOSED); 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 = _unref_(eis_event) *disconnect =
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT); peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);