idle_inhibit: Store wlr inhibitor instead of view

When an application inhibited idle, a view pointer was stored and a
destroy listener was registered to the wlr inhibitor. As the wlr
inhibitor lives longer than the view, this lead to a dangling view
pointer between view unmap and inhibitor destroy.

Store a pointer to the wlr inhibitor instead of to the view, and look up
the view when needed, which may at any point be NULL. This also allows
for an inhibitor to remain functional if a surface is re-mapped.
This commit is contained in:
Kenny Levinsen 2021-03-20 12:30:53 +01:00 committed by Simon Ser
parent 70842f4e14
commit 152a559e30
2 changed files with 5 additions and 4 deletions

View file

@ -22,6 +22,7 @@ struct sway_idle_inhibit_manager_v1 {
struct sway_idle_inhibitor_v1 {
struct sway_idle_inhibit_manager_v1 *manager;
struct wlr_idle_inhibitor_v1 *wlr_inhibitor;
struct sway_view *view;
enum sway_idle_inhibit_mode mode;

View file

@ -36,7 +36,7 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
inhibitor->manager = manager;
inhibitor->mode = INHIBIT_IDLE_APPLICATION;
inhibitor->view = view_from_wlr_surface(wlr_inhibitor->surface);
inhibitor->wlr_inhibitor = wlr_inhibitor;
wl_list_insert(&manager->inhibitors, &inhibitor->link);
inhibitor->destroy.notify = handle_destroy;
@ -104,10 +104,10 @@ void sway_idle_inhibit_v1_user_inhibitor_destroy(
bool sway_idle_inhibit_v1_is_active(struct sway_idle_inhibitor_v1 *inhibitor) {
switch (inhibitor->mode) {
case INHIBIT_IDLE_APPLICATION:
case INHIBIT_IDLE_APPLICATION:;
// If there is no view associated with the inhibitor, assume visible
return !inhibitor->view || !inhibitor->view->container ||
view_is_visible(inhibitor->view);
struct sway_view *view = view_from_wlr_surface(inhibitor->wlr_inhibitor->surface);
return !view || !view->container || view_is_visible(view);
case INHIBIT_IDLE_FOCUS:;
struct sway_seat *seat = NULL;
wl_list_for_each(seat, &server.input->seats, link) {