Skip to content

Commit

Permalink
Merge pull request #1350 from bynect/reload
Browse files Browse the repository at this point in the history
Add config reload mechanism
  • Loading branch information
bynect authored Jul 15, 2024
2 parents 5c16b3c + 703bc5a commit 844167a
Show file tree
Hide file tree
Showing 27 changed files with 398 additions and 160 deletions.
1 change: 1 addition & 0 deletions completions/_dunstctl.zshcomp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ case $state in
'set-pause-level:Set the pause level'
'rule:Enable or disable a rule by its name'
'rules:Displays configured rules'
'reload:Reload the settings of the running instance, optionally with specific configuration files'
'debug:Print debugging information'
'help:Show help'
)
Expand Down
2 changes: 1 addition & 1 deletion completions/dunstctl.bashcomp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ _dunstctl() {
local opts cur prev
_get_comp_words_by_ref cur prev
COMPREPLY=()
opts='action close close-all context count debug help history history-clear history-pop history-rm is-paused rule rules set-paused get-pause-level set-pause-level'
opts='action close close-all context count debug help history history-clear history-pop history-rm is-paused rule rules set-paused get-pause-level set-pause-level reload'

case "$prev" in
count) COMPREPLY=( $( compgen -W 'displayed history waiting' -- "$cur" ) )
Expand Down
2 changes: 2 additions & 0 deletions completions/dunstctl.fishcomp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ complete -c dunstctl -f -n __fish_use_subcommand -a get-pause-level -d 'Get the
complete -c dunstctl -f -n __fish_use_subcommand -a set-pause-level -d 'Set the pause level'
complete -c dunstctl -f -n __fish_use_subcommand -a rules -d 'Displays configured rules (optionally in JSON)'
complete -c dunstctl -f -n __fish_use_subcommand -a rule -d 'Enable or disable a rule by its name'
complete -c dunstctl -f -n __fish_use_subcommand -a reload -d 'Reload the settings of the running instance, optionally with specific configuration files'
complete -c dunstctl -f -n __fish_use_subcommand -a debug -d 'Print debugging information'
complete -c dunstctl -f -n __fish_use_subcommand -a help -d 'Show help'

Expand All @@ -38,5 +39,6 @@ complete -c dunstctl -x -n '__fish_seen_subcommand_from history-pop history-rm'
complete -c dunstctl -x -n '__fish_seen_subcommand_from set-paused' -a 'true false toggle'
complete -c dunstctl -x -n '__fish_seen_subcommand_from rule' -a '(__fish_dunstctl_rule_complete (commandline -c))'
complete -c dunstctl -x -n '__fish_seen_subcommand_from rules' -a --json
complete -c dunstctl -n '__fish_seen_subcommand_from reload'

# ex: filetype=fish
10 changes: 9 additions & 1 deletion docs/dunstctl.pod
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ will be kept but not shown until it is unpaused.
=item B<set-paused> true/false/toggle

Set the paused status of dunst. If false, dunst is running normally, if true,
dunst is paused (with maximum pause level of 100).
dunst is paused (with maximum pause level of 100).
See the is-paused command and the dunst man page for more information.

=item B<get-pause-level>
Expand All @@ -90,6 +90,14 @@ to temporarily activate or deactivate specific rules.

Exports all currently configured rules (optionally JSON formatted).

=item B<reload> [dunstrc ...]

Reload the settings of the running dunst instance. You can optionally specify
which configuration files to use. Otherwise, the config specified by the first invocation
of dunst will be reloaded.
When dunst is reloaded all the rules are reapplied to the original notification,
so modifications made by previous rules are not taken into account.

=item B<debug>

Tries to contact dunst and checks for common faults between dunstctl and dunst.
Expand Down
11 changes: 9 additions & 2 deletions dunstctl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ show_help() {
context menu of the notification at the
given position
close [ID] Close the last notification or the
notification with given ID.
notification with given ID
close-all Close all the notifications
context Open context menu
count [displayed|history|waiting] Show the number of notifications
Expand All @@ -37,6 +37,9 @@ show_help() {
rule name enable|disable|toggle Enable or disable a rule by its name
rules [--json] Displays configured rules (optionally
in JSON)
reload [dunstrc ...] Reload the settings of the running
instance, optionally with specific
config files (space/comma-separated)
debug Print debugging information
help Show help
EOH
Expand Down Expand Up @@ -206,8 +209,12 @@ case "${1:-}" in
busctl --user --json=pretty --no-pager call org.freedesktop.Notifications /org/freedesktop/Notifications org.dunstproject.cmd0 NotificationListHistory 2>/dev/null \
|| die "Dunst is not running."
;;
"reload")
shift
method_call "${DBUS_IFAC_DUNST}.ConfigReload" "array:string:$(IFS=','; echo "$*")" >/dev/null
;;
"")
die "dunstctl: No command specified. Please consult the usage."
die "dunstctl: No command specified. Use dunstctl help"
;;
*)
die "dunstctl: unrecognized command '${1:-}'. Please consult the usage."
Expand Down
42 changes: 37 additions & 5 deletions src/dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ static const char *introspection_xml =
" <method name=\"RuleList\">"
" <arg direction=\"out\" name=\"rules\" type=\"aa{sv}\"/>"
" </method>"
" <method name=\"ConfigReload\">"
" <arg direction=\"in\" name=\"configs\" type=\"as\"/>"
" </method>"
" <method name=\"Ping\" />"

