aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_idle.h17
-rw-r--r--types/wlr_idle.c112
2 files changed, 91 insertions, 38 deletions
diff --git a/include/wlr/types/wlr_idle.h b/include/wlr/types/wlr_idle.h
index d8c81a60..da268555 100644
--- a/include/wlr/types/wlr_idle.h
+++ b/include/wlr/types/wlr_idle.h
@@ -46,6 +46,12 @@ struct wlr_idle_timeout {
bool enabled;
uint32_t timeout; // milliseconds
+ struct {
+ struct wl_signal idle;
+ struct wl_signal resume;
+ struct wl_signal destroy;
+ } events;
+
struct wl_listener input_listener;
struct wl_listener seat_destroy;
@@ -68,4 +74,15 @@ void wlr_idle_notify_activity(struct wlr_idle *idle, struct wlr_seat *seat);
*/
void wlr_idle_set_enabled(struct wlr_idle *idle, struct wlr_seat *seat,
bool enabled);
+
+/**
+ * Create a new timer on the given seat. The idle event will be called after
+ * the given amount of milliseconds of inactivity, and the resumed event will
+ * be sent at the first user activty after the fired event.
+ */
+struct wlr_idle_timeout *wlr_idle_timeout_create(struct wlr_idle *idle,
+ struct wlr_seat *seat, uint32_t timeout);
+
+void wlr_idle_timeout_destroy(struct wlr_idle_timeout *timeout);
+
#endif
diff --git a/types/wlr_idle.c b/types/wlr_idle.c
index 29367ceb..7ea8cd76 100644
--- a/types/wlr_idle.c
+++ b/types/wlr_idle.c
@@ -16,22 +16,17 @@ static struct wlr_idle_timeout *idle_timeout_from_resource(
return wl_resource_get_user_data(resource);
}
-static void idle_timeout_destroy(struct wlr_idle_timeout *timer) {
- wl_list_remove(&timer->input_listener.link);
- wl_list_remove(&timer->seat_destroy.link);
- wl_event_source_remove(timer->idle_source);
- wl_list_remove(&timer->link);
- wl_resource_set_user_data(timer->resource, NULL);
- free(timer);
-}
-
static int idle_notify(void *data) {
struct wlr_idle_timeout *timer = data;
if (timer->idle_state) {
return 0;
}
timer->idle_state = true;
- org_kde_kwin_idle_timeout_send_idle(timer->resource);
+ wlr_signal_emit_safe(&timer->events.idle, timer);
+
+ if (timer->resource) {
+ org_kde_kwin_idle_timeout_send_idle(timer->resource);
+ }
return 1;
}
@@ -43,7 +38,11 @@ static void handle_activity(struct wlr_idle_timeout *timer) {
// in case the previous state was sleeping send a resume event and switch state
if (timer->idle_state) {
timer->idle_state = false;
- org_kde_kwin_idle_timeout_send_resumed(timer->resource);
+ wlr_signal_emit_safe(&timer->events.resume, timer);
+
+ if (timer->resource) {
+ org_kde_kwin_idle_timeout_send_resumed(timer->resource);
+ }
}
// rearm the timer
@@ -56,14 +55,14 @@ static void handle_activity(struct wlr_idle_timeout *timer) {
static void handle_timer_resource_destroy(struct wl_resource *timer_resource) {
struct wlr_idle_timeout *timer = idle_timeout_from_resource(timer_resource);
if (timer != NULL) {
- idle_timeout_destroy(timer);
+ wlr_idle_timeout_destroy(timer);
}
}
static void handle_seat_destroy(struct wl_listener *listener, void *data) {
struct wlr_idle_timeout *timer = wl_container_of(listener, timer, seat_destroy);
if (timer != NULL) {
- idle_timeout_destroy(timer);
+ wlr_idle_timeout_destroy(timer);
}
}
@@ -101,34 +100,23 @@ static void handle_input_notification(struct wl_listener *listener, void *data)
}
}
-static void create_idle_timer(struct wl_client *client,
- struct wl_resource *idle_resource, uint32_t id,
- struct wl_resource *seat_resource, uint32_t timeout) {
- struct wlr_idle *idle = idle_from_resource(idle_resource);
- struct wlr_seat_client *client_seat =
- wlr_seat_client_from_resource(seat_resource);
-
+static struct wlr_idle_timeout *create_timer(struct wlr_idle *idle,
+ struct wlr_seat *seat, uint32_t timeout, struct wl_resource *resource) {
struct wlr_idle_timeout *timer =
calloc(1, sizeof(struct wlr_idle_timeout));
if (!timer) {
- wl_resource_post_no_memory(idle_resource);
- return;
+ return NULL;
}
- timer->seat = client_seat->seat;
+
+ timer->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);
- if (timer->resource == NULL) {
- free(timer);
- wl_resource_post_no_memory(idle_resource);
- return;
- }
- wl_resource_set_implementation(timer->resource, &idle_timeout_impl, timer,
- handle_timer_resource_destroy);
+
wl_list_insert(&idle->idle_timers, &timer->link);
+ wl_signal_init(&timer->events.idle);
+ wl_signal_init(&timer->events.resume);
+ wl_signal_init(&timer->events.destroy);
timer->seat_destroy.notify = handle_seat_destroy;
wl_signal_add(&timer->seat->events.destroy, &timer->seat_destroy);
@@ -142,11 +130,15 @@ static void create_idle_timer(struct wl_client *client,
wl_list_remove(&timer->link);
wl_list_remove(&timer->input_listener.link);
wl_list_remove(&timer->seat_destroy.link);
- wl_resource_set_user_data(timer->resource, NULL);
free(timer);
- wl_resource_post_no_memory(idle_resource);
- return;
+ return NULL;
}
+
+ if (resource) {
+ timer->resource = resource;
+ wl_resource_set_user_data(resource, timer);
+ }
+
if (timer->enabled) {
// arm the timer
wl_event_source_timer_update(timer->idle_source, timer->timeout);
@@ -154,6 +146,30 @@ static void create_idle_timer(struct wl_client *client,
idle_notify(timer);
}
}
+
+ return timer;
+}
+
+static void create_idle_timer(struct wl_client *client,
+ struct wl_resource *idle_resource, uint32_t id,
+ struct wl_resource *seat_resource, uint32_t timeout) {
+ struct wlr_idle *idle = idle_from_resource(idle_resource);
+ struct wlr_seat_client *client_seat =
+ wlr_seat_client_from_resource(seat_resource);
+
+ struct wl_resource *resource = wl_resource_create(client,
+ &org_kde_kwin_idle_timeout_interface,
+ wl_resource_get_version(idle_resource), id);
+ if (resource == NULL) {
+ wl_resource_post_no_memory(idle_resource);
+ return;
+ }
+ wl_resource_set_implementation(resource, &idle_timeout_impl,
+ NULL, handle_timer_resource_destroy);
+
+ if (!create_timer(idle, client_seat->seat, timeout, resource)) {
+ wl_resource_post_no_memory(resource);
+ }
}
static const struct org_kde_kwin_idle_interface idle_impl = {
@@ -202,7 +218,7 @@ void wlr_idle_destroy(struct wlr_idle *idle) {
wl_list_remove(&idle->display_destroy.link);
struct wlr_idle_timeout *timer, *tmp;
wl_list_for_each_safe(timer, tmp, &idle->idle_timers, link) {
- idle_timeout_destroy(timer);
+ wlr_idle_timeout_destroy(timer);
}
wl_global_destroy(idle->global);
free(idle);
@@ -234,7 +250,7 @@ struct wlr_idle *wlr_idle_create(struct wl_display *display) {
idle->global = wl_global_create(display, &org_kde_kwin_idle_interface,
1, idle, idle_bind);
- if (idle->global == NULL){
+ if (idle->global == NULL) {
wl_list_remove(&idle->display_destroy.link);
free(idle);
return NULL;
@@ -246,3 +262,23 @@ struct wlr_idle *wlr_idle_create(struct wl_display *display) {
void wlr_idle_notify_activity(struct wlr_idle *idle, struct wlr_seat *seat) {
wlr_signal_emit_safe(&idle->events.activity_notify, seat);
}
+
+struct wlr_idle_timeout *wlr_idle_timeout_create(struct wlr_idle *idle,
+ struct wlr_seat *seat, uint32_t timeout) {
+ return create_timer(idle, seat, timeout, NULL);
+}
+
+void wlr_idle_timeout_destroy(struct wlr_idle_timeout *timer) {
+ wlr_signal_emit_safe(&timer->events.destroy, NULL);
+
+ wl_list_remove(&timer->input_listener.link);
+ wl_list_remove(&timer->seat_destroy.link);
+ wl_event_source_remove(timer->idle_source);
+ wl_list_remove(&timer->link);
+
+ if (timer->resource) {
+ wl_resource_set_user_data(timer->resource, NULL);
+ }
+
+ free(timer);
+}