diff --git a/src/dunst.c b/src/dunst.c index c76e078..2bf6899 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -19,6 +19,7 @@ #include "option_parser.h" #include "queues.h" #include "settings.h" +#include "utils.h" #include "x11/screen.h" #include "x11/x.h" @@ -70,7 +71,7 @@ static gboolean run(void *data) } if (xctx.visible) { - gint64 now = g_get_monotonic_time(); + gint64 now = time_monotonic_now(); gint64 sleep = queues_get_next_datachange(now); gint64 timeout_at = now + sleep; diff --git a/src/notification.c b/src/notification.c index b54b79f..d3d8445 100644 --- a/src/notification.c +++ b/src/notification.c @@ -290,7 +290,7 @@ notification *notification_create(void) n->markup = settings.markup; n->format = settings.format; - n->timestamp = g_get_monotonic_time(); + n->timestamp = time_monotonic_now(); n->urgency = URG_NORM; n->timeout = -1; @@ -528,7 +528,7 @@ void notification_update_text_to_render(notification *n) /* print age */ gint64 hours, minutes, seconds; - gint64 t_delta = g_get_monotonic_time() - n->timestamp; + gint64 t_delta = time_monotonic_now() - n->timestamp; if (settings.show_age_threshold >= 0 && t_delta >= settings.show_age_threshold) { diff --git a/src/queues.c b/src/queues.c index cf229a2..e64172d 100644 --- a/src/queues.c +++ b/src/queues.c @@ -23,6 +23,7 @@ #include "log.h" #include "notification.h" #include "settings.h" +#include "utils.h" /* notification lists */ static GQueue *waiting = NULL; /**< all new notifications get into here */ @@ -133,7 +134,7 @@ static bool queues_stack_duplicate(notification *n) iter->data = n; - n->start = g_get_monotonic_time(); + n->start = time_monotonic_now(); n->dup_count = orig->dup_count; @@ -180,7 +181,7 @@ bool queues_notification_replace_id(notification *new) notification *old = iter->data; if (old->id == new->id) { iter->data = new; - new->start = g_get_monotonic_time(); + new->start = time_monotonic_now(); new->dup_count = old->dup_count; notification_run_script(new); notification_free(old); @@ -305,7 +306,7 @@ void queues_check_timeouts(bool idle, bool fullscreen) /* don't timeout when user is idle */ if (is_idle && !n->transient) { - n->start = g_get_monotonic_time(); + n->start = time_monotonic_now(); continue; } @@ -315,7 +316,7 @@ void queues_check_timeouts(bool idle, bool fullscreen) } /* remove old message */ - if (g_get_monotonic_time() - n->start > n->timeout) { + if (time_monotonic_now() - n->start > n->timeout) { queues_notification_close(n, REASON_TIME); } } @@ -368,7 +369,7 @@ void queues_update(bool fullscreen) continue; } - n->start = g_get_monotonic_time(); + n->start = time_monotonic_now(); if (!n->redisplayed && n->script) { notification_run_script(n); diff --git a/src/utils.c b/src/utils.c index 8d2f00e..6eda3bc 100644 --- a/src/utils.c +++ b/src/utils.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "log.h" @@ -166,4 +167,21 @@ gint64 string_to_time(const char *string) return 0; } +/* see utils.h */ +gint64 time_monotonic_now(void) +{ + struct timespec tv_now; + + /* On Linux, BOOTTIME is the correct monotonic time, + * as BOOTTIME counts onwards during sleep. For all other + * POSIX compliant OSes, MONOTONIC should also count onwards + * during system sleep. */ +#ifdef __linux__ + clock_gettime(CLOCK_BOOTTIME, &tv_now); +#else + clock_gettime(CLOCK_MONOTONIC, &tv_now); +#endif + return (gint64)tv_now.tv_sec * G_USEC_PER_SEC + + tv_now.tv_nsec / 1000; +} /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ diff --git a/src/utils.h b/src/utils.h index 874bb49..48ee618 100644 --- a/src/utils.h +++ b/src/utils.h @@ -27,5 +27,14 @@ char *string_to_path(char *string); /* convert time units (ms, s, m) to internal gint64 microseconds */ gint64 string_to_time(const char *string); +/** + * Get the current monotonic time. In contrast to `g_get_monotonic_time`, + * this function respects the real monotonic time of the system and + * counts onwards during system sleep. + * + * @returns: A `gint64` monotonic time representation + */ +gint64 time_monotonic_now(void); + #endif /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */