Skip to content

Commit c46db13

Browse files
committed
Feature remove_current in notification queues
1 parent fb59a30 commit c46db13

File tree

12 files changed

+135
-6
lines changed

12 files changed

+135
-6
lines changed

docs/dunst.5.pod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ B<Defaults:>
596596

597597
=item * C<mouse_left_click=close_current>
598598

599-
=item * C<mouse_middle_click=do_action, close_current>
599+
=item * C<mouse_middle_click=do_action, remove_current>
600600

601601
=item * C<mouse_right_click=close_all>
602602

dunstrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,14 @@
320320
# * open_url: If the notification has exactly one url, open it. If there are multiple
321321
# ones, open the context menu.
322322
# * close_current: Close current notification.
323+
# * remove_current: Remove current notification from history.
323324
# * close_all: Close all notifications.
324325
# * context: Open context menu for the notification.
325326
# * context_all: Open context menu for all notifications.
326327
# These values can be strung together for each mouse event, and
327328
# will be executed in sequence.
328329
mouse_left_click = close_current
329-
mouse_middle_click = do_action, close_current
330+
mouse_middle_click = do_action, remove_current
330331
mouse_right_click = close_all
331332

332333
# Experimental features that may or may not work correctly. Do not expect them

src/dbus.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,63 @@ void signal_notification_closed(struct notification *n, enum reason reason)
11171117
}
11181118
}
11191119

