session-lock: send more protocol errors

The invalid_destroy and invalid_unlock protocol errors aren't currently
sent by wlroots and instead left up to the compositor. However, we can
handle these as well without much additional complexity.

This also adds a missing wl_resource_destroy() call if the lock is inert
in lock_handle_unlock_and_destroy().
This commit is contained in:
Isaac Freund 2022-12-21 17:52:48 +01:00
parent 48a89179a3
commit 869af1cfbb
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
2 changed files with 38 additions and 2 deletions

View File

@ -40,6 +40,10 @@ struct wlr_session_lock_v1 {
} events;
void *data;
// private state
bool locked_sent;
};
struct wlr_session_lock_surface_v1_state {

View File

@ -126,7 +126,6 @@ static void lock_surface_handle_ack_configure(struct wl_client *client,
free(configure);
}
static const struct ext_session_lock_surface_v1_interface lock_surface_implementation = {
.destroy = resource_handle_destroy,
.ack_configure = lock_surface_handle_ack_configure,
@ -306,6 +305,17 @@ static void lock_handle_unlock_and_destroy(struct wl_client *client,
struct wl_resource *lock_resource) {
struct wlr_session_lock_v1 *lock = lock_from_resource(lock_resource);
if (lock == NULL) {
// This can happen if the compositor sent the locked event and
// later the finished event as the lock is destroyed when the
// finished event is sent.
wl_resource_destroy(lock_resource);
return;
}
if (!lock->locked_sent) {
wl_resource_post_error(lock_resource,
EXT_SESSION_LOCK_V1_ERROR_INVALID_UNLOCK,
"the locked event was never sent");
return;
}
@ -314,13 +324,35 @@ static void lock_handle_unlock_and_destroy(struct wl_client *client,
wl_resource_destroy(lock_resource);
}
static void lock_handle_destroy(struct wl_client *client,
struct wl_resource *lock_resource) {
struct wlr_session_lock_v1 *lock = lock_from_resource(lock_resource);
if (lock == NULL) {
// The compositor sent the finished event and destroyed the lock.
wl_resource_destroy(lock_resource);
return;
}
if (lock->locked_sent) {
wl_resource_post_error(lock_resource,
EXT_SESSION_LOCK_V1_ERROR_INVALID_DESTROY,
"the session lock may not be destroyed while locked");
} else {
wl_resource_post_error(lock_resource,
EXT_SESSION_LOCK_V1_ERROR_INVALID_DESTROY,
"the finished event was never sent");
}
}
static const struct ext_session_lock_v1_interface lock_implementation = {
.destroy = resource_handle_destroy,
.destroy = lock_handle_destroy,
.get_lock_surface = lock_handle_get_lock_surface,
.unlock_and_destroy = lock_handle_unlock_and_destroy,
};
void wlr_session_lock_v1_send_locked(struct wlr_session_lock_v1 *lock) {
assert(!lock->locked_sent);
lock->locked_sent = true;
ext_session_lock_v1_send_locked(lock->resource);
}