Introduce a status structure

This commit is contained in:
Benedikt Heine 2018-10-03 15:02:46 +02:00
parent ef08f6aa66
commit 140278a36f
8 changed files with 122 additions and 77 deletions

View File

@ -2,6 +2,7 @@
#include "dunst.h"
#include <assert.h>
#include <glib.h>
#include <glib-unix.h>
#include <signal.h>
@ -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);

View File

@ -6,6 +6,7 @@
#include <glib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stddef.h>
#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);

View File

@ -20,6 +20,7 @@
#include <stdio.h>
#include <string.h>
#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
*

View File

@ -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
*

23
test/dunst.c Normal file
View File

@ -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: */

View File

@ -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();

View File

@ -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

View File

@ -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;