1120+
void signal_notification_removed(struct notification *n, enum reason reason)
1121+
{
1122+
if (!n->dbus_valid) {
1123+
LOG_W("Removing notification with reason '%d' not supported. "
1124+
"Notification already closed.", reason);
1125+
return;
1126+
}
1127+
1128+
if (reason < REASON_MIN || REASON_MAX < reason) {
1129+
LOG_W("Removing notification with reason '%d' not supported. "
1130+
"Closing it with reason '%d'.", reason, REASON_UNDEF);
1131+
reason = REASON_UNDEF;
1132+
}
1133+
1134+
if (!dbus_conn) {
1135+
LOG_E("Unable to remove notification: No DBus connection.");
1136+
}
1137+
1138+
GVariant *body = g_variant_new("(uu)", n->id, reason);
1139+
GError *err = NULL;
1140+
1141+
g_dbus_connection_emit_signal(dbus_conn,
1142+
n->dbus_client,
1143+
FDN_PATH,
1144+
FDN_IFAC,
1145+
"NotificationRemoved",
1146+
body,
1147+
&err);
1148+
1149+
notification_invalidate_actions(n);
1150+
1151+
if (err) {
1152+
LOG_W("Unable to remove notification: %s", err->message);
1153+
g_error_free(err);
1154+
} else {
1155+
char* reason_string;
1156+
switch (reason) {
1157+
case REASON_TIME:
1158+
reason_string="time";
1159+
break;
1160+
case REASON_USER:
1161+
reason_string="user";
1162+
break;
1163+
case REASON_SIG:
1164+
reason_string="signal";
1165+
break;
1166+
case REASON_UNDEF:
1167+
reason_string="undefined";
1168+
break;
1169+
default:
1170+
reason_string="unknown";
1171+
}
1172+
1173+
LOG_D("Queues: Removing notification for reason: %s", reason_string);
1174+
}
1175+
}
1176+
11201177
void signal_action_invoked(const struct notification *n, const char *identifier)
11211178
{
11221179
if (!n->dbus_valid) {

src/dbus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ enum reason {
1919
int dbus_init(void);
2020
void dbus_teardown(int id);
2121
void signal_notification_closed(struct notification *n, enum reason reason);
22+
void signal_notification_removed(struct notification *n, enum reason reason);
2223
void signal_action_invoked(const struct notification *n, const char *identifier);
2324
void signal_length_propertieschanged(void);
2425
void signal_history_removed(guint id);

src/input.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void input_handle_click(unsigned int button, bool button_down, int mouse_x, int
9797
continue;
9898
}
9999

100-
if (act == MOUSE_DO_ACTION || act == MOUSE_CLOSE_CURRENT || act == MOUSE_CONTEXT || act == MOUSE_OPEN_URL) {
100+
if (act == MOUSE_DO_ACTION || act == MOUSE_CLOSE_CURRENT || act == MOUSE_REMOVE_CURRENT || act == MOUSE_CONTEXT || act == MOUSE_OPEN_URL) {
101101
struct notification *n = get_notification_at(mouse_y);
102102

103103
if (n) {
@@ -107,6 +107,8 @@ void input_handle_click(unsigned int button, bool button_down, int mouse_x, int
107107
notification_do_action(n);
108108
} else if (act == MOUSE_OPEN_URL) {
109109
notification_open_url(n);
110+
} else if (act == MOUSE_REMOVE_CURRENT) {
111+
n->marked_for_removal = REASON_USER;
110112
} else {
111113
notification_open_context_menu(n);
112114
}

src/menu.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,14 @@ static gboolean context_menu_result_dispatch(gpointer user_data)
355355
queues_notification_close(n, n->marked_for_closure);
356356
n->marked_for_closure = 0;
357357
}
358+
359+
// If the notification was marked for removal, remove it from history
360+
if (n->marked_for_removal) {
361+
// Don't close notification if context was aborted
362+
// if (dmenu_output != NULL)
363+
queues_notification_remove(n, n->marked_for_removal);
364+
n->marked_for_removal = 0;
365+
}
358366
}
359367

360368
menu_ctx.locked_notifications = NULL;

src/notification.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct notification {
106106
enum behavior_fullscreen fullscreen; //!< The instruction what to do with it, when desktop enters fullscreen
107107
bool script_run; /**< Has the script been executed already? */
108108
guint8 marked_for_closure;
109+
guint8 marked_for_removal; /**< If set, the notification is marked for removal in history */
109110
bool word_wrap;
110111
PangoEllipsizeMode ellipsize;
111112
PangoAlignment alignment;

src/queues.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,39 @@ void queues_notification_close_id(gint id, enum reason reason)
341341
}
342342
}
343343

344+
void queues_notification_remove_id(gint id, enum reason reason)
345+
{
346+
struct notification *target = NULL;
347+
348+
GQueue *allqueues[] = { displayed, waiting, history };
349+
for (size_t i = 0; i < sizeof(allqueues)/sizeof(GQueue*); i++) {
350+
for (GList *iter = g_queue_peek_head_link(allqueues[i]); iter;
351+
iter = iter->next) {
352+
struct notification *n = iter->data;
353+
if (n->id == id) {
354+
g_queue_remove(allqueues[i], n);
355+
target = n;
356+
break;
357+
}
358+
}
359+
}
360+
if (target)
361+
signal_notification_removed(target, reason);
362+
}
363+
344364
/* see queues.h */
345365
void queues_notification_close(struct notification *n, enum reason reason)
346366
{
347367
assert(n != NULL);
348368
queues_notification_close_id(n->id, reason);
349369
}
350370

371+
void queues_notification_remove(struct notification *n, enum reason reason)
372+
{
373+
assert(n != NULL);
374+
queues_notification_remove_id(n->id, reason);
375+
}
376+
351377
static void queues_destroy_notification(struct notification *n, gpointer user_data)
352378
{
353379
(void)user_data;
@@ -480,6 +506,13 @@ void queues_update(struct dunst_status status, gint64 time)
480506
continue;
481507
}
482508

509+
if (n->marked_for_removal) {
510+
queues_notification_remove(n, n->marked_for_removal);
511+
n->marked_for_removal = 0;
512+
iter = nextiter;
513+
continue;
514+
}
515+
483516

484517
if (queues_notification_is_finished(n, status, time)) {
485518
queues_notification_close(n, REASON_TIME);

src/queues.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,32 @@ void queues_notification_close_id(gint id, enum reason reason);
104104
*
105105
* @param n (transfer full) The notification to close
106106
* @param reason The #reason to close
107-
* */
107+
*/
108108
void queues_notification_close(struct notification *n, enum reason reason);
109109

110+
/**
111+
* Remove the given notification from all queues
112+
*
113+
* Sends a signal and removes the selected notification from all queues.
114+
*
115+
* @param n (transfer full) The notification to remove
116+
* @param reason The #reason to remove
117+
*/
118+
void queues_notification_remove(struct notification *n, enum reason reason);
119+
120+
/**
121+
* Remove the notification that has n->id == id
122+
*
123+
* Sends a signal and removes the selected notification from all queues.
124+
*
125+
* @param id The id of the notification to remove
126+
* @param reason The #reason to remove
127+
*
128+
* @post Call wake_up() to synchronize the queues with the UI
129+
* (which closes the notification on screen)
130+
*/
131+
void queues_notification_remove_id(gint id, enum reason reason);
132+
110133
/**
111134
* Removes all notifications from history
112135
* Returns the number of removed notifications

src/settings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ enum sort_type { SORT_TYPE_ID, SORT_TYPE_URGENCY_ASCENDING, SORT_TYPE_URGENCY_DE
3333
enum vertical_alignment { VERTICAL_TOP, VERTICAL_CENTER, VERTICAL_BOTTOM };
3434
enum separator_color { SEP_FOREGROUND, SEP_AUTO, SEP_FRAME, SEP_CUSTOM };
3535
enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD };
36-
enum mouse_action { MOUSE_NONE, MOUSE_DO_ACTION, MOUSE_CLOSE_CURRENT,
36+
enum mouse_action { MOUSE_NONE, MOUSE_DO_ACTION, MOUSE_CLOSE_CURRENT, MOUSE_REMOVE_CURRENT,
3737
MOUSE_CLOSE_ALL, MOUSE_CONTEXT, MOUSE_CONTEXT_ALL, MOUSE_OPEN_URL,
3838
MOUSE_ACTION_END = LIST_END /* indicates the end of a list of mouse actions */};
3939
#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM

0 commit comments

Comments
 (0)