diff --git a/include/wlr/types/wlr_idle.h b/include/wlr/types/wlr_idle.h index 45f350be..aca9146c 100644 --- a/include/wlr/types/wlr_idle.h +++ b/include/wlr/types/wlr_idle.h @@ -17,6 +17,7 @@ struct wlr_idle { struct wl_global *wl_global; struct wl_list idle_timers; // wlr_idle_timeout::link struct wl_event_loop *event_loop; + bool enabled; struct wl_listener display_destroy; struct { @@ -33,6 +34,7 @@ struct wlr_idle_timeout { struct wl_event_source *idle_source; bool idle_state; + bool enabled; uint32_t timeout; // milliseconds struct wl_listener input_listener; @@ -50,4 +52,11 @@ void wlr_idle_destroy(struct wlr_idle *idle); * compositor when there is an user activity event on that seat. */ void wlr_idle_notify_activity(struct wlr_idle *idle, struct wlr_seat *seat); + +/** + * Enable or disable timers for a given idle resource by seat. + * Passing a NULL seat means update timers for all seats. + */ +void wlr_idle_set_enabled(struct wlr_idle *idle, struct wlr_seat *seat, + bool enabled); #endif diff --git a/types/wlr_idle.c b/types/wlr_idle.c index a3981479..fffb8d55 100644 --- a/types/wlr_idle.c +++ b/types/wlr_idle.c @@ -33,6 +33,9 @@ static int idle_notify(void *data) { } static void handle_activity(struct wlr_idle_timeout *timer) { + if (!timer->enabled) { + return; + } // rearm the timer wl_event_source_timer_update(timer->idle_source, timer->timeout); // in case the previous state was sleeping send a resume event and switch state @@ -106,6 +109,7 @@ static void create_idle_timer(struct wl_client *client, timer->seat = client_seat->seat; timer->timeout = timeout; timer->idle_state = false; + timer->enabled = idle->enabled; timer->resource = wl_resource_create(client, &org_kde_kwin_idle_timeout_interface, wl_resource_get_version(idle_resource), id); @@ -135,14 +139,36 @@ static void create_idle_timer(struct wl_client *client, wl_resource_post_no_memory(idle_resource); return; } - // arm the timer - wl_event_source_timer_update(timer->idle_source, timer->timeout); + if (timer->enabled) { + // arm the timer + wl_event_source_timer_update(timer->idle_source, timer->timeout); + } } static const struct org_kde_kwin_idle_interface idle_impl = { .get_idle_timeout = create_idle_timer, }; +void wlr_idle_set_enabled(struct wlr_idle *idle, struct wlr_seat *seat, + bool enabled) { + if (idle->enabled == enabled) { + return; + } + wlr_log(L_DEBUG, "%s idle timers for %s", + enabled ? "Enabling" : "Disabling", + seat ? seat->name : "all seats"); + idle->enabled = enabled; + struct wlr_idle_timeout *timer; + wl_list_for_each(timer, &idle->idle_timers, link) { + if (seat != NULL && timer->seat != seat) { + continue; + } + int timeout = enabled ? timer->timeout : 0; + wl_event_source_timer_update(timer->idle_source, timeout); + timer->enabled = enabled; + } +} + static void idle_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id) { struct wlr_idle *idle = data; @@ -182,6 +208,7 @@ struct wlr_idle *wlr_idle_create(struct wl_display *display) { } wl_list_init(&idle->idle_timers); wl_signal_init(&idle->events.activity_notify); + idle->enabled = true; idle->event_loop = wl_display_get_event_loop(display); if (idle->event_loop == NULL) {