Merge pull request #651 from bebehei/dunstctl

Implement a command line control (dunstctl)
This commit is contained in:
Nikos Tsipinakis 2020-05-01 15:38:23 +02:00 committed by GitHub
commit 337ff1edb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 450 additions and 38 deletions

View File

@ -106,9 +106,15 @@ test/test: ${OBJ} ${TEST_OBJ}
${CC} -o ${@} ${TEST_OBJ} $(filter-out ${TEST_OBJ:test/%=src/%},${OBJ}) ${CFLAGS} ${LDFLAGS} ${CC} -o ${@} ${TEST_OBJ} $(filter-out ${TEST_OBJ:test/%=src/%},${OBJ}) ${CFLAGS} ${LDFLAGS}
.PHONY: doc doc-doxygen .PHONY: doc doc-doxygen
doc: docs/dunst.1 doc: docs/dunst.1 docs/dunstctl.1
# Can't dedup this as we need to explicitly provide the name and title text to
# pod2man :(
docs/dunst.1: docs/dunst.pod docs/dunst.1: docs/dunst.pod
${POD2MAN} --name=dunst -c "Dunst Reference" --section=1 --release=${VERSION} $< > $@ ${POD2MAN} --name=dunst -c "Dunst Reference" --section=1 --release=${VERSION} $< > $@
docs/dunstctl.1: docs/dunstctl.pod
${POD2MAN} --name=dunstctl -c "dunstctl reference" --section=1 --release=${VERSION} $< > $@
doc-doxygen: doc-doxygen:
${DOXYGEN} docs/internal/Doxyfile ${DOXYGEN} docs/internal/Doxyfile
@ -137,6 +143,7 @@ clean-dunstify:
clean-doc: clean-doc:
rm -f docs/dunst.1 rm -f docs/dunst.1
rm -f docs/dunstctl.1
rm -fr docs/internal/html rm -fr docs/internal/html
rm -fr docs/internal/coverage rm -fr docs/internal/coverage
@ -151,15 +158,19 @@ clean-coverage-run:
${FIND} . -type f -name '*.gcov' -delete ${FIND} . -type f -name '*.gcov' -delete
${FIND} . -type f -name '*.gcda' -delete ${FIND} . -type f -name '*.gcda' -delete
.PHONY: install install-dunst install-doc \ .PHONY: install install-dunst install-dunstctl install-doc \
install-service install-service-dbus install-service-systemd \ install-service install-service-dbus install-service-systemd \
uninstall \ uninstall uninstall-dunstctl \
uninstall-service uninstall-service-dbus uninstall-service-systemd uninstall-service uninstall-service-dbus uninstall-service-systemd
install: install-dunst install-doc install-service install-dunstify install: install-dunst install-dunstctl install-doc install-service install-dunstify
install-dunst: dunst doc install-dunst: dunst doc
install -Dm755 dunst ${DESTDIR}${BINDIR}/dunst install -Dm755 dunst ${DESTDIR}${BINDIR}/dunst
install -Dm644 docs/dunst.1 ${DESTDIR}${MANPREFIX}/man1/dunst.1 install -Dm644 docs/dunst.1 ${DESTDIR}${MANPREFIX}/man1/dunst.1
install -Dm644 docs/dunstctl.1 ${DESTDIR}${MANPREFIX}/man1/dunstctl.1
install-dunstctl: dunstctl
install -Dm755 dunstctl ${DESTDIR}${BINDIR}/dunstctl
install-doc: install-doc:
install -Dm644 dunstrc ${DESTDIR}${DATADIR}/dunst/dunstrc install -Dm644 dunstrc ${DESTDIR}${DATADIR}/dunst/dunstrc
@ -176,12 +187,16 @@ endif
install-dunstify: dunstify install-dunstify: dunstify
install -Dm755 dunstify ${DESTDIR}${BINDIR}/dunstify install -Dm755 dunstify ${DESTDIR}${BINDIR}/dunstify
uninstall: uninstall-service uninstall: uninstall-service uninstall-dunstctl
rm -f ${DESTDIR}${BINDIR}/dunst rm -f ${DESTDIR}${BINDIR}/dunst
rm -f ${DESTDIR}${BINDIR}/dunstify rm -f ${DESTDIR}${BINDIR}/dunstify
rm -f ${DESTDIR}${MANPREFIX}/man1/dunst.1 rm -f ${DESTDIR}${MANPREFIX}/man1/dunst.1
rm -f ${DESTDIR}${MANPREFIX}/man1/dunstctl.1
rm -rf ${DESTDIR}${DATADIR}/dunst rm -rf ${DESTDIR}${DATADIR}/dunst
uninstall-dunstctl:
rm -f ${DESTDIR}${BINDIR}/dunstctl
uninstall-service: uninstall-service-dbus uninstall-service: uninstall-service-dbus
uninstall-service-dbus: uninstall-service-dbus:
rm -f ${DESTDIR}${SERVICEDIR_DBUS}/org.knopwob.dunst.service rm -f ${DESTDIR}${SERVICEDIR_DBUS}/org.knopwob.dunst.service

