mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
pointer-constraints: use wlr_surface_synced.commit hook
This fixes a problem where an outdated surface input region was used to compute the effective confinement region. Additionally, this commit fixes a bug in pointer_constraint_create() which caused the initial region to not be applied immediately. This is a breaking change: set_region is now emitted before the role commit hook is called, and it's not emitted if the region hasn't actually changed.
This commit is contained in:
parent
f95270bb5e
commit
b25f98d583
2 changed files with 34 additions and 34 deletions
|
|
@ -64,7 +64,6 @@ struct wlr_pointer_constraint_v1 {
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_listener surface_commit;
|
|
||||||
struct wl_listener surface_destroy;
|
struct wl_listener surface_destroy;
|
||||||
struct wl_listener seat_destroy;
|
struct wl_listener seat_destroy;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ static void pointer_constraint_destroy(struct wlr_pointer_constraint_v1 *constra
|
||||||
wl_resource_set_user_data(constraint->resource, NULL);
|
wl_resource_set_user_data(constraint->resource, NULL);
|
||||||
wlr_surface_synced_finish(&constraint->synced);
|
wlr_surface_synced_finish(&constraint->synced);
|
||||||
wl_list_remove(&constraint->link);
|
wl_list_remove(&constraint->link);
|
||||||
wl_list_remove(&constraint->surface_commit.link);
|
|
||||||
wl_list_remove(&constraint->surface_destroy.link);
|
wl_list_remove(&constraint->surface_destroy.link);
|
||||||
wl_list_remove(&constraint->seat_destroy.link);
|
wl_list_remove(&constraint->seat_destroy.link);
|
||||||
pixman_region32_fini(&constraint->region);
|
pixman_region32_fini(&constraint->region);
|
||||||
|
|
@ -72,19 +71,6 @@ static void pointer_constraint_destroy_resource(struct wl_resource *resource) {
|
||||||
pointer_constraint_destroy(constraint);
|
pointer_constraint_destroy(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointer_constraint_set_region(
|
|
||||||
struct wlr_pointer_constraint_v1 *constraint,
|
|
||||||
struct wl_resource *region_resource) {
|
|
||||||
pixman_region32_clear(&constraint->pending.region);
|
|
||||||
|
|
||||||
if (region_resource) {
|
|
||||||
const pixman_region32_t *region = wlr_region_from_resource(region_resource);
|
|
||||||
pixman_region32_copy(&constraint->pending.region, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
constraint->pending.committed |= WLR_POINTER_CONSTRAINT_V1_STATE_REGION;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pointer_constraint_handle_set_region(struct wl_client *client,
|
static void pointer_constraint_handle_set_region(struct wl_client *client,
|
||||||
struct wl_resource *resource, struct wl_resource *region_resource) {
|
struct wl_resource *resource, struct wl_resource *region_resource) {
|
||||||
struct wlr_pointer_constraint_v1 *constraint =
|
struct wlr_pointer_constraint_v1 *constraint =
|
||||||
|
|
@ -93,7 +79,13 @@ static void pointer_constraint_handle_set_region(struct wl_client *client,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer_constraint_set_region(constraint, region_resource);
|
pixman_region32_clear(&constraint->pending.region);
|
||||||
|
if (region_resource) {
|
||||||
|
const pixman_region32_t *region = wlr_region_from_resource(region_resource);
|
||||||
|
pixman_region32_copy(&constraint->pending.region, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
constraint->pending.committed |= WLR_POINTER_CONSTRAINT_V1_STATE_REGION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointer_constraint_set_cursor_position_hint(struct wl_client *client,
|
static void pointer_constraint_set_cursor_position_hint(struct wl_client *client,
|
||||||
|
|
@ -110,27 +102,27 @@ static void pointer_constraint_set_cursor_position_hint(struct wl_client *client
|
||||||
constraint->pending.committed |= WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT;
|
constraint->pending.committed |= WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointer_constraint_commit(
|
// Returns true if the region has changed
|
||||||
struct wlr_pointer_constraint_v1 *constraint) {
|
static bool update_region(struct wlr_pointer_constraint_v1 *constraint) {
|
||||||
pixman_region32_clear(&constraint->region);
|
pixman_region32_t region;
|
||||||
|
pixman_region32_init(®ion);
|
||||||
|
|
||||||
if (pixman_region32_not_empty(&constraint->current.region)) {
|
if (pixman_region32_not_empty(&constraint->current.region)) {
|
||||||
pixman_region32_intersect(&constraint->region,
|
pixman_region32_intersect(®ion,
|
||||||
&constraint->surface->input_region, &constraint->current.region);
|
&constraint->surface->input_region, &constraint->current.region);
|
||||||
} else {
|
} else {
|
||||||
pixman_region32_copy(&constraint->region,
|
pixman_region32_copy(®ion, &constraint->surface->input_region);
|
||||||
&constraint->surface->input_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_REGION) {
|
if (pixman_region32_equal(®ion, &constraint->region)) {
|
||||||
wl_signal_emit_mutable(&constraint->events.set_region, NULL);
|
pixman_region32_fini(®ion);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
pixman_region32_fini(&constraint->region);
|
||||||
struct wlr_pointer_constraint_v1 *constraint =
|
constraint->region = region;
|
||||||
wl_container_of(listener, constraint, surface_commit);
|
|
||||||
|
|
||||||
pointer_constraint_commit(constraint);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -182,11 +174,20 @@ static void surface_synced_move_state(void *_dst, void *_src) {
|
||||||
src->committed = 0;
|
src->committed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void surface_synced_commit(struct wlr_surface_synced *synced) {
|
||||||
|
struct wlr_pointer_constraint_v1 *constraint = wl_container_of(synced, constraint, synced);
|
||||||
|
|
||||||
|
if (update_region(constraint)) {
|
||||||
|
wl_signal_emit_mutable(&constraint->events.set_region, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wlr_surface_synced_impl surface_synced_impl = {
|
static const struct wlr_surface_synced_impl surface_synced_impl = {
|
||||||
.state_size = sizeof(struct wlr_pointer_constraint_v1_state),
|
.state_size = sizeof(struct wlr_pointer_constraint_v1_state),
|
||||||
.init_state = surface_synced_init_state,
|
.init_state = surface_synced_init_state,
|
||||||
.finish_state = surface_synced_finish_state,
|
.finish_state = surface_synced_finish_state,
|
||||||
.move_state = surface_synced_move_state,
|
.move_state = surface_synced_move_state,
|
||||||
|
.commit = surface_synced_commit,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pointer_constraint_create(struct wl_client *client,
|
static void pointer_constraint_create(struct wl_client *client,
|
||||||
|
|
@ -264,11 +265,11 @@ static void pointer_constraint_create(struct wl_client *client,
|
||||||
|
|
||||||
pixman_region32_init(&constraint->region);
|
pixman_region32_init(&constraint->region);
|
||||||
|
|
||||||
pointer_constraint_set_region(constraint, region_resource);
|
if (region_resource) {
|
||||||
pointer_constraint_commit(constraint);
|
pixman_region32_copy(&constraint->current.region,
|
||||||
|
wlr_region_from_resource(region_resource));
|
||||||
constraint->surface_commit.notify = handle_surface_commit;
|
update_region(constraint);
|
||||||
wl_signal_add(&surface->events.commit, &constraint->surface_commit);
|
}
|
||||||
|
|
||||||
constraint->surface_destroy.notify = handle_surface_destroy;
|
constraint->surface_destroy.notify = handle_surface_destroy;
|
||||||
wl_signal_add(&surface->events.destroy, &constraint->surface_destroy);
|
wl_signal_add(&surface->events.destroy, &constraint->surface_destroy);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue