Skip to content

Commit 6148c2d

Browse files
committed
dynamic timeouts
Compute notification timeouts on every config change, rather than only on notification creation.
1 parent 4d48aca commit 6148c2d

File tree

9 files changed

+58
-50
lines changed

9 files changed

+58
-50
lines changed

criteria.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,38 @@ struct mako_criteria *global_criteria(struct mako_config *config) {
418418
return criteria;
419419
}
420420

421-
// Iterate through `criteria_list`, applying the style from each matching
421+
static void timespec_add(struct timespec *t, int delta_ms) {
422+
static const long ms = 1000000, s = 1000000000;
423+
424+
int delta_ms_low = delta_ms % 1000;
425+
int delta_s_high = delta_ms / 1000;
426+
427+
t->tv_sec += delta_s_high;
428+
429+
t->tv_nsec += (long)delta_ms_low * ms;
430+
if (t->tv_nsec >= s) {
431+
t->tv_nsec -= s;
432+
++t->tv_sec;
433+
}
434+
}
435+
436+
static void handle_notification_timer(void *data) {
437+
struct mako_notification *notif = data;
438+
struct mako_surface *surface = notif->surface;
439+
notif->timer = NULL;
440+
441+
close_notification(notif, MAKO_NOTIFICATION_CLOSE_EXPIRED, true);
442+
set_dirty(surface);
443+
}
444+
445+
// Iterate through the criteria list, applying the style from each matching
422446
// criteria to `notif`. Returns the number of criteria that matched, or -1 if
423447
// a failure occurs.
424-
ssize_t apply_each_criteria(struct wl_list *criteria_list,
425-
struct mako_notification *notif) {
448+
ssize_t apply_each_criteria(struct mako_state *state, struct mako_notification *notif) {
426449
ssize_t match_count = 0;
427450

428451
struct mako_criteria *criteria;
429-
wl_list_for_each(criteria, criteria_list, link) {
452+
wl_list_for_each(criteria, &state->config.criteria, link) {
430453
if (!match_criteria(criteria, notif)) {
431454
continue;
432455
}
@@ -447,6 +470,25 @@ ssize_t apply_each_criteria(struct wl_list *criteria_list,
447470
}
448471
}
449472

473+
int32_t expire_timeout = notif->requested_timeout;
474+
if (expire_timeout < 0 || notif->style.ignore_timeout) {
475+
expire_timeout = notif->style.default_timeout;
476+
}
477+
478+
if (expire_timeout > 0) {
479+
struct timespec at = notif->at;
480+
timespec_add(&at, expire_timeout);
481+
if (notif->timer) {
482+
notif->timer->at = at;
483+
} else {
484+
notif->timer = add_event_loop_timer(&state->event_loop, &at,
485+
handle_notification_timer, notif);
486+
}
487+
} else if (notif->timer) {
488+
destroy_timer(notif->timer);
489+
notif->timer = NULL;
490+
}
491+
450492
if (!notif->surface) {
451493
notif->surface = create_surface(notif->state, notif->style.output,
452494
notif->style.layer, notif->style.anchor);

dbus/mako.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ static void reapply_config(struct mako_state *state) {
305305

306306
finish_style(&notif->style);
307307
init_empty_style(&notif->style);
308-
apply_each_criteria(&state->config.criteria, notif);
308+
apply_each_criteria(state, notif);
309309

310310
// Having to do this for every single notification really hurts... but
311311
// it does do The Right Thing (tm).

dbus/xdg.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,6 @@ static int handle_get_capabilities(sd_bus_message *msg, void *data,
8181
return 0;
8282
}
8383

84-
static void handle_notification_timer(void *data) {
85-
struct mako_notification *notif = data;
86-
struct mako_surface *surface = notif->surface;
87-
notif->timer = NULL;
88-
89-
close_notification(notif, MAKO_NOTIFICATION_CLOSE_EXPIRED, true);
90-
set_dirty(surface);
91-
}
92-
9384
static int handle_notify(sd_bus_message *msg, void *data,
9485
sd_bus_error *ret_error) {
9586
struct mako_state *state = data;
@@ -382,7 +373,7 @@ static int handle_notify(sd_bus_message *msg, void *data,
382373
insert_notification(state, notif);
383374
}
384375

385-
int match_count = apply_each_criteria(&state->config.criteria, notif);
376+
int match_count = apply_each_criteria(state, notif);
386377
if (match_count == -1) {
387378
// We encountered an allocation failure or similar while applying
388379
// criteria. The notification may be partially matched, but the worst
@@ -398,16 +389,6 @@ static int handle_notify(sd_bus_message *msg, void *data,
398389
return -1;
399390
}
400391

401-
int32_t expire_timeout = notif->requested_timeout;
402-
if (expire_timeout < 0 || notif->style.ignore_timeout) {
403-
expire_timeout = notif->style.default_timeout;
404-
}
405-
406-
if (expire_timeout > 0) {
407-
notif->timer = add_event_loop_timer(&state->event_loop, expire_timeout,
408-
handle_notification_timer, notif);
409-
}
410-
411392
if (notif->style.icons) {
412393
notif->icon = create_icon(notif);
413394
}

event-loop.c

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,6 @@ void finish_event_loop(struct mako_event_loop *loop) {
7474
}
7575
}
7676

77-
static void timespec_add(struct timespec *t, int delta_ms) {
78-
static const long ms = 1000000, s = 1000000000;
79-
80-
int delta_ms_low = delta_ms % 1000;
81-
int delta_s_high = delta_ms / 1000;
82-
83-
t->tv_sec += delta_s_high;
84-
85-
t->tv_nsec += (long)delta_ms_low * ms;
86-
if (t->tv_nsec >= s) {
87-
t->tv_nsec -= s;
88-
++t->tv_sec;
89-
}
90-
}
91-
9277
static bool timespec_less(struct timespec *t1, struct timespec *t2) {
9378
if (t1->tv_sec != t2->tv_sec) {
9479
return t1->tv_sec < t2->tv_sec;
@@ -124,7 +109,7 @@ static void update_event_loop_timer(struct mako_event_loop *loop) {
124109
}
125110

126111
struct mako_timer *add_event_loop_timer(struct mako_event_loop *loop,
127-
int delay_ms, mako_event_loop_timer_func_t func, void *data) {
112+
struct timespec *at, mako_event_loop_timer_func_t func, void *data) {
128113
struct mako_timer *timer = calloc(1, sizeof(struct mako_timer));
129114
if (timer == NULL) {
130115
fprintf(stderr, "allocation failed\n");
@@ -133,10 +118,7 @@ struct mako_timer *add_event_loop_timer(struct mako_event_loop *loop,
133118
timer->event_loop = loop;
134119
timer->func = func;
135120
timer->user_data = data;
136-
wl_list_insert(&loop->timers, &timer->link);
137-
138-
clock_gettime(CLOCK_MONOTONIC, &timer->at);
139-
timespec_add(&timer->at, delay_ms);
121+
timer->at = *at;
140122

141123
update_event_loop_timer(loop);
142124
return timer;

include/criteria.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <wayland-client.h>
88
#include "config.h"
99
#include "types.h"
10+
#include "mako.h"
1011

1112
struct mako_config;
1213
struct mako_notification;
@@ -53,8 +54,7 @@ bool parse_criteria(const char *string, struct mako_criteria *criteria);
5354
bool apply_criteria_field(struct mako_criteria *criteria, char *token);
5455

5556
struct mako_criteria *global_criteria(struct mako_config *config);
56-
ssize_t apply_each_criteria(struct wl_list *criteria_list,
57-
struct mako_notification *notif);
57+
ssize_t apply_each_criteria(struct mako_state *state, struct mako_notification *notif);
5858
struct mako_criteria *create_criteria_from_notification(
5959
struct mako_notification *notif, struct mako_criteria_spec *spec);
6060

include/event-loop.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ bool init_event_loop(struct mako_event_loop *loop, sd_bus *bus,
4747
void finish_event_loop(struct mako_event_loop *loop);
4848
int run_event_loop(struct mako_event_loop *loop);
4949
struct mako_timer *add_event_loop_timer(struct mako_event_loop *loop,
50-
int delay_ms, mako_event_loop_timer_func_t func, void *data);
50+
struct timespec *at, mako_event_loop_timer_func_t func, void *data);
5151

5252
void destroy_timer(struct mako_timer *timer);
5353

include/notification.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct mako_notification {
4848

4949
struct mako_hotspot hotspot;
5050
struct mako_timer *timer;
51+
struct timespec at;
5152
};
5253

5354
struct mako_action {

notification.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ void reset_notification(struct mako_notification *notif) {
6666

6767
destroy_icon(notif->icon);
6868
notif->icon = NULL;
69+
70+
clock_gettime(CLOCK_MONOTONIC, &notif->at);
6971
}
7072

7173
struct mako_notification *create_notification(struct mako_state *state) {

render.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ void render(struct mako_surface *surface, struct pool_buffer *buffer, int scale,
355355
// Immediately before rendering we need to re-match all of the criteria
356356
// so that matches against the anchor and output work even if the
357357
// output was automatically assigned by the compositor.
358-
int rematch_count = apply_each_criteria(&state->config.criteria, notif);
358+
int rematch_count = apply_each_criteria(state, notif);
359359
if (rematch_count == -1) {
360360
// We encountered an allocation failure or similar while applying
361361
// criteria. The notification may be partially matched, but the
@@ -427,7 +427,7 @@ void render(struct mako_surface *surface, struct pool_buffer *buffer, int scale,
427427
struct mako_notification *hidden_notif = create_notification(state);
428428
hidden_notif->surface = surface;
429429
hidden_notif->hidden = true;
430-
apply_each_criteria(&state->config.criteria, hidden_notif);
430+
apply_each_criteria(state, hidden_notif);
431431

432432
struct mako_style *style = &hidden_notif->style;
433433

0 commit comments

Comments
 (0)