diff --git a/src/dunst.c b/src/dunst.c index 337c2e2..6f901c0 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -2,6 +2,7 @@ #include "dunst.h" +#include #include #include #include @@ -24,6 +25,34 @@ GMainLoop *mainloop = NULL; +static struct dunst_status status; + +/* see dunst.h */ +void dunst_status(const enum dunst_status_field field, + bool value) +{ + switch (field) { + case S_FULLSCREEN: + status.fullscreen = value; + break; + case S_IDLE: + status.idle = value; + break; + case S_RUNNING: + status.running = value; + break; + default: + LOG_E("Invalid %s enum value in %s:%d", "dunst_status", __FILE__, __LINE__); + break; + } +} + +/* see dunst.h */ +struct dunst_status dunst_status_get(void) +{ + return status; +} + /* misc functions */ static gboolean run(void *data); @@ -36,10 +65,11 @@ static gboolean run(void *data) { LOG_D("RUN"); - bool fullscreen = have_fullscreen_window(); + dunst_status(S_FULLSCREEN, have_fullscreen_window()); + dunst_status(S_IDLE, x_is_idle()); - queues_check_timeouts(x_is_idle(), fullscreen); - queues_update(fullscreen); + queues_check_timeouts(status); + queues_update(status); static gint64 next_timeout = 0; @@ -76,7 +106,7 @@ static gboolean run(void *data) gboolean pause_signal(gpointer data) { - queues_pause_on(); + dunst_status(S_RUNNING, false); wake_up(); return G_SOURCE_CONTINUE; @@ -84,7 +114,7 @@ gboolean pause_signal(gpointer data) gboolean unpause_signal(gpointer data) { - queues_pause_off(); + dunst_status(S_RUNNING, true); wake_up(); return G_SOURCE_CONTINUE; @@ -109,6 +139,9 @@ static void teardown(void) int dunst_main(int argc, char *argv[]) { + dunst_status(S_RUNNING, true); + dunst_status(S_IDLE, false); + queues_init(); cmdline_load(argc, argv); diff --git a/src/dunst.h b/src/dunst.h index a0d0519..47a2b35 100644 --- a/src/dunst.h +++ b/src/dunst.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "notification.h" @@ -14,6 +15,29 @@ #define ColFG 1 #define ColBG 0 +//!< A structure to describe dunst's global window status +struct dunst_status { + bool fullscreen; //!< a fullscreen window is currently focused + bool running; //!< set true if dunst is currently running + bool idle; //!< set true if the user is idle +}; + +enum dunst_status_field { + S_FULLSCREEN, + S_IDLE, + S_RUNNING, +}; + +/** + * Modify the current status of dunst + * @param field The field to change in the global status structure + * @param value Anything boolean or DO_TOGGLE to toggle the current value + */ +void dunst_status(const enum dunst_status_field field, + bool value); + +struct dunst_status dunst_status_get(void); + extern const char *colors[3][3]; void wake_up(void); diff --git a/src/queues.c b/src/queues.c index 24a8b9f..4bff9b1 100644 --- a/src/queues.c +++ b/src/queues.c @@ -20,6 +20,7 @@ #include #include +#include "dunst.h" #include "log.h" #include "notification.h" #include "settings.h" @@ -31,7 +32,6 @@ static GQueue *displayed = NULL; /**< currently displayed notifications */ static GQueue *history = NULL; /**< history of displayed notifications */ int next_notification_id = 1; -bool pause_displayed = false; static bool queues_stack_duplicate(struct notification *n); static bool queues_stack_by_tag(struct notification *n); @@ -107,15 +107,15 @@ static void queues_swap_notifications(GQueue *queueA, /** * Check if a notification is eligible to get shown. * - * @param n The notification to check - * @param fullscreen True if a fullscreen window is currently active - * @param visible True if the notification is currently displayed + * @param n The notification to check + * @param status The current status of dunst + * @param shown True if the notification is currently displayed */ -static bool queues_notification_is_ready(const struct notification *n, bool fullscreen, bool visible) +static bool queues_notification_is_ready(const struct notification *n, struct dunst_status status, bool shown) { - if (fullscreen && visible) + if (status.fullscreen && shown) return n && n->fullscreen != FS_PUSHBACK; - else if (fullscreen && !visible) + else if (status.fullscreen && !shown) return n && n->fullscreen == FS_SHOW; else return true; @@ -134,15 +134,15 @@ int queues_notification_insert(struct notification *n) } /* Do not insert the message if it's a command */ if (STR_EQ("DUNST_COMMAND_PAUSE", n->summary)) { - pause_displayed = true; + dunst_status(S_RUNNING, false); return 0; } if (STR_EQ("DUNST_COMMAND_RESUME", n->summary)) { - pause_displayed = false; + dunst_status(S_RUNNING, true); return 0; } if (STR_EQ("DUNST_COMMAND_TOGGLE", n->summary)) { - pause_displayed = !pause_displayed; + dunst_status(S_RUNNING, !dunst_status_get().running); return 0; } @@ -343,13 +343,13 @@ void queues_history_push_all(void) } /* see queues.h */ -void queues_check_timeouts(bool idle, bool fullscreen) +void queues_check_timeouts(struct dunst_status status) { /* nothing to do */ if (displayed->length == 0) return; - bool is_idle = fullscreen ? false : idle; + bool is_idle = status.fullscreen ? false : status.idle; GList *iter = g_queue_peek_head_link(displayed); while (iter) { @@ -381,9 +381,9 @@ void queues_check_timeouts(bool idle, bool fullscreen) } /* see queues.h */ -void queues_update(bool fullscreen) +void queues_update(struct dunst_status status) { - if (pause_displayed) { + if (!status.running) { while (displayed->length > 0) { g_queue_insert_sorted( waiting, g_queue_pop_head(displayed), notification_cmp_data, NULL); @@ -392,7 +392,7 @@ void queues_update(bool fullscreen) } /* move notifications back to queue, which are set to pushback */ - if (fullscreen) { + if (status.fullscreen) { GList *iter = g_queue_peek_head_link(displayed); while (iter) { struct notification *n = iter->data; @@ -426,7 +426,7 @@ void queues_update(bool fullscreen) if (!n) return; - if (!queues_notification_is_ready(n, fullscreen, false)) { + if (!queues_notification_is_ready(n, status, false)) { iter = nextiter; continue; } @@ -455,7 +455,7 @@ void queues_update(bool fullscreen) while ( (i_waiting = g_queue_peek_head_link(waiting)) && (i_displayed = g_queue_peek_tail_link(displayed))) { - while (i_waiting && ! queues_notification_is_ready(i_waiting->data, fullscreen, true)) { + while (i_waiting && ! queues_notification_is_ready(i_waiting->data, status, true)) { i_waiting = i_waiting->prev; } @@ -505,24 +505,6 @@ gint64 queues_get_next_datachange(gint64 time) return sleep != G_MAXINT64 ? sleep : -1; } -/* see queues.h */ -void queues_pause_on(void) -{ - pause_displayed = true; -} - -/* see queues.h */ -void queues_pause_off(void) -{ - pause_displayed = false; -} - -/* see queues.h */ -bool queues_pause_status(void) -{ - return pause_displayed; -} - /** * Helper function for queues_teardown() to free a single notification * diff --git a/src/queues.h b/src/queues.h index 0b55a38..a74e30b 100644 --- a/src/queues.h +++ b/src/queues.h @@ -8,6 +8,7 @@ #define DUNST_QUEUE_H #include "dbus.h" +#include "dunst.h" #include "notification.h" /** @@ -120,12 +121,9 @@ void queues_history_push_all(void); /** * Check timeout of each notification and close it, if necessary * - * @param idle the program's idle status. Important to calculate the - * timeout for transient notifications - * @param fullscreen the desktop's fullscreen status. Important to - * calculate the timeout for transient notifications + * @param status the current status of dunst */ -void queues_check_timeouts(bool idle, bool fullscreen); +void queues_check_timeouts(struct dunst_status status); /** * Move inserted notifications from waiting queue to displayed queue @@ -135,10 +133,9 @@ void queues_check_timeouts(bool idle, bool fullscreen); * @post Call wake_up() to synchronize the queues with the UI * (which closes old and shows new notifications on screen) * - * @param fullscreen the desktop's fullscreen status. Important to - * move notifications to the right queue + * @param status the current status of dunst */ -void queues_update(bool fullscreen); +void queues_update(struct dunst_status status); /** * Calculate the distance to the next event, when an element in the @@ -154,28 +151,6 @@ void queues_update(bool fullscreen); */ gint64 queues_get_next_datachange(gint64 time); -/** - * Pause queue-management of dunst - * - * @post Calling update_lists() is necessary - */ -void queues_pause_on(void); - -/** - * Unpause (run) queue-management of dunst - * - * @post Calling update_lists() is necessary - */ -void queues_pause_off(void); - -/** - * Get the current status - * - * @return true if paused - * @return false if running - */ -bool queues_pause_status(void); - /** * Remove all notifications from all list and free the notifications * diff --git a/test/dunst.c b/test/dunst.c new file mode 100644 index 0000000..827f98d --- /dev/null +++ b/test/dunst.c @@ -0,0 +1,23 @@ +#include "../src/dunst.c" +#include "greatest.h" + +TEST test_dunst_status(void) +{ + status = (struct dunst_status) {false, false, false}; + + dunst_status(S_FULLSCREEN, true); + ASSERT(status.fullscreen); + dunst_status(S_IDLE, true); + ASSERT(status.idle); + dunst_status(S_RUNNING, true); + ASSERT(status.running); + + PASS(); +} + +SUITE(suite_dunst) +{ + RUN_TEST(test_dunst_status); +} + +/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ diff --git a/test/queues.c b/test/queues.c index e70d48e..6afda5d 100644 --- a/test/queues.c +++ b/test/queues.c @@ -61,7 +61,7 @@ TEST test_queue_insert_id_replacement(void) ASSERT_EQ(a->id, b->id); NOT_LAST(a); - queues_update(false); + queues_update(STATUS_NORMAL); c = test_notification("c", -1); c->id = b->id; @@ -86,7 +86,7 @@ TEST test_queue_notification_close(void) queues_notification_insert(n); QUEUE_LEN_ALL(1, 0, 0); queues_notification_close(n, REASON_UNDEF); - queues_update(NULL); + queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0, 0, 1); queues_teardown(); @@ -96,10 +96,10 @@ TEST test_queue_notification_close(void) queues_init(); queues_notification_insert(n); QUEUE_LEN_ALL(1, 0, 0); - queues_update(NULL); + queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0, 1, 0); queues_notification_close(n, REASON_UNDEF); - queues_update(NULL); + queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0, 0, 1); queues_teardown(); @@ -118,7 +118,7 @@ TEST test_queue_notification_close_histignore(void) queues_notification_insert(n); QUEUE_LEN_ALL(1, 0, 0); queues_notification_close(n, REASON_UNDEF); - queues_update(NULL); + queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0, 0, 0); queues_teardown(); @@ -129,10 +129,10 @@ TEST test_queue_notification_close_histignore(void) queues_init(); queues_notification_insert(n); QUEUE_LEN_ALL(1, 0, 0); - queues_update(NULL); + queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0, 1, 0); queues_notification_close(n, REASON_UNDEF); - queues_update(NULL); + queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0, 0, 0); queues_teardown(); diff --git a/test/queues.h b/test/queues.h index 72bf29f..67b68a7 100644 --- a/test/queues.h +++ b/test/queues.h @@ -9,6 +9,12 @@ #include "../src/notification.h" #include "../src/queues.h" +#define STATUS_NORMAL ((struct dunst_status) {.fullscreen=false, .running=true, .idle=false}) +#define STATUS_IDLE ((struct dunst_status) {.fullscreen=false, .running=true, .idle=true}) +#define STATUS_FSIDLE ((struct dunst_status) {.fullscreen=true, .running=true, .idle=true}) +#define STATUS_FS ((struct dunst_status) {.fullscreen=true, .running=true, .idle=false}) +#define STATUS_PAUSE ((struct dunst_status) {.fullscreen=false, .running=false, .idle=false}) + #define QUEUE_WAIT waiting #define QUEUE_DISP displayed #define QUEUE_HIST history diff --git a/test/test.c b/test/test.c index 7d2f6f4..a816ee5 100644 --- a/test/test.c +++ b/test/test.c @@ -16,6 +16,7 @@ SUITE_EXTERN(suite_markup); SUITE_EXTERN(suite_misc); SUITE_EXTERN(suite_icon); SUITE_EXTERN(suite_queues); +SUITE_EXTERN(suite_dunst); GREATEST_MAIN_DEFS(); @@ -38,6 +39,7 @@ int main(int argc, char *argv[]) { RUN_SUITE(suite_misc); RUN_SUITE(suite_icon); RUN_SUITE(suite_queues); + RUN_SUITE(suite_dunst); GREATEST_MAIN_END(); base = NULL;