View File

@ -517,7 +517,7 @@ Close all notifications.
=back =back
=head2 Shortcut section =head2 Shortcut section B<DEPRECATED SEE DUNSTCTL>
Keyboard shortcuts are defined in the following format: "Modifier+key" where the Keyboard shortcuts are defined in the following format: "Modifier+key" where the
modifier is one of ctrl,mod1,mod2,mod3,mod4 and key is any keyboard key. modifier is one of ctrl,mod1,mod2,mod3,mod4 and key is any keyboard key.
@ -602,6 +602,13 @@ See TIME FORMAT for valid times.
=back =back
=head1 DUNSTCTL
Dunst now contains a command line control command that can be used to interact
with it. It supports all functions previously done only via keyboard shortcuts
but also has a lot of extra functionality. So see more see the dunstctl man
page.
=head1 HISTORY =head1 HISTORY
Dunst saves a number of notifications (specified by B<history_length>) in memory. Dunst saves a number of notifications (specified by B<history_length>) in memory.
@ -865,9 +872,8 @@ Example time: "1000ms" "10m"
=head1 MISCELLANEOUS =head1 MISCELLANEOUS
Dunst can be paused by sending a notification with a summary of Dunst can be paused via the `dunstctl set-running false` command. To unpause dunst use
"DUNST_COMMAND_PAUSE", resumed with a summary of "DUNST_COMMAND_RESUME" and `dunstctl set-status true` and to unpause `dunstctl set-status false`.
toggled with a summary of "DUNST_COMMAND_TOGGLE".
Alternatively you can send SIGUSR1 and SIGUSR2 to pause and unpause Alternatively you can send SIGUSR1 and SIGUSR2 to pause and unpause
respectively. For Example: respectively. For Example:
@ -908,4 +914,4 @@ If you feel that copyrights are violated, please send me an email.
=head1 SEE ALSO =head1 SEE ALSO
dwm(1), dmenu(1), twmn(1), notify-send(1) dunstctl(1), dwm(1), dmenu(1), twmn(1), notify-send(1)

59
docs/dunstctl.pod Normal file
View File

@ -0,0 +1,59 @@
=head1 NAME
dunstctl - Command line control utility for dunst, a customizable and lightweight notification-daemon
=head1 SYNOPSIS
dunstctl COMMAND [PARAMETER]
=head1 COMMANDS
=over 4
=item B<action> notification_position
Performs the default action or, if not available, opens the context menu of the
notification at the given position (starting count at the top, first
notification being 0).
=item B<close>
Close the topmost notification currently being displayed.
=item B<close-all>
Close all notifications currently being displayed
=item B<context>
Open the context menu, presenting all available actions and urls for the
currently open notifications.
=item B<history-pop>
Redisplay the notification that was most recently closed. This can be called
multiple times to show older notifications, up to the history limit configured
in dunst.
=item B<running>
Check if dunst is currently running or paused. If dunst is paused notifications
will be kept but not shown until it is unpaused.
=item B<set-running> true/false
Set the paused status of dunst. If true, dunst is running normally, if false,
dunst is paused. See the running command and the dunst man page for more
information.
=item B<debug>
Tries to contact dunst and checks for common faults between dunstctl and dunst.
Useful if something isn't working
=item B<help>
Show all available commands with a brief description
=back