" <property name=\"paused\" type=\"b\" access=\"readwrite\">"
Expand Down Expand Up @@ -193,8 +196,12 @@ DBUS_METHOD(dunst_NotificationRemoveFromHistory);
DBUS_METHOD(dunst_NotificationShow);
DBUS_METHOD(dunst_RuleEnable);
DBUS_METHOD(dunst_RuleList);
DBUS_METHOD(dunst_ConfigReload);
DBUS_METHOD(dunst_Ping);

// NOTE: Keep the names sorted alphabetically
static struct dbus_method methods_dunst[] = {
{"ConfigReload", dbus_cb_dunst_ConfigReload},
{"ContextMenuCall", dbus_cb_dunst_ContextMenuCall},
{"NotificationAction", dbus_cb_dunst_NotificationAction},
{"NotificationClearHistory", dbus_cb_dunst_NotificationClearHistory},
Expand Down Expand Up @@ -603,6 +610,19 @@ static void dbus_cb_dunst_RuleEnable(GDBusConnection *connection,
g_dbus_connection_flush(connection, NULL, NULL, NULL);
}

static void dbus_cb_dunst_ConfigReload(GDBusConnection *connection,
const gchar *sender,
GVariant *parameters,
GDBusMethodInvocation *invocation)
{
gchar **configs = NULL;
g_variant_get(parameters, "(^as)", &configs);
reload(configs);

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,
Expand Down Expand Up @@ -790,29 +810,41 @@ static struct notification *dbus_message_to_notification(const gchar *sender, GV
// Modify these values after the notification is initialized and all rules are applied.
if ((dict_value = g_variant_lookup_value(hints, "fgcolor", G_VARIANT_TYPE_STRING))) {
struct color c;
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c))
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c)) {
notification_keep_original(n);
if (!COLOR_VALID(n->original->fg)) n->original->fg = n->colors.fg;
n->colors.fg = c;
}
g_variant_unref(dict_value);
}

if ((dict_value = g_variant_lookup_value(hints, "bgcolor", G_VARIANT_TYPE_STRING))) {
struct color c;
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c))
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c)) {
notification_keep_original(n);
if (!COLOR_VALID(n->original->bg)) n->original->bg = n->colors.bg;
n->colors.bg = c;
}
g_variant_unref(dict_value);
}

if ((dict_value = g_variant_lookup_value(hints, "frcolor", G_VARIANT_TYPE_STRING))) {
struct color c;
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c))
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c)) {
notification_keep_original(n);
if (!COLOR_VALID(n->original->fc)) n->original->fc = n->colors.frame;
n->colors.frame = c;
}
g_variant_unref(dict_value);
}

if ((dict_value = g_variant_lookup_value(hints, "hlcolor", G_VARIANT_TYPE_STRING))) {
struct color c;
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c))
if (string_parse_color(g_variant_get_string(dict_value, NULL), &c)) {
notification_keep_original(n);
if (!COLOR_VALID(n->original->highlight)) n->original->highlight = n->colors.highlight;
n->colors.highlight = c;
}
g_variant_unref(dict_value);
}

