commit
fe2a3b5049
@ -10,7 +10,7 @@ char *lowbgcolor = "#aaaaff";
|
|||||||
char *lowfgcolor = "#000000";
|
char *lowfgcolor = "#000000";
|
||||||
char *format = "%s %b"; /* default format */
|
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 */
|
char *icons[] = { "dialog-information", "dialog-information", "dialog-warning" }; /* low, normal, critical */
|
||||||
|
|
||||||
unsigned int transparency = 0; /* transparency */
|
unsigned int transparency = 0; /* transparency */
|
||||||
@ -20,8 +20,8 @@ char *class = "Dunst"; /* the class of dunst notification windows */
|
|||||||
int shrink = false; /* shrinking */
|
int shrink = false; /* shrinking */
|
||||||
int sort = true; /* sort messages by urgency */
|
int sort = true; /* sort messages by urgency */
|
||||||
int indicate_hidden = true; /* show count of hidden messages */
|
int indicate_hidden = true; /* show count of hidden messages */
|
||||||
int idle_threshold = 0; /* don't timeout notifications when idle for x seconds */
|
gint64 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 show_age_threshold = -1; /* show age of notification, when notification is older than x seconds */
|
||||||
enum alignment align = left; /* text alignment [left/center/right] */
|
enum alignment align = left; /* text alignment [left/center/right] */
|
||||||
int sticky_history = true;
|
int sticky_history = true;
|
||||||
int history_length = 20; /* max amount of notifications kept in history */
|
int history_length = 20; /* max amount of notifications kept in history */
|
||||||
|
@ -230,7 +230,8 @@ If set to true, display notifications with higher urgency above the others.
|
|||||||
|
|
||||||
=item B<idle_threshold> (default: 0)
|
=item B<idle_threshold> (default: 0)
|
||||||
|
|
||||||
Don't timeout notifications if user is idle longer than this value (in seconds).
|
Don't timeout notifications if user is idle longer than this time.
|
||||||
|
See TIME FORMAT for valid times.
|
||||||
|
|
||||||
Set to 0 to disable.
|
Set to 0 to disable.
|
||||||
|
|
||||||
@ -338,7 +339,8 @@ Defines how the text should be aligned within the notification.
|
|||||||
|
|
||||||
=item B<show_age_threshold> (default: -1)
|
=item B<show_age_threshold> (default: -1)
|
||||||
|
|
||||||
Show age of message if message is older than this value (in seconds).
|
Show age of message if message is older than this time.
|
||||||
|
See TIME FORMAT for valid times.
|
||||||
|
|
||||||
Set to -1 to disable.
|
Set to -1 to disable.
|
||||||
|
|
||||||
@ -533,8 +535,9 @@ See COLORS for more information
|
|||||||
|
|
||||||
=item B<-lto/nto/cto secs>
|
=item B<-lto/nto/cto secs>
|
||||||
|
|
||||||
Defines the timeout time(in seconds) for low, normal and critical notifications
|
Defines the timeout time for low, normal and critical notifications
|
||||||
respectively.
|
respectively.
|
||||||
|
See TIME FORMAT for valid times.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
@ -661,6 +664,15 @@ If there is exactly one associated action, or one is marked as default, that one
|
|||||||
is invoked. If there are multiple, the context menu is shown. The same applies
|
is invoked. If there are multiple, the context menu is shown. The same applies
|
||||||
to URLs when there are no actions.
|
to URLs when there are no actions.
|
||||||
|
|
||||||
|
=head1 TIME FORMAT
|
||||||
|
|
||||||
|
A time can be any decimal integer value suffixed with a time unit. If no unit
|
||||||
|
given, seconds ("s") is taken as default.
|
||||||
|
|
||||||
|
Time units understood by dunst are "ms", "s", "m", "h" and "d".
|
||||||
|
|
||||||
|
Example time: "1000ms" "10m"
|
||||||
|
|
||||||
=head1 MISCELLANEOUS
|
=head1 MISCELLANEOUS
|
||||||
|
|
||||||
Dunst can be paused by sending a notification with a summary of
|
Dunst can be paused by sending a notification with a summary of
|
||||||
|
10
src/dbus.c
10
src/dbus.c
@ -236,21 +236,13 @@ static void on_notify(GDBusConnection *connection,
|
|||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
if (timeout > 0) {
|
|
||||||
/* do some rounding */
|
|
||||||
timeout = (timeout + 500) / 1000;
|
|
||||||
if (timeout < 1) {
|
|
||||||
timeout = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
notification *n = notification_create();
|
notification *n = notification_create();
|
||||||
n->appname = appname;
|
n->appname = appname;
|
||||||
n->summary = summary;
|
n->summary = summary;
|
||||||
n->body = body;
|
n->body = body;
|
||||||
n->icon = icon;
|
n->icon = icon;
|
||||||
n->raw_icon = raw_icon;
|
n->raw_icon = raw_icon;
|
||||||
n->timeout = timeout;
|
n->timeout = timeout < 0 ? -1 : timeout * 1000;
|
||||||
n->markup = settings.markup;
|
n->markup = settings.markup;
|
||||||
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
||||||
n->urgency = urgency;
|
n->urgency = urgency;
|
||||||
|
79
src/dunst.c
79
src/dunst.c
@ -12,7 +12,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -70,7 +69,7 @@ void check_timeouts(void)
|
|||||||
|
|
||||||
/* don't timeout when user is idle */
|
/* don't timeout when user is idle */
|
||||||
if (x_is_idle() && !n->transient) {
|
if (x_is_idle() && !n->transient) {
|
||||||
n->start = time(NULL);
|
n->start = g_get_monotonic_time();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ void check_timeouts(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* remove old message */
|
/* remove old message */
|
||||||
if (difftime(time(NULL), n->start) > n->timeout) {
|
if (g_get_monotonic_time() - n->start > n->timeout) {
|
||||||
notification_close(n, 1);
|
notification_close(n, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +121,7 @@ void update_lists()
|
|||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
return;
|
return;
|
||||||
n->start = time(NULL);
|
n->start = g_get_monotonic_time();
|
||||||
if (!n->redisplayed && n->script) {
|
if (!n->redisplayed && n->script) {
|
||||||
notification_run_script(n);
|
notification_run_script(n);
|
||||||
}
|
}
|
||||||
@ -173,61 +172,45 @@ void wake_up(void)
|
|||||||
run(NULL);
|
run(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_sleep_time(void)
|
static gint64 get_sleep_time(void)
|
||||||
{
|
{
|
||||||
|
gint64 time = g_get_monotonic_time();
|
||||||
|
gint64 sleep = G_MAXINT64;
|
||||||
|
|
||||||
if (settings.show_age_threshold == 0) {
|
|
||||||
/* we need to update every second */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool have_ttl = false;
|
|
||||||
int min_ttl = 0;
|
|
||||||
int max_age = 0;
|
|
||||||
for (GList *iter = g_queue_peek_head_link(displayed); iter;
|
for (GList *iter = g_queue_peek_head_link(displayed); iter;
|
||||||
iter = iter->next) {
|
iter = iter->next) {
|
||||||
notification *n = iter->data;
|
notification *n = iter->data;
|
||||||
|
gint64 ttl = n->timeout - (time - n->start);
|
||||||
|
|
||||||
max_age = MAX(max_age, notification_get_age(n));
|
if (n->timeout > 0) {
|
||||||
int ttl = notification_get_ttl(n);
|
if (ttl > 0)
|
||||||
if (ttl >= 0) {
|
sleep = MIN(sleep, ttl);
|
||||||
if (have_ttl) {
|
else
|
||||||
min_ttl = MIN(min_ttl, ttl);
|
// while we're processing, the notification already timed out
|
||||||
} else {
|
return 0;
|
||||||
min_ttl = ttl;
|
}
|
||||||
have_ttl = true;
|
|
||||||
}
|
if (settings.show_age_threshold >= 0) {
|
||||||
|
gint64 age = time - n->timestamp;
|
||||||
|
|
||||||
|
if (age > settings.show_age_threshold)
|
||||||
|
// sleep exactly until the next shift of the second happens
|
||||||
|
sleep = MIN(sleep, ((G_USEC_PER_SEC) - (age % (G_USEC_PER_SEC))));
|
||||||
|
else if (ttl > settings.show_age_threshold)
|
||||||
|
sleep = MIN(sleep, settings.show_age_threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int min_timeout;
|
return sleep != G_MAXINT64 ? sleep : -1;
|
||||||
int show_age_timeout = settings.show_age_threshold - max_age;
|
|
||||||
|
|
||||||
if (show_age_timeout < 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!have_ttl) {
|
|
||||||
min_timeout = show_age_timeout;
|
|
||||||
} else {
|
|
||||||
min_timeout = MIN(show_age_timeout, min_ttl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* show_age_timeout might be negative */
|
|
||||||
if (min_timeout < 1) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return min_timeout;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean run(void *data)
|
gboolean run(void *data)
|
||||||
{
|
{
|
||||||
update_lists();
|
update_lists();
|
||||||
static int timeout_cnt = 0;
|
static int timeout_cnt = 0;
|
||||||
static int next_timeout = 0;
|
static gint64 next_timeout = 0;
|
||||||
|
|
||||||
if (data) {
|
if (data && timeout_cnt > 0) {
|
||||||
timeout_cnt--;
|
timeout_cnt--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,13 +227,13 @@ gboolean run(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (xctx.visible) {
|
if (xctx.visible) {
|
||||||
int now = time(NULL);
|
gint64 now = g_get_monotonic_time();
|
||||||
int sleep = get_sleep_time();
|
gint64 sleep = get_sleep_time();
|
||||||
|
gint64 timeout_at = now + sleep;
|
||||||
|
|
||||||
if (sleep > 0) {
|
if (sleep >= 0) {
|
||||||
int timeout_at = now + sleep;
|
|
||||||
if (timeout_cnt == 0 || timeout_at < next_timeout) {
|
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;
|
next_timeout = timeout_at;
|
||||||
timeout_cnt++;
|
timeout_cnt++;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ void notification_print(notification *n)
|
|||||||
printf("\ticon: '%s'\n", n->icon);
|
printf("\ticon: '%s'\n", n->icon);
|
||||||
printf("\traw_icon set: %s\n", (n->raw_icon ? "true" : "false"));
|
printf("\traw_icon set: %s\n", (n->raw_icon ? "true" : "false"));
|
||||||
printf("\tcategory: %s\n", n->category);
|
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("\turgency: %d\n", n->urgency);
|
||||||
printf("\ttransient: %d\n", n->transient);
|
printf("\ttransient: %d\n", n->transient);
|
||||||
printf("\tformatted: '%s'\n", n->msg);
|
printf("\tformatted: '%s'\n", n->msg);
|
||||||
@ -478,7 +477,7 @@ int notification_init(notification *n, int id)
|
|||||||
} else {
|
} else {
|
||||||
orig->progress = n->progress;
|
orig->progress = n->progress;
|
||||||
}
|
}
|
||||||
orig->start = time(NULL);
|
orig->start = g_get_monotonic_time();
|
||||||
notification_free(n);
|
notification_free(n);
|
||||||
wake_up();
|
wake_up();
|
||||||
return orig->id;
|
return orig->id;
|
||||||
@ -502,10 +501,10 @@ int notification_init(notification *n, int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n->timeout =
|
n->timeout =
|
||||||
n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout;
|
n->timeout < 0 ? settings.timeouts[n->urgency] : n->timeout;
|
||||||
n->start = 0;
|
n->start = 0;
|
||||||
|
|
||||||
n->timestamp = time(NULL);
|
n->timestamp = g_get_monotonic_time();
|
||||||
|
|
||||||
n->redisplayed = false;
|
n->redisplayed = false;
|
||||||
|
|
||||||
@ -671,26 +670,26 @@ void notification_update_text_to_render(notification *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* print age */
|
/* print age */
|
||||||
int hours, minutes, seconds;
|
gint64 hours, minutes, seconds;
|
||||||
time_t t_delta = time(NULL) - n->timestamp;
|
gint64 t_delta = g_get_monotonic_time() - n->timestamp;
|
||||||
|
|
||||||
if (settings.show_age_threshold >= 0
|
if (settings.show_age_threshold >= 0
|
||||||
&& t_delta >= settings.show_age_threshold) {
|
&& t_delta >= settings.show_age_threshold) {
|
||||||
hours = t_delta / 3600;
|
hours = t_delta / G_USEC_PER_SEC / 3600;
|
||||||
minutes = t_delta / 60 % 60;
|
minutes = t_delta / G_USEC_PER_SEC / 60 % 60;
|
||||||
seconds = t_delta % 60;
|
seconds = t_delta / G_USEC_PER_SEC % 60;
|
||||||
|
|
||||||
char *new_buf;
|
char *new_buf;
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
new_buf =
|
new_buf =
|
||||||
g_strdup_printf("%s (%dh %dm %ds old)", buf, hours,
|
g_strdup_printf("%s (%ldh %ldm %lds old)", buf, hours,
|
||||||
minutes, seconds);
|
minutes, seconds);
|
||||||
} else if (minutes > 0) {
|
} else if (minutes > 0) {
|
||||||
new_buf =
|
new_buf =
|
||||||
g_strdup_printf("%s (%dm %ds old)", buf, minutes,
|
g_strdup_printf("%s (%ldm %lds old)", buf, minutes,
|
||||||
seconds);
|
seconds);
|
||||||
} else {
|
} else {
|
||||||
new_buf = g_strdup_printf("%s (%ds old)", buf, seconds);
|
new_buf = g_strdup_printf("%s (%lds old)", buf, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
@ -700,18 +699,6 @@ void notification_update_text_to_render(notification *n)
|
|||||||
n->text_to_render = buf;
|
n->text_to_render = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int notification_get_ttl(notification *n) {
|
|
||||||
if (n->timeout == 0) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return n->timeout - (time(NULL) - n->start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int notification_get_age(notification *n) {
|
|
||||||
return time(NULL) - n->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the notification has exactly one action, or one is marked as default,
|
* If the notification has exactly one action, or one is marked as default,
|
||||||
* invoke it. If there are multiple and no default, open the context menu. If
|
* invoke it. If there are multiple and no default, open the context menu. If
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
@ -42,9 +41,9 @@ typedef struct _notification {
|
|||||||
char *text_to_render;
|
char *text_to_render;
|
||||||
const char *format;
|
const char *format;
|
||||||
char *dbus_client;
|
char *dbus_client;
|
||||||
time_t start;
|
gint64 start;
|
||||||
time_t timestamp;
|
gint64 timestamp;
|
||||||
int timeout;
|
gint64 timeout;
|
||||||
int urgency;
|
int urgency;
|
||||||
enum markup_mode markup;
|
enum markup_mode markup;
|
||||||
bool redisplayed; /* has been displayed before? */
|
bool redisplayed; /* has been displayed before? */
|
||||||
@ -75,8 +74,6 @@ int notification_close(notification *n, int reason);
|
|||||||
void notification_print(notification *n);
|
void notification_print(notification *n);
|
||||||
void notification_replace_single_field(char **haystack, char **needle, const char *replacement, enum markup_mode markup_mode);
|
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);
|
void notification_update_text_to_render(notification *n);
|
||||||
int notification_get_ttl(notification *n);
|
|
||||||
int notification_get_age(notification *n);
|
|
||||||
void notification_do_action(notification *n);
|
void notification_do_action(notification *n);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -123,6 +123,18 @@ char *ini_get_string(const char *section, const char *key, const char *def)
|
|||||||
return def ? g_strdup(def) : NULL;
|
return def ? g_strdup(def) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint64 ini_get_time(const char *section, const char *key, gint64 def)
|
||||||
|
{
|
||||||
|
const char *timestring = get_value(section, key);
|
||||||
|
gint64 val = def;
|
||||||
|
|
||||||
|
if (timestring) {
|
||||||
|
val = string_to_time(timestring);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
int ini_get_int(const char *section, const char *key, int def)
|
int ini_get_int(const char *section, const char *key, int def)
|
||||||
{
|
{
|
||||||
const char *value = get_value(section, key);
|
const char *value = get_value(section, key);
|
||||||
@ -371,6 +383,19 @@ char *cmdline_get_path(const char *key, const char *def, const char *description
|
|||||||
return string_to_path(g_strdup(def));
|
return string_to_path(g_strdup(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint64 cmdline_get_time(const char *key, gint64 def, const char *description)
|
||||||
|
{
|
||||||
|
cmdline_usage_append(key, "time", description);
|
||||||
|
const char *timestring = cmdline_get_value(key);
|
||||||
|
gint64 val = def;
|
||||||
|
|
||||||
|
if (timestring) {
|
||||||
|
val = string_to_time(timestring);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
int cmdline_get_int(const char *key, int def, const char *description)
|
int cmdline_get_int(const char *key, int def, const char *description)
|
||||||
{
|
{
|
||||||
cmdline_usage_append(key, "int", description);
|
cmdline_usage_append(key, "int", description);
|
||||||
@ -451,6 +476,16 @@ char *option_get_string(const char *ini_section,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint64 option_get_time(const char *ini_section,
|
||||||
|
const char *ini_key,
|
||||||
|
const char *cmdline_key,
|
||||||
|
gint64 def,
|
||||||
|
const char *description)
|
||||||
|
{
|
||||||
|
gint64 ini_val = ini_get_time(ini_section, ini_key, def);
|
||||||
|
return cmdline_get_time(cmdline_key, ini_val, description);
|
||||||
|
}
|
||||||
|
|
||||||
int option_get_int(const char *ini_section,
|
int option_get_int(const char *ini_section,
|
||||||
const char *ini_key,
|
const char *ini_key,
|
||||||
const char *cmdline_key,
|
const char *cmdline_key,
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
#ifndef DUNST_OPTION_PARSER_H
|
#ifndef DUNST_OPTION_PARSER_H
|
||||||
#define DUNST_OPTION_PARSER_H
|
#define DUNST_OPTION_PARSER_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int load_ini_file(FILE *);
|
int load_ini_file(FILE *);
|
||||||
char *ini_get_path(const char *section, const char *key, const char *def);
|
char *ini_get_path(const char *section, const char *key, const char *def);
|
||||||
char *ini_get_string(const char *section, const char *key, const char *def);
|
char *ini_get_string(const char *section, const char *key, const char *def);
|
||||||
|
gint64 ini_get_time(const char *section, const char *key, gint64 def);
|
||||||
int ini_get_int(const char *section, const char *key, int def);
|
int ini_get_int(const char *section, const char *key, int def);
|
||||||
double ini_get_double(const char *section, const char *key, double def);
|
double ini_get_double(const char *section, const char *key, double def);
|
||||||
int ini_get_bool(const char *section, const char *key, int def);
|
int ini_get_bool(const char *section, const char *key, int def);
|
||||||
@ -34,6 +36,11 @@ char *option_get_path(const char *ini_section,
|
|||||||
const char *cmdline_key,
|
const char *cmdline_key,
|
||||||
const char *def,
|
const char *def,
|
||||||
const char *description);
|
const char *description);
|
||||||
|
gint64 option_get_time(const char *ini_section,
|
||||||
|
const char *ini_key,
|
||||||
|
const char *cmdline_key,
|
||||||
|
gint64 def,
|
||||||
|
const char *description);
|
||||||
int option_get_int(const char *ini_section,
|
int option_get_int(const char *ini_section,
|
||||||
const char *ini_key,
|
const char *ini_key,
|
||||||
const char *cmdline_key,
|
const char *cmdline_key,
|
||||||
|
@ -19,7 +19,7 @@ typedef struct _rule_t {
|
|||||||
int msg_urgency;
|
int msg_urgency;
|
||||||
|
|
||||||
/* actions */
|
/* actions */
|
||||||
int timeout;
|
gint64 timeout;
|
||||||
int urgency;
|
int urgency;
|
||||||
enum markup_mode markup;
|
enum markup_mode markup;
|
||||||
int history_ignore;
|
int history_ignore;
|
||||||
|
@ -197,7 +197,7 @@ void load_settings(char *cmdline_config_path)
|
|||||||
"Ignore newline characters in notifications"
|
"Ignore newline characters in notifications"
|
||||||
);
|
);
|
||||||
|
|
||||||
settings.idle_threshold = option_get_int(
|
settings.idle_threshold = option_get_time(
|
||||||
"global",
|
"global",
|
||||||
"idle_threshold", "-idle_threshold", idle_threshold,
|
"idle_threshold", "-idle_threshold", idle_threshold,
|
||||||
"Don't timeout notifications if user is longer idle than 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 = option_get_time(
|
||||||
"global",
|
"global",
|
||||||
"show_age_threshold", "-show_age_threshold", show_age_threshold,
|
"show_age_threshold", "-show_age_threshold", show_age_threshold,
|
||||||
"When should the age of the notification be displayed?"
|
"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"
|
"Frame color for notifications with low urgency"
|
||||||
);
|
);
|
||||||
|
|
||||||
settings.timeouts[LOW] = option_get_int(
|
settings.timeouts[LOW] = option_get_time(
|
||||||
"urgency_low",
|
"urgency_low",
|
||||||
"timeout", "-lto", timeouts[LOW],
|
"timeout", "-lto", timeouts[LOW],
|
||||||
"Timeout for notifications with low urgency"
|
"Timeout for notifications with low urgency"
|
||||||
@ -520,7 +520,7 @@ void load_settings(char *cmdline_config_path)
|
|||||||
"Frame color for notifications with normal urgency"
|
"Frame color for notifications with normal urgency"
|
||||||
);
|
);
|
||||||
|
|
||||||
settings.timeouts[NORM] = option_get_int(
|
settings.timeouts[NORM] = option_get_time(
|
||||||
"urgency_normal",
|
"urgency_normal",
|
||||||
"timeout", "-nto", timeouts[NORM],
|
"timeout", "-nto", timeouts[NORM],
|
||||||
"Timeout for notifications with normal urgency"
|
"Timeout for notifications with normal urgency"
|
||||||
@ -550,7 +550,7 @@ void load_settings(char *cmdline_config_path)
|
|||||||
"Frame color for notifications with critical urgency"
|
"Frame color for notifications with critical urgency"
|
||||||
);
|
);
|
||||||
|
|
||||||
settings.timeouts[CRIT] = option_get_int(
|
settings.timeouts[CRIT] = option_get_time(
|
||||||
"urgency_critical",
|
"urgency_critical",
|
||||||
"timeout", "-cto", timeouts[CRIT],
|
"timeout", "-cto", timeouts[CRIT],
|
||||||
"Timeout for notifications with critical urgency"
|
"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->body = ini_get_string(cur_section, "body", r->body);
|
||||||
r->icon = ini_get_string(cur_section, "icon", r->icon);
|
r->icon = ini_get_string(cur_section, "icon", r->icon);
|
||||||
r->category = ini_get_string(cur_section, "category", r->category);
|
r->category = ini_get_string(cur_section, "category", r->category);
|
||||||
r->timeout = ini_get_int(cur_section, "timeout", r->timeout);
|
r->timeout = ini_get_time(cur_section, "timeout", r->timeout);
|
||||||
|
|
||||||
{
|
{
|
||||||
char *c = ini_get_string(
|
char *c = ini_get_string(
|
||||||
|
@ -30,7 +30,7 @@ typedef struct _settings {
|
|||||||
char *lowfgcolor;
|
char *lowfgcolor;
|
||||||
char *lowframecolor;
|
char *lowframecolor;
|
||||||
char *format;
|
char *format;
|
||||||
int timeouts[3];
|
gint64 timeouts[3];
|
||||||
char *icons[3];
|
char *icons[3];
|
||||||
unsigned int transparency;
|
unsigned int transparency;
|
||||||
char *geom;
|
char *geom;
|
||||||
@ -39,8 +39,8 @@ typedef struct _settings {
|
|||||||
int shrink;
|
int shrink;
|
||||||
int sort;
|
int sort;
|
||||||
int indicate_hidden;
|
int indicate_hidden;
|
||||||
int idle_threshold;
|
gint64 idle_threshold;
|
||||||
int show_age_threshold;
|
gint64 show_age_threshold;
|
||||||
enum alignment align;
|
enum alignment align;
|
||||||
int sticky_history;
|
int sticky_history;
|
||||||
int history_length;
|
int history_length;
|
||||||
|
44
src/utils.c
44
src/utils.c
@ -2,7 +2,9 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -122,6 +124,48 @@ char *string_to_path(char *string) {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint64 string_to_time(const char *string) {
|
||||||
|
|
||||||
|
assert(string);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
char *endptr;
|
||||||
|
gint64 val = strtoll(string, &endptr, 10);
|
||||||
|
|
||||||
|
if (errno != 0) {
|
||||||
|
fprintf(stderr, "ERROR: Time: '%s': %s.\n", string, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (string == endptr) {
|
||||||
|
fprintf(stderr, "ERROR: Time: No digits found.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (errno != 0 && val == 0) {
|
||||||
|
fprintf(stderr, "ERROR: Time: '%s' unknown error.\n", string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (errno == 0 && !*endptr) {
|
||||||
|
return val * G_USEC_PER_SEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// endptr may point to a separating space
|
||||||
|
while (*endptr == ' ')
|
||||||
|
endptr++;
|
||||||
|
|
||||||
|
if (0 == strncmp(endptr, "ms", 2))
|
||||||
|
return val * 1000;
|
||||||
|
else if (0 == strncmp(endptr, "s", 1))
|
||||||
|
return val * G_USEC_PER_SEC;
|
||||||
|
else if (0 == strncmp(endptr, "m", 1))
|
||||||
|
return val * G_USEC_PER_SEC * 60;
|
||||||
|
else if (0 == strncmp(endptr, "h", 1))
|
||||||
|
return val * G_USEC_PER_SEC * 60 * 60;
|
||||||
|
else if (0 == strncmp(endptr, "d", 1))
|
||||||
|
return val * G_USEC_PER_SEC * 60 * 60 * 24;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void die(char *text, int exit_value)
|
void die(char *text, int exit_value)
|
||||||
{
|
{
|
||||||
fputs(text, stderr);
|
fputs(text, stderr);
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#ifndef DUNST_UTILS_H
|
#ifndef DUNST_UTILS_H
|
||||||
#define DUNST_UTILS_H
|
#define DUNST_UTILS_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
/* replace all occurences of the character needle with the character replacement in haystack */
|
/* replace all occurences of the character needle with the character replacement in haystack */
|
||||||
char *string_replace_char(char needle, char replacement, char *haystack);
|
char *string_replace_char(char needle, char replacement, char *haystack);
|
||||||
|
|
||||||
@ -27,5 +29,8 @@ void die(char *msg, int exit_value);
|
|||||||
/* replace tilde and path-specific values with its equivalents */
|
/* replace tilde and path-specific values with its equivalents */
|
||||||
char *string_to_path(char *string);
|
char *string_to_path(char *string);
|
||||||
|
|
||||||
|
/* convert time units (ms, s, m) to internal gint64 microseconds */
|
||||||
|
gint64 string_to_time(const char *string);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
@ -900,7 +900,7 @@ bool x_is_idle(void)
|
|||||||
if (settings.idle_threshold == 0) {
|
if (settings.idle_threshold == 0) {
|
||||||
return false;
|
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_* */
|
/* TODO move to x_mainloop_* */
|
||||||
|
15
test/utils.c
15
test/utils.c
@ -158,6 +158,20 @@ TEST test_string_to_path(void)
|
|||||||
PASS();
|
PASS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST test_string_to_time(void)
|
||||||
|
{
|
||||||
|
char *input[] = { "5000 ms", "5000ms", "100", "10s", "2m", "11h", "9d", "d9", " 5 ms ", NULL };
|
||||||
|
gint64 exp[] = { 5000, 5000, 100000, 10000, 120000, 39600000, 777600000, 0, 5, };
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (input[i]){
|
||||||
|
ASSERT_EQ_FMT(string_to_time(input[i]), exp[i]*1000, "%ld");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
SUITE(suite_utils)
|
SUITE(suite_utils)
|
||||||
{
|
{
|
||||||
RUN_TEST(test_string_replace_char);
|
RUN_TEST(test_string_replace_char);
|
||||||
@ -166,5 +180,6 @@ SUITE(suite_utils)
|
|||||||
RUN_TEST(test_string_append);
|
RUN_TEST(test_string_append);
|
||||||
RUN_TEST(test_string_strip_delimited);
|
RUN_TEST(test_string_strip_delimited);
|
||||||
RUN_TEST(test_string_to_path);
|
RUN_TEST(test_string_to_path);
|
||||||
|
RUN_TEST(test_string_to_time);
|
||||||
}
|
}
|
||||||
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user