diff --git a/contrib/dunstctl.fishcomp b/contrib/dunstctl.fishcomp
index 7b59c9ba6..006e8b96d 100644
--- a/contrib/dunstctl.fishcomp
+++ b/contrib/dunstctl.fishcomp
@@ -1,17 +1,17 @@
if command -q jq
function __fish_dunstctl_info
- dunstctl $argv[1] | jq -r ".data[][] | \"\(.$argv[2].data)\t\(.$argv[3].data)\""
+ dunstctl (string split ' ' $argv[1]) | jq -r ".data[][] | \"\(.$argv[2].data)\t\(.$argv[3].data)\""
end
else
function __fish_dunstctl_info
- dunstctl $argv[1] | awk -vpattern="\"$argv[2]\" :" '$0 ~ pattern {getline; getline; gsub("\"", "", $3); print $3}'
+ dunstctl (string split ' ' $argv[1]) | awk -vpattern="\"$argv[2]\" :" '$0 ~ pattern {getline; getline; gsub("\"", "", $3); print $3}'
end
end
function __fish_dunstctl_rule_complete
set -l parts (string split ' ' $argv[1])
if test (count $parts[-1]) -eq 0 || test $parts[-2] = rule
- __fish_dunstctl_info rules name enabled
+ __fish_dunstctl_info 'rules --json' name enabled
return
end
# TODO? enable disable might not make sense when the rule is already in the correct state
diff --git a/dunstctl b/dunstctl
index 90afb5856..a42a7197c 100755
--- a/dunstctl
+++ b/dunstctl
@@ -34,7 +34,8 @@ show_help() {
get-pause-level Get the current pause level
set-pause-level level Set the pause level
rule name enable|disable|toggle Enable or disable a rule by its name
- rules [--json] Displays configured rules (in JSON)
+ rules [--json] Displays configured rules (optionally
+ in JSON)
debug Print debugging information
help Show this help
EOH
@@ -127,7 +128,7 @@ case "${1:-}" in
"rules")
case "${2:-}" in
"")
- method_call "${DBUS_IFAC_DUNST}.RuleList"
+ method_call "${DBUS_IFAC_DUNST}.RuleListHumanReadable" | sed '1s/^[[:space:]]\+//'
;;
--json)
busctl --user --json=pretty --no-pager call "${DBUS_NAME}" "${DBUS_PATH}" "${DBUS_IFAC_DUNST}" RuleList 2>/dev/null \
diff --git a/src/dbus.c b/src/dbus.c
index 4d3c0d509..50d56866a 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -97,6 +97,9 @@ static const char *introspection_xml =
" "
" "
" "
+ " "
+ " "
+ " "
" "
" "
@@ -190,6 +193,7 @@ DBUS_METHOD(dunst_NotificationRemoveFromHistory);
DBUS_METHOD(dunst_NotificationShow);
DBUS_METHOD(dunst_RuleEnable);
DBUS_METHOD(dunst_RuleList);
+DBUS_METHOD(dunst_RuleListHumanReadable);
DBUS_METHOD(dunst_Ping);
static struct dbus_method methods_dunst[] = {
{"ContextMenuCall", dbus_cb_dunst_ContextMenuCall},
@@ -204,6 +208,7 @@ static struct dbus_method methods_dunst[] = {
{"Ping", dbus_cb_dunst_Ping},
{"RuleEnable", dbus_cb_dunst_RuleEnable},
{"RuleList", dbus_cb_dunst_RuleList},
+ {"RuleListHumanReadable", dbus_cb_dunst_RuleListHumanReadable},
};
void dbus_cb_dunst_methods(GDBusConnection *connection,
@@ -481,6 +486,67 @@ static void dbus_cb_dunst_RuleList(GDBusConnection *connection,
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}
+static void add_rule_entry_string(GStrvBuilder *builder, const char *name, const char *value) {
+ if (value)
+ g_strv_builder_add(builder, g_strdup_printf(" %s = %s", name, value));
+}
+
+static void dbus_cb_dunst_RuleListHumanReadable(GDBusConnection *connection,
+ const gchar *sender,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation)
+{
+ LOG_D("CMD: Listing all configured rules in human readable format");
+
+ GStrvBuilder *builder = g_strv_builder_new();
+
+ for (GSList *iter = rules; iter; iter = iter->next) {
+ struct rule *r = iter->data;
+
+ if (is_special_section(r->name)) {
+ continue;
+ }
+
+ g_strv_builder_add(builder, g_strdup_printf("[%s]", r->name));
+
+ // filters - order according to rule_matches_notification
+ if (r->enabled)
+ g_strv_builder_add(builder, g_strdup_printf(" enabled = %s", r->enabled ? "yes" : "no"));
+ // undocumented filter?
+ if (r->match_dbus_timeout >= 0)
+ g_strv_builder_add(builder, g_strdup_printf(" match_dbus_timeout = %ld", r->match_dbus_timeout));
+ if (r->msg_urgency != URG_NONE) {
+ const char *msg_urgency;
+ switch (r->msg_urgency) {
+ case URG_LOW:
+ msg_urgency = "low";
+ case URG_NORM:
+ msg_urgency = "normal";
+ case URG_CRIT:
+ msg_urgency = "critical";
+ }
+ g_strv_builder_add(builder, g_strdup_printf(" msg_urgency = %s", msg_urgency));
+ }
+ if (r->match_transient >= 0)
+ g_strv_builder_add(builder, g_strdup_printf(" match_transient = %s", r->match_transient ? "yes" : "no"));
+ add_rule_entry_string(builder, "appname", r->appname);
+ add_rule_entry_string(builder, "desktop_entry", r->desktop_entry);
+ add_rule_entry_string(builder, "summary", r->summary);
+ add_rule_entry_string(builder, "body", r->body);
+ add_rule_entry_string(builder, "category", r->category);
+ add_rule_entry_string(builder, "stack_tag", r->stack_tag);
+
+ // add an empty line after each rule to make it easier to read
+ g_strv_builder_add(builder, "");
+ }
+
+ gchar **answer = g_strv_builder_end(builder);
+
+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", g_strjoinv("\n", answer)));
+ g_dbus_connection_flush(connection, NULL, NULL, NULL);
+ g_strfreev(answer);
+}
+
static void dbus_cb_dunst_RuleEnable(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,