101
dunstctl Executable file
View File

@ -0,0 +1,101 @@
#!/bin/sh
set -eu
DBUS_NAME="org.freedesktop.Notifications"
DBUS_PATH="/org/freedesktop/Notifications"
DBUS_IFAC_DUNST="org.dunstproject.cmd0"
DBUS_IFAC_PROP="org.freedesktop.DBus.Properties"
DBUS_IFAC_FDN="org.freedesktop.Notifications"
die(){ printf "%s\n" "${1}" >&2; exit 1; }
show_help() {
cat <<-EOH
Usage: dunstctl <command> [parameters]"
Commands:
action Perform the default action, or open the
context menu of the notification at the
given position
close Close the last notification
close-all Close the all notifications
context Open context menu
history-pop Pop one notification from history
running Check if dunst is running or paused
set-running [true|false] Set the pause status
debug Print debugging information
help Show this help
EOH
}
dbus_send_checked() {
dbus-send "$@" \
|| die "Failed to communicate with dunst, is it running? Or maybe the version is outdated. You can try 'dunstctl debug' as a next debugging step."
}
method_call() {
dbus_send_checked --print-reply=literal --dest="${DBUS_NAME}" "${DBUS_PATH}" "$@"
}
property_get() {
dbus_send_checked --print-reply=literal --dest="${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_PROP}.Get" "string:${DBUS_IFAC_DUNST}" "string:${1}"
}
property_set() {
dbus_send_checked --print-reply=literal --dest="${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_PROP}.Set" "string:${DBUS_IFAC_DUNST}" "string:${1}" "${2}"
}
command -v dbus-send >/dev/null 2>/dev/null || \
die "Command dbus-send not found"
case "${1:-}" in
"action")
method_call "${DBUS_IFAC_DUNST}.NotificationAction" "int32:${2:-0}" >/dev/null
;;
"close")
method_call "${DBUS_IFAC_DUNST}.NotificationCloseLast" >/dev/null
;;
"close-all")
method_call "${DBUS_IFAC_DUNST}.NotificationCloseAll" >/dev/null
;;
"context")
method_call "${DBUS_IFAC_DUNST}.ContextMenuCall" >/dev/null
;;
"history-pop")
method_call "${DBUS_IFAC_DUNST}.NotificationShow" >/dev/null
;;
"running")
property_get running | ( read -r _ _ paused; printf "%s\n" "${paused}"; )
;;
"set-running")
[ "${2:-}" ] \
|| die "No status parameter specified. Please give either 'true' or 'false' as running parameter."
[ "${2}" = "true" ] || [ "${2}" = "false" ] \
|| die "Please give either 'true' or 'false' as running parameter."
property_set running variant:boolean:"${2}"
;;
"help"|"--help"|"-h")
show_help
;;
"debug")
dbus-send --print-reply=literal --dest="${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_FDN}.GetServerInformation" >/dev/null 2>/dev/null \
|| die "Dunst is not running."
dbus-send --print-reply=literal --dest="${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_FDN}.GetServerInformation" \
| (
read -r name _ version _
[ "${name}" = "dunst" ]
printf "dunst version: %s\n" "${version}"
) \
|| die "Another notification manager is running. It's not dunst"
dbus-send --print-reply=literal --dest="${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_DUNST}.Ping" >/dev/null 2>/dev/null \
|| die "Dunst controlling interface not available. Is the version too old?"
;;
"")
die "dunstctl: No command specified. Please consult the usage."
;;
*)
die "dunstctl: unrecognized command '${1:-}'. Please consult the usage."
;;
esac

View File

