Use gint64 as microseconds for internal timeunit
time(NULL) is vulnerable against timeshifts by NTP, timezones,... g_get_monotonic_time() is not, but counts its in microseconds with the gint64 datatype. To prevent any conversion bugs, all internal timeformats are now using a gint64 and only get converted during import or export (DBus notification arrives, configuration reading, age threshold display).
This commit is contained in:
parent
7a02d8e48a
commit
956b5c6401
@ -10,7 +10,7 @@ char *lowbgcolor = "#aaaaff";
|
||||
char *lowfgcolor = "#000000";
|
||||
char *format = "%s %b"; /* default format */
|
||||
|
||||
int timeouts[] = { 10, 10, 0 }; /* low, normal, critical */
|
||||
gint64 timeouts[] = { 10*G_USEC_PER_SEC, 10*G_USEC_PER_SEC, 0 }; /* low, normal, critical */
|
||||
char *icons[] = { "dialog-information", "dialog-information", "dialog-warning" }; /* low, normal, critical */
|
||||
|
||||
unsigned int transparency = 0; /* transparency */
|
||||
@ -20,8 +20,8 @@ char *class = "Dunst"; /* the class of dunst notification windows */
|
||||
int shrink = false; /* shrinking */
|
||||
int sort = true; /* sort messages by urgency */
|
||||
int indicate_hidden = true; /* show count of hidden messages */
|
||||
int idle_threshold = 0; /* don't timeout notifications when idle for x seconds */
|
||||
int show_age_threshold = -1; /* show age of notification, when notification is older than x seconds */
|
||||
gint64 idle_threshold = 0; /* don't timeout notifications when idle for x seconds */
|
||||
gint64 show_age_threshold = -1; /* show age of notification, when notification is older than x seconds */
|
||||
enum alignment align = left; /* text alignment [left/center/right] */
|
||||
int sticky_history = true;
|
||||
int history_length = 20; /* max amount of notifications kept in history */
|
||||
|
10
src/dbus.c
10
src/dbus.c
@ -236,21 +236,13 @@ static void on_notify(GDBusConnection *connection,
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
if (timeout > 0) {
|
||||
/* do some rounding */
|
||||
timeout = (timeout + 500) / 1000;
|
||||
if (timeout < 1) {
|
||||
timeout = 1;
|
||||
}
|
||||
}
|
||||
|
||||
notification *n = notification_create();
|
||||
n->appname = appname;
|
||||
n->summary = summary;
|
||||
n->body = body;
|
||||
n->icon = icon;
|
||||
n->raw_icon = raw_icon;
|
||||
n->timeout = timeout;
|
||||
n->timeout = timeout < 0 ? -1 : timeout * 1000;
|
||||
n->markup = settings.markup;
|
||||
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
||||
n->urgency = urgency;
|
||||
|
55
src/dunst.c
55
src/dunst.c
@ -12,7 +12,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "dbus.h"
|
||||
#include "menu.h"
|
||||
@ -70,7 +69,7 @@ void check_timeouts(void)
|
||||
|
||||
/* don't timeout when user is idle */
|
||||
if (x_is_idle() && !n->transient) {
|
||||
n->start = time(NULL);
|
||||
n->start = g_get_monotonic_time();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -80,7 +79,7 @@ void check_timeouts(void)
|
||||
}
|
||||
|
||||
/* remove old message */
|
||||
if (difftime(time(NULL), n->start) > n->timeout) {
|
||||
if (g_get_monotonic_time() - n->start > n->timeout) {
|
||||
notification_close(n, 1);
|
||||
}
|
||||
}
|
||||
@ -122,7 +121,7 @@ void update_lists()
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
n->start = time(NULL);
|
||||
n->start = g_get_monotonic_time();
|
||||
if (!n->redisplayed && n->script) {
|
||||
notification_run_script(n);
|
||||
}
|
||||
@ -173,49 +172,37 @@ void wake_up(void)
|
||||
run(NULL);
|
||||
}
|
||||
|
||||
static int get_sleep_time(void)
|
||||
static gint64 get_sleep_time(void)
|
||||
{
|
||||
gint64 sleep = G_MAXINT64;
|
||||
|
||||
if (settings.show_age_threshold == 0) {
|
||||
/* we need to update every second */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int min_ttl = INT_MAX;
|
||||
int max_age = 0;
|
||||
gint64 max_age = 0;
|
||||
for (GList *iter = g_queue_peek_head_link(displayed); iter;
|
||||
iter = iter->next) {
|
||||
notification *n = iter->data;
|
||||
|
||||
max_age = MAX(max_age, notification_get_age(n));
|
||||
int ttl = notification_get_ttl(n);
|
||||
if (ttl >= 0) {
|
||||
min_ttl = MIN(min_ttl, ttl);
|
||||
}
|
||||
gint64 ttl = notification_get_ttl(n);
|
||||
if (ttl >= 0)
|
||||
sleep = MIN(sleep, ttl);
|
||||
}
|
||||
|
||||
int min_timeout;
|
||||
int show_age_timeout = settings.show_age_threshold - max_age;
|
||||
|
||||
if (show_age_timeout < 1) {
|
||||
return 1;
|
||||
/* if age_threshold is hit, seconds have to get updated every second */
|
||||
if (settings.show_age_threshold >= 0) {
|
||||
if (settings.show_age_threshold > max_age)
|
||||
sleep = MIN(sleep, settings.show_age_threshold - max_age);
|
||||
else
|
||||
sleep = MIN(sleep, 1000*1000);
|
||||
}
|
||||
|
||||
min_timeout = MIN(show_age_timeout, min_ttl);
|
||||
|
||||
/* show_age_timeout might be negative */
|
||||
if (min_timeout < 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return min_timeout;
|
||||
}
|
||||
return sleep;
|
||||
}
|
||||
|
||||
gboolean run(void *data)
|
||||
{
|
||||
update_lists();
|
||||
static int timeout_cnt = 0;
|
||||
static int next_timeout = 0;
|
||||
static gint64 next_timeout = 0;
|
||||
|
||||
if (data) {
|
||||
timeout_cnt--;
|
||||
@ -234,13 +221,13 @@ gboolean run(void *data)
|
||||
}
|
||||
|
||||
if (xctx.visible) {
|
||||
int now = time(NULL);
|
||||
int sleep = get_sleep_time();
|
||||
gint64 now = g_get_monotonic_time();
|
||||
gint64 sleep = get_sleep_time();
|
||||
gint64 timeout_at = now + sleep;
|
||||
|
||||
if (sleep > 0) {
|
||||
int timeout_at = now + sleep;
|
||||
if (timeout_cnt == 0 || timeout_at < next_timeout) {
|
||||
g_timeout_add_seconds(sleep, run, mainloop);
|
||||
g_timeout_add(sleep/1000, run, mainloop);
|
||||
next_timeout = timeout_at;
|
||||
timeout_cnt++;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
@ -39,7 +38,7 @@ void notification_print(notification *n)
|
||||
printf("\ticon: '%s'\n", n->icon);
|
||||
printf("\traw_icon set: %s\n", (n->raw_icon ? "true" : "false"));
|
||||
printf("\tcategory: %s\n", n->category);
|
||||
printf("\ttimeout: %d\n", n->timeout);
|
||||
printf("\ttimeout: %ld\n", n->timeout/1000);
|
||||
printf("\turgency: %d\n", n->urgency);
|
||||
printf("\ttransient: %d\n", n->transient);
|
||||
printf("\tformatted: '%s'\n", n->msg);
|
||||
@ -478,7 +477,7 @@ int notification_init(notification *n, int id)
|
||||
} else {
|
||||
orig->progress = n->progress;
|
||||
}
|
||||
orig->start = time(NULL);
|
||||
orig->start = g_get_monotonic_time();
|
||||
notification_free(n);
|
||||
wake_up();
|
||||
return orig->id;
|
||||
@ -502,10 +501,10 @@ int notification_init(notification *n, int id)
|
||||
}
|
||||
|
||||
n->timeout =
|
||||
n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout;
|
||||
n->timeout < 0 ? settings.timeouts[n->urgency] : n->timeout;
|
||||
n->start = 0;
|
||||
|
||||
n->timestamp = time(NULL);
|
||||
n->timestamp = g_get_monotonic_time();
|
||||
|
||||
n->redisplayed = false;
|
||||
|
||||
@ -671,26 +670,26 @@ void notification_update_text_to_render(notification *n)
|
||||
}
|
||||
|
||||
/* print age */
|
||||
int hours, minutes, seconds;
|
||||
time_t t_delta = time(NULL) - n->timestamp;
|
||||
gint64 hours, minutes, seconds;
|
||||
gint64 t_delta = g_get_monotonic_time() - n->timestamp;
|
||||
|
||||
if (settings.show_age_threshold >= 0
|
||||
&& t_delta >= settings.show_age_threshold) {
|
||||
hours = t_delta / 3600;
|
||||
minutes = t_delta / 60 % 60;
|
||||
seconds = t_delta % 60;
|
||||
hours = t_delta / G_USEC_PER_SEC / 3600;
|
||||
minutes = t_delta / G_USEC_PER_SEC / 60 % 60;
|
||||
seconds = t_delta / G_USEC_PER_SEC % 60;
|
||||
|
||||
char *new_buf;
|
||||
if (hours > 0) {
|
||||
new_buf =
|
||||
g_strdup_printf("%s (%dh %dm %ds old)", buf, hours,
|
||||
g_strdup_printf("%s (%ldh %ldm %lds old)", buf, hours,
|
||||
minutes, seconds);
|
||||
} else if (minutes > 0) {
|
||||
new_buf =
|
||||
g_strdup_printf("%s (%dm %ds old)", buf, minutes,
|
||||
g_strdup_printf("%s (%ldm %lds old)", buf, minutes,
|
||||
seconds);
|
||||
} else {
|
||||
new_buf = g_strdup_printf("%s (%ds old)", buf, seconds);
|
||||
new_buf = g_strdup_printf("%s (%lds old)", buf, seconds);
|
||||
}
|
||||
|
||||
g_free(buf);
|
||||
@ -700,16 +699,16 @@ void notification_update_text_to_render(notification *n)
|
||||
n->text_to_render = buf;
|
||||
}
|
||||
|
||||
int notification_get_ttl(notification *n) {
|
||||
if (n->timeout == 0) {
|
||||
gint64 notification_get_ttl(notification *n) {
|
||||
if (n->timeout < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return n->timeout - (time(NULL) - n->start);
|
||||
return n->timeout - (g_get_monotonic_time() - n->start);
|
||||
}
|
||||
}
|
||||
|
||||
int notification_get_age(notification *n) {
|
||||
return time(NULL) - n->timestamp;
|
||||
gint64 notification_get_age(notification *n) {
|
||||
return g_get_monotonic_time() - n->timestamp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
@ -42,9 +41,9 @@ typedef struct _notification {
|
||||
char *text_to_render;
|
||||
const char *format;
|
||||
char *dbus_client;
|
||||
time_t start;
|
||||
time_t timestamp;
|
||||
int timeout;
|
||||
gint64 start;
|
||||
gint64 timestamp;
|
||||
gint64 timeout;
|
||||
int urgency;
|
||||
enum markup_mode markup;
|
||||
bool redisplayed; /* has been displayed before? */
|
||||
@ -75,8 +74,8 @@ int notification_close(notification *n, int reason);
|
||||
void notification_print(notification *n);
|
||||
void notification_replace_single_field(char **haystack, char **needle, const char *replacement, enum markup_mode markup_mode);
|
||||
void notification_update_text_to_render(notification *n);
|
||||
int notification_get_ttl(notification *n);
|
||||
int notification_get_age(notification *n);
|
||||
gint64 notification_get_ttl(notification *n);
|
||||
gint64 notification_get_age(notification *n);
|
||||
void notification_do_action(notification *n);
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@ typedef struct _rule_t {
|
||||
int msg_urgency;
|
||||
|
||||
/* actions */
|
||||
int timeout;
|
||||
gint64 timeout;
|
||||
int urgency;
|
||||
enum markup_mode markup;
|
||||
int history_ignore;
|
||||
|
@ -197,7 +197,7 @@ void load_settings(char *cmdline_config_path)
|
||||
"Ignore newline characters in notifications"
|
||||
);
|
||||
|
||||
settings.idle_threshold = option_get_int(
|
||||
settings.idle_threshold = G_USEC_PER_SEC * option_get_int(
|
||||
"global",
|
||||
"idle_threshold", "-idle_threshold", idle_threshold,
|
||||
"Don't timeout notifications if user is longer idle than threshold"
|
||||
@ -279,7 +279,7 @@ void load_settings(char *cmdline_config_path)
|
||||
}
|
||||
}
|
||||
|
||||
settings.show_age_threshold = option_get_int(
|
||||
settings.show_age_threshold = G_USEC_PER_SEC * option_get_int(
|
||||
"global",
|
||||
"show_age_threshold", "-show_age_threshold", show_age_threshold,
|
||||
"When should the age of the notification be displayed?"
|
||||
@ -490,7 +490,7 @@ void load_settings(char *cmdline_config_path)
|
||||
"Frame color for notifications with low urgency"
|
||||
);
|
||||
|
||||
settings.timeouts[LOW] = option_get_int(
|
||||
settings.timeouts[LOW] = G_USEC_PER_SEC * option_get_int(
|
||||
"urgency_low",
|
||||
"timeout", "-lto", timeouts[LOW],
|
||||
"Timeout for notifications with low urgency"
|
||||
@ -520,7 +520,7 @@ void load_settings(char *cmdline_config_path)
|
||||
"Frame color for notifications with normal urgency"
|
||||
);
|
||||
|
||||
settings.timeouts[NORM] = option_get_int(
|
||||
settings.timeouts[NORM] = G_USEC_PER_SEC * option_get_int(
|
||||
"urgency_normal",
|
||||
"timeout", "-nto", timeouts[NORM],
|
||||
"Timeout for notifications with normal urgency"
|
||||
@ -550,7 +550,7 @@ void load_settings(char *cmdline_config_path)
|
||||
"Frame color for notifications with critical urgency"
|
||||
);
|
||||
|
||||
settings.timeouts[CRIT] = option_get_int(
|
||||
settings.timeouts[CRIT] = G_USEC_PER_SEC * option_get_int(
|
||||
"urgency_critical",
|
||||
"timeout", "-cto", timeouts[CRIT],
|
||||
"Timeout for notifications with critical urgency"
|
||||
@ -637,7 +637,7 @@ void load_settings(char *cmdline_config_path)
|
||||
r->body = ini_get_string(cur_section, "body", r->body);
|
||||
r->icon = ini_get_string(cur_section, "icon", r->icon);
|
||||
r->category = ini_get_string(cur_section, "category", r->category);
|
||||
r->timeout = ini_get_int(cur_section, "timeout", r->timeout);
|
||||
r->timeout = G_USEC_PER_SEC * ini_get_int(cur_section, "timeout", r->timeout);
|
||||
|
||||
{
|
||||
char *c = ini_get_string(
|
||||
|
@ -30,7 +30,7 @@ typedef struct _settings {
|
||||
char *lowfgcolor;
|
||||
char *lowframecolor;
|
||||
char *format;
|
||||
int timeouts[3];
|
||||
gint64 timeouts[3];
|
||||
char *icons[3];
|
||||
unsigned int transparency;
|
||||
char *geom;
|
||||
@ -39,8 +39,8 @@ typedef struct _settings {
|
||||
int shrink;
|
||||
int sort;
|
||||
int indicate_hidden;
|
||||
int idle_threshold;
|
||||
int show_age_threshold;
|
||||
gint64 idle_threshold;
|
||||
gint64 show_age_threshold;
|
||||
enum alignment align;
|
||||
int sticky_history;
|
||||
int history_length;
|
||||
|
@ -900,7 +900,7 @@ bool x_is_idle(void)
|
||||
if (settings.idle_threshold == 0) {
|
||||
return false;
|
||||
}
|
||||
return xctx.screensaver_info->idle / 1000 > settings.idle_threshold;
|
||||
return xctx.screensaver_info->idle > settings.idle_threshold / 1000;
|
||||
}
|
||||
|
||||
/* TODO move to x_mainloop_* */
|
||||
|
Loading…
x
Reference in New Issue
Block a user