Expand Down Expand Up @@ -1083,7 +1115,7 @@ gboolean dbus_cb_dunst_Properties_Set(GDBusConnection *connection,
int targetPauseLevel = -1;
if (STR_EQ(property_name, "paused")) {
if (g_variant_get_boolean(value)) {
targetPauseLevel = MAX_PAUSE_LEVEL;
targetPauseLevel = MAX_PAUSE_LEVEL;
} else {
targetPauseLevel = 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ void draw(void)

void draw_deinit(void)
{
pango_font_description_free(pango_fdesc);
output->win_destroy(win);
output->deinit();
if (settings.enable_recursive_icon_lookup)
Expand Down
44 changes: 38 additions & 6 deletions src/dunst.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ GMainLoop *mainloop = NULL;

static struct dunst_status status;
static bool setup_done = false;
static char **config_paths = NULL;

/* see dunst.h */
void dunst_status(const enum dunst_status_field field,
Expand Down Expand Up @@ -205,11 +206,31 @@ static void teardown(void)
queues_teardown();

draw_deinit();

g_strfreev(config_paths);
}

int dunst_main(int argc, char *argv[])
void reload(char **const configs)
{
guint length = g_strv_length(configs);
LOG_M("Reloading settings (with the %s files)", length != 0 ? "new" : "old");

pause_signal(NULL);

setup_done = false;
draw_deinit();

load_settings(configs);
draw_setup();
setup_done = true;

queues_reapply_all_rules();

unpause_signal(NULL);
}

int dunst_main(int argc, char *argv[])
{
dunst_status_int(S_PAUSE_LEVEL, 0);
dunst_status(S_IDLE, false);

Expand All @@ -229,10 +250,21 @@ int dunst_main(int argc, char *argv[])
log_set_level_from_string(verbosity);
g_free(verbosity);

char *cmdline_config_path;
cmdline_config_path =
cmdline_get_string("-conf/-config", NULL,
"Path to configuration file");
cmdline_usage_append("-conf/-config", "string", "Path to configuration file");

int start = 1, count = 1;
while (cmdline_get_string_offset("-conf/-config", NULL, start, &start))
count++;

// Leaves an extra space for the NULL
config_paths = g_malloc0(sizeof(char *) * count);
start = 1, count = 0;
char *path = NULL;

do {
path = cmdline_get_string_offset("-conf/-config", NULL, start, &start);
config_paths[count++] = path;
} while (path != NULL);

settings.print_notifications = cmdline_get_bool("-print/--print", false, "Print notifications to stdout");

Expand All @@ -244,7 +276,7 @@ int dunst_main(int argc, char *argv[])
usage(EXIT_SUCCESS);
}

load_settings(cmdline_config_path);
load_settings(config_paths);
int dbus_owner_id = dbus_init();

mainloop = g_main_loop_new(NULL, FALSE);
Expand Down
1 change: 1 addition & 0 deletions src/dunst.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void dunst_status_int(const enum dunst_status_field field,
struct dunst_status dunst_status_get(void);

void wake_up(void);
void reload(char **const configs);

int dunst_main(int argc, char *argv[]);

Expand Down
3 changes: 2 additions & 1 deletion src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

#include "utils.h"

static GLogLevelFlags log_level = G_LOG_LEVEL_WARNING;
// NOTE: Keep updated with the dunst manual
static GLogLevelFlags log_level = G_LOG_LEVEL_MESSAGE;

/* see log.h */
static const char *log_level_to_string(GLogLevelFlags level)
Expand Down
21 changes: 18 additions & 3 deletions src/notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "utils.h"
#include "draw.h"
#include "icon-lookup.h"
#include "settings_data.h"

static void notification_extract_urls(struct notification *n);
static void notification_format_message(struct notification *n);
Expand Down Expand Up @@ -293,6 +294,15 @@ void notification_unref(struct notification *n)
if (!g_atomic_int_dec_and_test(&n->priv->refcount))
return;

if (n->original) {
g_free(n->original->action_name);
g_free(n->original->set_category);
g_free(n->original->default_icon);
g_free(n->original->set_stack_tag);
g_free(n->original->new_icon);
g_free(n->original);
}

g_free(n->appname);
g_free(n->summary);
g_free(n->body);
Expand All @@ -316,9 +326,7 @@ void notification_unref(struct notification *n)

notification_private_free(n->priv);

if (n->script_count > 0) {
g_free(n->scripts);
}
g_strfreev(n->scripts);

g_free(n);
}
Expand Down Expand Up @@ -770,4 +778,11 @@ void notification_invalidate_actions(struct notification *n) {
g_hash_table_remove_all(n->actions);
}

void notification_keep_original(struct notification *n)
{
if (n->original) return;
n->original = g_malloc0(sizeof(struct rule));
*n->original = empty_rule;
}

/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
9 changes: 7 additions & 2 deletions src/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ struct notification {
char *dbus_client;
bool dbus_valid;

// We keep the original notification properties here when it is modified
struct rule *original;

char *appname;
char *summary;
char *body;
Expand Down Expand Up @@ -83,7 +86,7 @@ struct notification {

enum markup_mode markup;
const char *format;
const char **scripts;
char **scripts;
int script_count;
struct notification_colors colors;

Expand Down Expand Up @@ -242,7 +245,7 @@ void notification_open_url(struct notification *n);

/**
* Open the context menu for the notification.
*
*
* Convenience function that creates the GList and passes it to context_menu_for().
*/
void notification_open_context_menu(struct notification *n);
Expand All @@ -266,5 +269,7 @@ const char *notification_urgency_to_string(const enum urgency urgency);
*/
const char *enum_to_string_fullscreen(enum behavior_fullscreen in);

void notification_keep_original(struct notification *n);

#endif
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
Loading

0 comments on commit 844167a

Please sign in to comment.