@ -8,6 +8,7 @@
#include "dunst.h" #include "dunst.h"
#include "log.h" #include "log.h"
#include "menu.h"
#include "notification.h" #include "notification.h"
#include "queues.h" #include "queues.h"
#include "settings.h" #include "settings.h"
@ -17,6 +18,12 @@
#define FDN_IFAC "org.freedesktop.Notifications" #define FDN_IFAC "org.freedesktop.Notifications"
#define FDN_NAME "org.freedesktop.Notifications" #define FDN_NAME "org.freedesktop.Notifications"
#define DUNST_PATH "/org/freedesktop/Notifications"
#define DUNST_IFAC "org.dunstproject.cmd0"
#define DUNST_NAME "org.freedesktop.Notifications"
#define PROPERTIES_IFAC "org.freedesktop.DBus.Properties"
GDBusConnection *dbus_conn; GDBusConnection *dbus_conn;
static GDBusNodeInfo *introspection_data = NULL; static GDBusNodeInfo *introspection_data = NULL;
@ -62,6 +69,22 @@ static const char *introspection_xml =
" <arg name=\"id\" type=\"u\"/>" " <arg name=\"id\" type=\"u\"/>"
" <arg name=\"action_key\" type=\"s\"/>" " <arg name=\"action_key\" type=\"s\"/>"
" </signal>" " </signal>"
" </interface>"
" <interface name=\""DUNST_IFAC"\">"
" <method name=\"ContextMenuCall\" />"
" <method name=\"NotificationAction\">"
" <arg name=\"number\" type=\"i\"/>"
" </method>"
" <method name=\"NotificationCloseLast\" />"
" <method name=\"NotificationCloseAll\" />"
" <method name=\"NotificationShow\" />"
" <method name=\"Ping\" />"
" <property name=\"running\" type=\"b\" access=\"readwrite\">"
" <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
" </property>"
" </interface>" " </interface>"
"</node>"; "</node>";
@ -98,7 +121,6 @@ DBUS_METHOD(Notify);
DBUS_METHOD(CloseNotification); DBUS_METHOD(CloseNotification);
DBUS_METHOD(GetCapabilities); DBUS_METHOD(GetCapabilities);
DBUS_METHOD(GetServerInformation); DBUS_METHOD(GetServerInformation);
static struct dbus_method methods_fdn[] = { static struct dbus_method methods_fdn[] = {
{"CloseNotification", dbus_cb_CloseNotification}, {"CloseNotification", dbus_cb_CloseNotification},
{"GetCapabilities", dbus_cb_GetCapabilities}, {"GetCapabilities", dbus_cb_GetCapabilities},
@ -106,7 +128,7 @@ static struct dbus_method methods_fdn[] = {
{"Notify", dbus_cb_Notify}, {"Notify", dbus_cb_Notify},
}; };
void handle_method_call(GDBusConnection *connection, void dbus_cb_fdn_methods(GDBusConnection *connection,
const gchar *sender, const gchar *sender,
const gchar *object_path, const gchar *object_path,
const gchar *interface_name, const gchar *interface_name,
@ -115,9 +137,9 @@ void handle_method_call(GDBusConnection *connection,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
gpointer user_data) gpointer user_data)
{ {
struct dbus_method *m = bsearch(
method_name, struct dbus_method *m = bsearch(method_name,
&methods_fdn, methods_fdn,
G_N_ELEMENTS(methods_fdn), G_N_ELEMENTS(methods_fdn),
sizeof(struct dbus_method), sizeof(struct dbus_method),
cmp_methods); cmp_methods);
@ -131,6 +153,144 @@ void handle_method_call(GDBusConnection *connection,
} }
} }
DBUS_METHOD(dunst_ContextMenuCall);
DBUS_METHOD(dunst_NotificationAction);
DBUS_METHOD(dunst_NotificationCloseAll);
DBUS_METHOD(dunst_NotificationCloseLast);
DBUS_METHOD(dunst_NotificationShow);
DBUS_METHOD(dunst_Ping);
static struct dbus_method methods_dunst[] = {
{"ContextMenuCall", dbus_cb_dunst_ContextMenuCall},
{"NotificationAction", dbus_cb_dunst_NotificationAction},
{"NotificationCloseAll", dbus_cb_dunst_NotificationCloseAll},
{"NotificationCloseLast", dbus_cb_dunst_NotificationCloseLast},
{"NotificationShow", dbus_cb_dunst_NotificationShow},
{"Ping", dbus_cb_dunst_Ping},
};
void dbus_cb_dunst_methods(GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
struct dbus_method *m = bsearch(method_name,
methods_dunst,
G_N_ELEMENTS(methods_dunst),
sizeof(struct dbus_method),
cmp_methods);
if (m) {
m->method(connection, sender, parameters, invocation);
} else {
LOG_M("Unknown method name: '%s' (sender: '%s').",
method_name,
sender);
}
}
static void dbus_cb_dunst_ContextMenuCall(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
LOG_D("CMD: Calling context menu");
context_menu();
g_dbus_method_invocation_return_value(invocation, NULL);
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
static void dbus_cb_dunst_NotificationAction(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
int notification_nr = 0;
g_variant_get(parameters, "(i)", &notification_nr);
LOG_D("CMD: Calling action for notification %d", notification_nr);
if (notification_nr < 0 || queues_length_waiting() < notification_nr) {
g_dbus_method_invocation_return_error(invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Couldn't activate action for notification in position %d, %d notifications currently open",
notification_nr, queues_length_waiting());
return;
}
const GList *list = g_list_nth_data(queues_get_displayed(), notification_nr);
if (list && list->data) {
struct notification *n = list->data;
LOG_D("CMD: Calling action for notification %s", n->summary);
notification_do_action(n);
}
g_dbus_method_invocation_return_value(invocation, NULL);
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
static void dbus_cb_dunst_NotificationCloseAll(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
LOG_D("CMD: Pushing all to history");
queues_history_push_all();
wake_up();
g_dbus_method_invocation_return_value(invocation, NULL);
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
static void dbus_cb_dunst_NotificationCloseLast(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
LOG_D("CMD: Closing last notification");
const GList *list = queues_get_displayed();
if (list && list->data) {
struct notification *n = list->data;
queues_notification_close_id(n->id, REASON_USER);
wake_up();
}
g_dbus_method_invocation_return_value(invocation, NULL);
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
static void dbus_cb_dunst_NotificationShow(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
LOG_D("CMD: Showing last notification from history");
queues_history_pop();
wake_up();
g_dbus_method_invocation_return_value(invocation, NULL);
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
/* Just a simple Ping command to give the ability to dunstctl to test for the existence of this interface
* Any other way requires parsing the XML of the Introspection or other foo. Just calling the Ping on an old dunst version will fail. */
static void dbus_cb_dunst_Ping(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
g_dbus_method_invocation_return_value(invocation, NULL);
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
static void dbus_cb_GetCapabilities( static void dbus_cb_GetCapabilities(
GDBusConnection *connection, GDBusConnection *connection,
const gchar *sender, const gchar *sender,
@ -347,11 +507,9 @@ static void dbus_cb_GetServerInformation(
GVariant *parameters, GVariant *parameters,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
{ {
GVariant *value; GVariant *answer = g_variant_new("(ssss)", "dunst", "knopwob", VERSION, "1.2");
value = g_variant_new("(ssss)", "dunst", "knopwob", VERSION, "1.2");
g_dbus_method_invocation_return_value(invocation, value);
g_dbus_method_invocation_return_value(invocation, answer);
g_dbus_connection_flush(connection, NULL, NULL, NULL); g_dbus_connection_flush(connection, NULL, NULL, NULL);
} }
@ -420,28 +578,81 @@ void signal_action_invoked(const struct notification *n, const char *identifier)
} }
} }
static const GDBusInterfaceVTable interface_vtable = { GVariant *dbus_cb_dunst_Properties_Get(GDBusConnection *connection,
handle_method_call const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
gpointer user_data)
{
struct dunst_status status = dunst_status_get();
if (STR_EQ(property_name, "running")) {
return g_variant_new_boolean(status.running);
} else {
LOG_W("Unknown property!\n");
*error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property");
return NULL;
}
}
gboolean dbus_cb_dunst_Properties_Set(GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GVariant *value,
GError **error,
gpointer user_data)
{
if (STR_EQ(property_name, "running")) {
dunst_status(S_RUNNING, g_variant_get_boolean(value));
wake_up();
return true;
}
*error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property");
return false;
}
static const GDBusInterfaceVTable interface_vtable_fdn = {
dbus_cb_fdn_methods
};
static const GDBusInterfaceVTable interface_vtable_dunst = {
dbus_cb_dunst_methods,
dbus_cb_dunst_Properties_Get,
dbus_cb_dunst_Properties_Set,
}; };
static void dbus_cb_bus_acquired(GDBusConnection *connection, static void dbus_cb_bus_acquired(GDBusConnection *connection,
const gchar *name, const gchar *name,
gpointer user_data) gpointer user_data)
{ {
guint registration_id;
GError *err = NULL; GError *err = NULL;
if(!g_dbus_connection_register_object(
registration_id = g_dbus_connection_register_object(connection, connection,
FDN_PATH, FDN_PATH,
introspection_data->interfaces[0], introspection_data->interfaces[0],
&interface_vtable, &interface_vtable_fdn,
NULL, NULL,
NULL, NULL,
&err); &err)) {
DIE("Unable to register dbus connection interface '%s': %s", introspection_data->interfaces[0]->name, err->message);
}
if (registration_id == 0) { if(!g_dbus_connection_register_object(
DIE("Unable to register dbus connection: %s", err->message); connection,
FDN_PATH,
introspection_data->interfaces[1],
&interface_vtable_dunst,
NULL,
NULL,
&err)) {
DIE("Unable to register dbus connection interface '%s': %s", introspection_data->interfaces[1]->name, err->message);
} }
} }
@ -449,6 +660,8 @@ static void dbus_cb_name_acquired(GDBusConnection *connection,
const gchar *name, const gchar *name,
gpointer user_data) gpointer user_data)
{ {
// If we're not able to get org.fd.N bus, we've still got a problem
if (STR_EQ(name, FDN_NAME))
dbus_conn = connection; dbus_conn = connection;
} }

View File

@ -3,6 +3,7 @@
#ifndef DUNST_DBUS_H #ifndef DUNST_DBUS_H
#define DUNST_DBUS_H #define DUNST_DBUS_H
#include "dunst.h"
#include "notification.h" #include "notification.h"
/// The reasons according to the notification spec /// The reasons according to the notification spec

View File

@ -799,6 +799,12 @@ TEST assert_methodlists_sorted(void)
methods_fdn[i+1].method_name)); methods_fdn[i+1].method_name));
} }
for (size_t i = 0; i+1 < G_N_ELEMENTS(methods_dunst); i++) {
ASSERT(0 > strcmp(
methods_dunst[i].method_name,
methods_dunst[i+1].method_name));
}
PASS(); PASS();
} }

