Use structs for notifications

This commit is contained in:
Benedikt Heine 2018-09-16 02:58:31 +02:00
parent 1fa1532d7f
commit bbbddad3a7
15 changed files with 92 additions and 91 deletions

View File

@ -130,10 +130,10 @@ static void on_get_capabilities(GDBusConnection *connection,
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
static notification *dbus_message_to_notification(const gchar *sender, GVariant *parameters)
static struct notification *dbus_message_to_notification(const gchar *sender, GVariant *parameters)
{
notification *n = notification_create();
struct notification *n = notification_create();
n->actions = g_malloc0(sizeof(struct actions));
n->dbus_client = g_strdup(sender);
@ -272,7 +272,7 @@ static void on_notify(GDBusConnection *connection,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
notification *n = dbus_message_to_notification(sender, parameters);
struct notification *n = dbus_message_to_notification(sender, parameters);
int id = queues_notification_insert(n);
GVariant *reply = g_variant_new("(u)", id);
@ -314,7 +314,7 @@ static void on_get_server_information(GDBusConnection *connection,
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
void signal_notification_closed(notification *n, enum reason reason)
void signal_notification_closed(struct notification *n, enum reason reason)
{
if (reason < REASON_MIN || REASON_MAX < reason) {
LOG_W("Closing notification with reason '%d' not supported. "
@ -344,7 +344,7 @@ void signal_notification_closed(notification *n, enum reason reason)
}
void signal_action_invoked(notification *n, const char *identifier)
void signal_action_invoked(const struct notification *n, const char *identifier)
{
GVariant *body = g_variant_new("(us)", n->id, identifier);
GError *err = NULL;

View File

@ -17,8 +17,8 @@ enum reason {
int initdbus(void);
void dbus_tear_down(int id);
void signal_notification_closed(notification *n, enum reason reason);
void signal_action_invoked(notification *n, const char *identifier);
void signal_notification_closed(struct notification *n, enum reason reason);
void signal_action_invoked(const struct notification *n, const char *identifier);
#endif
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -26,7 +26,7 @@ struct colored_layout {
char *text;
PangoAttrList *attr;
cairo_surface_t *icon;
const notification *n;
const struct notification *n;
};
struct window_x11 *win;
@ -246,7 +246,7 @@ static PangoLayout *layout_create(cairo_t *c)
return layout;
}
static struct colored_layout *layout_init_shared(cairo_t *c, const notification *n)
static struct colored_layout *layout_init_shared(cairo_t *c, const struct notification *n)
{
struct colored_layout *cl = g_malloc(sizeof(struct colored_layout));
cl->l = layout_create(c);
@ -302,7 +302,7 @@ static struct colored_layout *layout_init_shared(cairo_t *c, const notification
return cl;
}
static struct colored_layout *layout_derive_xmore(cairo_t *c, const notification *n, int qlen)
static struct colored_layout *layout_derive_xmore(cairo_t *c, const struct notification *n, int qlen)
{
struct colored_layout *cl = layout_init_shared(c, n);
cl->text = g_strdup_printf("(%d more)", qlen);
@ -311,7 +311,7 @@ static struct colored_layout *layout_derive_xmore(cairo_t *c, const notification
return cl;
}
static struct colored_layout *layout_from_notification(cairo_t *c, notification *n)
static struct colored_layout *layout_from_notification(cairo_t *c, struct notification *n)
{
struct colored_layout *cl = layout_init_shared(c, n);
@ -354,7 +354,7 @@ static GSList *create_layouts(cairo_t *c)
for (const GList *iter = queues_get_displayed();
iter; iter = iter->next)
{
notification *n = iter->data;
struct notification *n = iter->data;
notification_update_text_to_render(n);

View File

@ -161,7 +161,7 @@ int dunst_main(int argc, char *argv[])
guint int_src = g_unix_signal_add(SIGINT, quit_signal, NULL);
if (settings.startup_notification) {
notification *n = notification_create();
struct notification *n = notification_create();
n->id = 0;
n->appname = g_strdup("dunst");
n->summary = g_strdup("startup");

View File

@ -143,7 +143,7 @@ GdkPixbuf *get_pixbuf_from_raw_image(const struct raw_image *raw_image)
return pixbuf;
}
cairo_surface_t *icon_get_for_notification(const notification *n)
cairo_surface_t *icon_get_for_notification(const struct notification *n)
{
GdkPixbuf *pixbuf;

View File

@ -36,7 +36,7 @@ GdkPixbuf *get_pixbuf_from_raw_image(const struct raw_image *raw_image);
*
* @return a cairo_surface_t pointer or NULL if no icon could be retrieved.
*/
cairo_surface_t *icon_get_for_notification(const notification *n);
cairo_surface_t *icon_get_for_notification(const struct notification *n);
#endif
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -135,7 +135,7 @@ void open_browser(const char *in)
*/
void invoke_action(const char *action)
{
notification *invoked = NULL;
struct notification *invoked = NULL;
char *action_identifier = NULL;
char *appname_begin = strchr(action, '[');
@ -149,7 +149,7 @@ void invoke_action(const char *action)
for (const GList *iter = queues_get_displayed(); iter;
iter = iter->next) {
notification *n = iter->data;
struct notification *n = iter->data;
if (g_str_has_prefix(appname_begin, n->appname) && strlen(n->appname) == appname_len) {
if (!n->actions)
continue;
@ -201,7 +201,7 @@ void context_menu(void)
for (const GList *iter = queues_get_displayed(); iter;
iter = iter->next) {
notification *n = iter->data;
struct notification *n = iter->data;
if (n->urls)
dmenu_input = string_append(dmenu_input, n->urls, "\n");

View File

@ -24,9 +24,9 @@
#include "utils.h"
#include "x11/x.h"
static void notification_extract_urls(notification *n);
static void notification_format_message(notification *n);
static void notification_dmenu_string(notification *n);
static void notification_extract_urls(struct notification *n);
static void notification_format_message(struct notification *n);
static void notification_dmenu_string(struct notification *n);
/* see notification.h */
const char *enum_to_string_fullscreen(enum behavior_fullscreen in)
@ -43,7 +43,7 @@ const char *enum_to_string_fullscreen(enum behavior_fullscreen in)
}
/* see notification.h */
void notification_print(notification *n)
void notification_print(const struct notification *n)
{
//TODO: use logging info for this
printf("{\n");
@ -87,7 +87,7 @@ void notification_print(notification *n)
}
/* see notification.h */
void notification_run_script(notification *n)
void notification_run_script(struct notification *n)
{
if (!n->script || strlen(n->script) < 1)
return;
@ -150,7 +150,7 @@ const char *notification_urgency_to_string(const enum urgency urgency)
}
/* see notification.h */
int notification_cmp(const notification *a, const notification *b)
int notification_cmp(const struct notification *a, const struct notification *b)
{
if (a->urgency != b->urgency) {
return b->urgency - a->urgency;
@ -162,8 +162,8 @@ int notification_cmp(const notification *a, const notification *b)
/* see notification.h */
int notification_cmp_data(const void *va, const void *vb, void *data)
{
notification *a = (notification *) va;
notification *b = (notification *) vb;
struct notification *a = (struct notification *) va;
struct notification *b = (struct notification *) vb;
if (!settings.sort)
return 1;
@ -171,7 +171,7 @@ int notification_cmp_data(const void *va, const void *vb, void *data)
return notification_cmp(a, b);
}
int notification_is_duplicate(const notification *a, const notification *b)
int notification_is_duplicate(const struct notification *a, const struct notification *b)
{
//Comparing raw icons is not supported, assume they are not identical
if (settings.icon_position != icons_off
@ -207,7 +207,7 @@ void rawimage_free(struct raw_image *i)
}
/* see notification.h */
void notification_free(notification *n)
void notification_free(struct notification *n)
{
if (!n)
return;
@ -256,9 +256,9 @@ void notification_replace_single_field(char **haystack,
}
/* see notification.h */
notification *notification_create(void)
struct notification *notification_create(void)
{
notification *n = g_malloc0(sizeof(notification));
struct notification *n = g_malloc0(sizeof(struct notification));
/* Unparameterized default values */
n->first_render = true;
@ -281,7 +281,7 @@ notification *notification_create(void)
}
/* see notification.h */
void notification_init(notification *n)
void notification_init(struct notification *n)
{
/* default to empty string to avoid further NULL faults */
n->appname = n->appname ? n->appname : g_strdup("unknown");
@ -326,7 +326,7 @@ void notification_init(notification *n)
notification_format_message(n);
}
static void notification_format_message(notification *n)
static void notification_format_message(struct notification *n)
{
g_clear_pointer(&n->msg, g_free);
@ -431,7 +431,7 @@ static void notification_format_message(notification *n)
}
}
static void notification_extract_urls(notification *n)
static void notification_extract_urls(struct notification *n)
{
g_clear_pointer(&n->urls, g_free);
@ -455,7 +455,7 @@ static void notification_extract_urls(notification *n)
g_free(urls_text);
}
static void notification_dmenu_string(notification *n)
static void notification_dmenu_string(struct notification *n)
{
if (n->actions) {
g_clear_pointer(&n->actions->dmenu_str, g_free);
@ -473,7 +473,7 @@ static void notification_dmenu_string(notification *n)
}
}
void notification_update_text_to_render(notification *n)
void notification_update_text_to_render(struct notification *n)
{
g_clear_pointer(&n->text_to_render, g_free);
@ -529,7 +529,7 @@ void notification_update_text_to_render(notification *n)
}
/* see notification.h */
void notification_do_action(notification *n)
void notification_do_action(const struct notification *n)
{
if (n->actions) {
if (n->actions->count == 2) {

View File

@ -42,7 +42,7 @@ struct actions {
gsize count;
};
typedef struct _notification {
struct notification {
int id;
char *dbus_client;
@ -83,7 +83,7 @@ typedef struct _notification {
char *msg; /**< formatted message */
char *text_to_render; /**< formatted message (with age and action indicators) */
char *urls; /**< urllist delimited by '\\n' */
} notification;
};
/**
* Create notification struct and initialise all fields with either
@ -93,7 +93,7 @@ typedef struct _notification {
* This function is guaranteed to return a valid pointer.
* @returns The generated notification
*/
notification *notification_create(void);
struct notification *notification_create(void);
/**
* Sanitize values of notification, apply all matching rules
@ -101,7 +101,7 @@ notification *notification_create(void);
*
* @param n: the notification to sanitize
*/
void notification_init(notification *n);
void notification_init(struct notification *n);
/**
* Free the actions structure
@ -122,12 +122,12 @@ void rawimage_free(struct raw_image *i);
*
* @param n (nullable): pointer to #notification
*/
void notification_free(notification *n);
void notification_free(struct notification *n);
/**
* Helper function to compare two given notifications.
*/
int notification_cmp(const notification *a, const notification *b);
int notification_cmp(const struct notification *a, const struct notification *b);
/**
* Wrapper for notification_cmp to match glib's
@ -135,7 +135,7 @@ int notification_cmp(const notification *a, const notification *b);
*/
int notification_cmp_data(const void *va, const void *vb, void *data);
int notification_is_duplicate(const notification *a, const notification *b);
int notification_is_duplicate(const struct notification *a, const struct notification *b);
/**
* Run the script associated with the
@ -144,12 +144,12 @@ int notification_is_duplicate(const notification *a, const notification *b);
* If the script of the notification has been executed already and
* settings.always_run_script is not set, do nothing.
*/
void notification_run_script(notification *n);
void notification_run_script(struct notification *n);
/**
* print a human readable representation
* of the given notification to stdout.
*/
void notification_print(notification *n);
void notification_print(const struct notification *n);
/**
* Replace the two chars where **needle points
@ -162,14 +162,15 @@ 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(struct notification *n);
/**
* 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
* there are no actions, proceed similarly with urls.
*/
void notification_do_action(notification *n);
void notification_do_action(const struct notification *n);
const char *notification_urgency_to_string(const enum urgency urgency);

View File

@ -33,7 +33,7 @@ static GQueue *history = NULL; /**< history of displayed notifications */
int next_notification_id = 1;
bool pause_displayed = false;
static bool queues_stack_duplicate(notification *n);
static bool queues_stack_duplicate(struct notification *n);
/* see queues.h */
void queues_init(void)
@ -50,7 +50,7 @@ const GList *queues_get_displayed(void)
}
/* see queues.h */
const notification *queues_get_head_waiting(void)
const struct notification *queues_get_head_waiting(void)
{
if (waiting->length == 0)
return NULL;
@ -91,8 +91,8 @@ static void queues_swap_notifications(GQueue *queueA,
GQueue *queueB,
GList *elemB)
{
notification *toB = elemA->data;
notification *toA = elemB->data;
struct notification *toB = elemA->data;
struct notification *toA = elemB->data;
g_queue_delete_link(queueA, elemA);
g_queue_delete_link(queueB, elemB);
@ -110,7 +110,7 @@ static void queues_swap_notifications(GQueue *queueA,
* @param fullscreen True if a fullscreen window is currently active
* @param visible True if the notification is currently displayed
*/
static bool queues_notification_is_ready(const notification *n, bool fullscreen, bool visible)
static bool queues_notification_is_ready(const struct notification *n, bool fullscreen, bool visible)
{
if (fullscreen && visible)
return n && n->fullscreen != FS_PUSHBACK;
@ -121,7 +121,7 @@ static bool queues_notification_is_ready(const notification *n, bool fullscreen,
}
/* see queues.h */
int queues_notification_insert(notification *n)
int queues_notification_insert(struct notification *n)
{
/* do not display the message, if the message is empty */
@ -167,13 +167,13 @@ int queues_notification_insert(notification *n)
* @return true, if notification got stacked
* @return false, if notification did not get stacked
*/
static bool queues_stack_duplicate(notification *n)
static bool queues_stack_duplicate(struct notification *n)
{
GQueue *allqueues[] = { displayed, waiting };
for (int i = 0; i < sizeof(allqueues)/sizeof(GList*); i++) {
for (GList *iter = g_queue_peek_head_link(allqueues[i]); iter;
iter = iter->next) {
notification *orig = iter->data;
struct notification *orig = iter->data;
if (notification_is_duplicate(orig, n)) {
/* If the progress differs, probably notify-send was used to update the notification
* So only count it as a duplicate, if the progress was not the same.
@ -201,14 +201,14 @@ static bool queues_stack_duplicate(notification *n)
}
/* see queues.h */
bool queues_notification_replace_id(notification *new)
bool queues_notification_replace_id(struct notification *new)
{
GQueue *allqueues[] = { displayed, waiting };
for (int i = 0; i < sizeof(allqueues)/sizeof(GList*); i++) {
for (GList *iter = g_queue_peek_head_link(allqueues[i]);
iter;
iter = iter->next) {
notification *old = iter->data;
struct notification *old = iter->data;
if (old->id == new->id) {
iter->data = new;
new->dup_count = old->dup_count;
@ -222,7 +222,6 @@ bool queues_notification_replace_id(notification *new)
return true;
}
}
}
return false;
}
@ -230,13 +229,13 @@ bool queues_notification_replace_id(notification *new)
/* see queues.h */
void queues_notification_close_id(int id, enum reason reason)
{
notification *target = NULL;
struct notification *target = NULL;
GQueue *allqueues[] = { displayed, waiting };
for (int i = 0; i < sizeof(allqueues)/sizeof(GList*); i++) {
for (GList *iter = g_queue_peek_head_link(allqueues[i]); iter;
iter = iter->next) {
notification *n = iter->data;
struct notification *n = iter->data;
if (n->id == id) {
g_queue_remove(allqueues[i], n);
target = n;
@ -254,7 +253,7 @@ void queues_notification_close_id(int id, enum reason reason)
}
/* see queues.h */
void queues_notification_close(notification *n, enum reason reason)
void queues_notification_close(struct notification *n, enum reason reason)
{
assert(n != NULL);
queues_notification_close_id(n->id, reason);
@ -266,7 +265,7 @@ void queues_history_pop(void)
if (g_queue_is_empty(history))
return;
notification *n = g_queue_pop_tail(history);
struct notification *n = g_queue_pop_tail(history);
n->redisplayed = true;
n->start = 0;
n->timeout = settings.sticky_history ? 0 : n->timeout;
@ -274,11 +273,11 @@ void queues_history_pop(void)
}
/* see queues.h */
void queues_history_push(notification *n)
void queues_history_push(struct notification *n)
{
if (!n->history_ignore) {
if (settings.history_length > 0 && history->length >= settings.history_length) {
notification *to_free = g_queue_pop_head(history);
struct notification *to_free = g_queue_pop_head(history);
notification_free(to_free);
}
@ -311,7 +310,7 @@ void queues_check_timeouts(bool idle, bool fullscreen)
GList *iter = g_queue_peek_head_link(displayed);
while (iter) {
notification *n = iter->data;
struct notification *n = iter->data;
/*
* Update iter to the next item before we either exit the
@ -353,7 +352,7 @@ void queues_update(bool fullscreen)
if (fullscreen) {
GList *iter = g_queue_peek_head_link(displayed);
while (iter) {
notification *n = iter->data;
struct notification *n = iter->data;
GList *nextiter = iter->next;
if (n->fullscreen == FS_PUSHBACK){
@ -378,7 +377,7 @@ void queues_update(bool fullscreen)
/* move notifications from queue to displayed */
GList *iter = g_queue_peek_head_link(waiting);
while (displayed->length < cur_displayed_limit && iter) {
notification *n = iter->data;
struct notification *n = iter->data;
GList *nextiter = iter->next;
if (!n)
@ -400,7 +399,7 @@ void queues_update(bool fullscreen)
/* if necessary, push the overhanging notifications from displayed to waiting again */
while (displayed->length > cur_displayed_limit) {
notification *n = g_queue_pop_tail(displayed);
struct notification *n = g_queue_pop_tail(displayed);
g_queue_insert_sorted(waiting, n, notification_cmp_data, NULL); //TODO: actually it should be on the head if unsorted
}
@ -418,7 +417,7 @@ void queues_update(bool fullscreen)
}
if (i_waiting && notification_cmp(i_displayed->data, i_waiting->data) > 0) {
notification *todisp = i_waiting->data;
struct notification *todisp = i_waiting->data;
todisp->start = time_monotonic_now();
notification_run_script(todisp);
@ -438,7 +437,7 @@ gint64 queues_get_next_datachange(gint64 time)
for (GList *iter = g_queue_peek_head_link(displayed); iter;
iter = iter->next) {
notification *n = iter->data;
struct notification *n = iter->data;
gint64 ttl = n->timeout - (time - n->start);
if (n->timeout > 0) {
@ -488,7 +487,7 @@ bool queues_pause_status(void)
*/
static void teardown_notification(gpointer data)
{
notification *n = data;
struct notification *n = data;
notification_free(n);
}

View File

@ -30,7 +30,7 @@ const GList *queues_get_displayed(void);
*
* @return a notification or NULL, if waiting is empty
*/
const notification *queues_get_head_waiting(void);
const struct notification *queues_get_head_waiting(void);
/**
* Returns the current amount of notifications,
@ -63,7 +63,7 @@ unsigned int queues_length_history(void);
* @return `0`, the notification was dismissed and freed
* @return The new value of `n->id`
*/
int queues_notification_insert(notification *n);
int queues_notification_insert(struct notification *n);
/**
* Replace the notification which matches the id field of
@ -75,7 +75,7 @@ int queues_notification_insert(notification *n);
* @return true, if a matching notification has been found and is replaced
* @return false, else
*/
bool queues_notification_replace_id(notification *new);
bool queues_notification_replace_id(struct notification *new);
/**
* Close the notification that has n->id == id
@ -96,7 +96,7 @@ void queues_notification_close_id(int id, enum reason reason);
* @param n (transfer full) The notification to close
* @param reason The #reason to close
* */
void queues_notification_close(notification *n, enum reason reason);
void queues_notification_close(struct notification *n, enum reason reason);
/**
* Pushes the latest notification of history to the displayed queue
@ -110,7 +110,7 @@ void queues_history_pop(void);
*
* @param n (transfer full) The notification to push to history
*/
void queues_history_push(notification *n);
void queues_history_push(struct notification *n);
/**
* Push all waiting and displayed notifications to history

View File

@ -10,7 +10,7 @@
/*
* Apply rule to notification.
*/
void rule_apply(struct rule *r, notification *n)
void rule_apply(struct rule *r, struct notification *n)
{
if (r->timeout != -1)
n->timeout = r->timeout;
@ -50,7 +50,7 @@ void rule_apply(struct rule *r, notification *n)
/*
* Check all rules if they match n and apply.
*/
void rule_apply_all(notification *n)
void rule_apply_all(struct notification *n)
{
for (GSList *iter = rules; iter; iter = iter->next) {
struct rule *r = iter->data;
@ -89,7 +89,7 @@ void rule_init(struct rule *r)
/*
* Check whether rule should be applied to n.
*/
bool rule_matches_notification(struct rule *r, notification *n)
bool rule_matches_notification(struct rule *r, struct notification *n)
{
return ( (!r->appname || (n->appname && !fnmatch(r->appname, n->appname, 0)))
&& (!r->summary || (n->summary && !fnmatch(r->summary, n->summary, 0)))

View File

@ -37,9 +37,9 @@ struct rule {
extern GSList *rules;
void rule_init(struct rule *r);
void rule_apply(struct rule *r, notification *n);
void rule_apply_all(notification *n);
bool rule_matches_notification(struct rule *r, notification *n);
void rule_apply(struct rule *r, struct notification *n);
void rule_apply_all(struct notification *n);
bool rule_matches_notification(struct rule *r, struct notification *n);
#endif
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -411,7 +411,7 @@ static void x_handle_click(XEvent ev)
if (act == MOUSE_DO_ACTION || act == MOUSE_CLOSE_CURRENT) {
int y = settings.separator_height;
notification *n = NULL;
struct notification *n = NULL;
int first = true;
for (const GList *iter = queues_get_displayed(); iter;
iter = iter->next) {

View File

@ -5,8 +5,9 @@
#include <glib.h>
TEST test_notification_is_duplicate_field(char **field, notification *a,
notification *b)
TEST test_notification_is_duplicate_field(char **field,
struct notification *a,
struct notification *b)
{
ASSERT(notification_is_duplicate(a, b));
char *tmp = *field;
@ -19,9 +20,9 @@ TEST test_notification_is_duplicate_field(char **field, notification *a,
TEST test_notification_is_duplicate(void *notifications)
{
notification **n = (notification**)notifications;
notification *a = n[0];
notification *b = n[1];
struct notification **n = (struct notification**)notifications;
struct notification *a = n[0];
struct notification *b = n[1];
ASSERT(notification_is_duplicate(a, b));
@ -102,18 +103,18 @@ SUITE(suite_notification)
cmdline_load(0, NULL);
load_settings("data/dunstrc.default");
notification *a = notification_create();
struct notification *a = notification_create();
a->appname = "Test";
a->summary = "Summary";
a->body = "Body";
a->icon = "Icon";
a->urgency = URG_NORM;
notification *b = notification_create();
struct notification *b = notification_create();
memcpy(b, a, sizeof(*b));
//2 equal notifications to be passed for duplicate checking,
notification *n[2] = {a, b};
struct notification *n[2] = {a, b};
RUN_TEST1(test_notification_is_duplicate, (void*) n);
g_free(a);