libweston: Add view unmap listener to pointer constraints
Since the logic of pointer constraints assumes a valid view throughout, add a signal to disable constraints when its current view is unmapped by Weston. The assumption that a previously unmapped view is valid already leads to the constraints code crashing. This can happen when attaching a NULL buffer to the surface and commiting, which effectively unmaps the view with the side effect of clearing the surface's input region, which is then assumed valid inside maybe_warp_confined_pointer(). Fixes: #721 Signed-off-by: Sergio Gómez <sergio.g.delreal@gmail.com> (cherry picked from commit e3079393c400e3dc6498234d1d092f3072fa8b44)
This commit is contained in:
committed by
Marius Vlad
parent
0bd68d9ad6
commit
21e46364c0
@@ -1452,6 +1452,7 @@ struct weston_view {
|
|||||||
struct weston_surface *surface;
|
struct weston_surface *surface;
|
||||||
struct wl_list surface_link;
|
struct wl_list surface_link;
|
||||||
struct wl_signal destroy_signal;
|
struct wl_signal destroy_signal;
|
||||||
|
struct wl_signal unmap_signal;
|
||||||
|
|
||||||
/* struct weston_paint_node::view_link */
|
/* struct weston_paint_node::view_link */
|
||||||
struct wl_list paint_node_list;
|
struct wl_list paint_node_list;
|
||||||
@@ -1605,6 +1606,7 @@ struct weston_pointer_constraint {
|
|||||||
bool hint_is_pending;
|
bool hint_is_pending;
|
||||||
|
|
||||||
struct wl_listener pointer_destroy_listener;
|
struct wl_listener pointer_destroy_listener;
|
||||||
|
struct wl_listener view_unmap_listener;
|
||||||
struct wl_listener surface_commit_listener;
|
struct wl_listener surface_commit_listener;
|
||||||
struct wl_listener surface_activate_listener;
|
struct wl_listener surface_activate_listener;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -396,6 +396,7 @@ weston_view_create(struct weston_surface *surface)
|
|||||||
wl_list_insert(&surface->views, &view->surface_link);
|
wl_list_insert(&surface->views, &view->surface_link);
|
||||||
|
|
||||||
wl_signal_init(&view->destroy_signal);
|
wl_signal_init(&view->destroy_signal);
|
||||||
|
wl_signal_init(&view->unmap_signal);
|
||||||
wl_list_init(&view->link);
|
wl_list_init(&view->link);
|
||||||
wl_list_init(&view->layer_link.link);
|
wl_list_init(&view->layer_link.link);
|
||||||
wl_list_init(&view->paint_node_list);
|
wl_list_init(&view->paint_node_list);
|
||||||
@@ -2248,9 +2249,7 @@ weston_view_unmap(struct weston_view *view)
|
|||||||
view->output_mask = 0;
|
view->output_mask = 0;
|
||||||
weston_surface_assign_output(view->surface);
|
weston_surface_assign_output(view->surface);
|
||||||
|
|
||||||
if (weston_surface_is_mapped(view->surface))
|
if (!weston_surface_is_mapped(view->surface)) {
|
||||||
return;
|
|
||||||
|
|
||||||
wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
|
wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
|
||||||
struct weston_touch *touch = weston_seat_get_touch(seat);
|
struct weston_touch *touch = weston_seat_get_touch(seat);
|
||||||
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
|
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
|
||||||
@@ -2264,6 +2263,8 @@ weston_view_unmap(struct weston_view *view)
|
|||||||
if (touch && touch->focus == view)
|
if (touch && touch->focus == view)
|
||||||
weston_touch_set_focus(touch, NULL);
|
weston_touch_set_focus(touch, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
weston_signal_emit_mutable(&view->unmap_signal, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
|
|||||||
@@ -3713,6 +3713,8 @@ enable_pointer_constraint(struct weston_pointer_constraint *constraint,
|
|||||||
constraint->view = view;
|
constraint->view = view;
|
||||||
pointer_constraint_notify_activated(constraint);
|
pointer_constraint_notify_activated(constraint);
|
||||||
weston_pointer_start_grab(constraint->pointer, &constraint->grab);
|
weston_pointer_start_grab(constraint->pointer, &constraint->grab);
|
||||||
|
wl_signal_add(&constraint->view->unmap_signal,
|
||||||
|
&constraint->view_unmap_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -3727,6 +3729,8 @@ weston_pointer_constraint_disable(struct weston_pointer_constraint *constraint)
|
|||||||
constraint->view = NULL;
|
constraint->view = NULL;
|
||||||
pointer_constraint_notify_deactivated(constraint);
|
pointer_constraint_notify_deactivated(constraint);
|
||||||
weston_pointer_end_grab(constraint->grab.pointer);
|
weston_pointer_end_grab(constraint->grab.pointer);
|
||||||
|
wl_list_remove(&constraint->view_unmap_listener.link);
|
||||||
|
wl_list_init(&constraint->view_unmap_listener.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -3931,6 +3935,16 @@ pointer_constraint_pointer_destroyed(struct wl_listener *listener, void *data)
|
|||||||
weston_pointer_constraint_destroy(constraint);
|
weston_pointer_constraint_destroy(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pointer_constraint_view_unmapped(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct weston_pointer_constraint *constraint =
|
||||||
|
container_of(listener, struct weston_pointer_constraint,
|
||||||
|
view_unmap_listener);
|
||||||
|
|
||||||
|
disable_pointer_constraint(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pointer_constraint_surface_committed(struct wl_listener *listener, void *data)
|
pointer_constraint_surface_committed(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
@@ -3992,6 +4006,8 @@ weston_pointer_constraint_create(struct weston_surface *surface,
|
|||||||
|
|
||||||
constraint->surface_activate_listener.notify =
|
constraint->surface_activate_listener.notify =
|
||||||
pointer_constraint_surface_activate;
|
pointer_constraint_surface_activate;
|
||||||
|
constraint->view_unmap_listener.notify =
|
||||||
|
pointer_constraint_view_unmapped;
|
||||||
constraint->surface_commit_listener.notify =
|
constraint->surface_commit_listener.notify =
|
||||||
pointer_constraint_surface_committed;
|
pointer_constraint_surface_committed;
|
||||||
constraint->pointer_destroy_listener.notify =
|
constraint->pointer_destroy_listener.notify =
|
||||||
|
|||||||
Reference in New Issue
Block a user