View File

@ -1,6 +1,15 @@
#define dbus_signal_status_changed(status) signal_sent_stub(status)
#include "../src/dunst.c" #include "../src/dunst.c"
#include "greatest.h" #include "greatest.h"
static bool signal_sent = false;
void signal_sent_stub(struct dunst_status status)
{
signal_sent = true;
return;
}
TEST test_dunst_status(void) TEST test_dunst_status(void)
{ {
status = (struct dunst_status) {false, false, false}; status = (struct dunst_status) {false, false, false};

View File

@ -9,10 +9,12 @@ make -C "${BASE}" SYSTEMD=1 SERVICEDIR_SYSTEMD="${PREFIX}/systemd" SERVICEDIR_DB
diff -u <(find "${PREFIX}" -type f -printf "%P\n" | sort) - <<EOF diff -u <(find "${PREFIX}" -type f -printf "%P\n" | sort) - <<EOF
bin/dunst bin/dunst
bin/dunstctl
bin/dunstify bin/dunstify
dbus/org.knopwob.dunst.service dbus/org.knopwob.dunst.service
share/dunst/dunstrc share/dunst/dunstrc
share/man/man1/dunst.1 share/man/man1/dunst.1
share/man/man1/dunstctl.1
systemd/dunst.service systemd/dunst.service
EOF EOF