diff --git a/config.h b/config.h index 3dc7b0a..f0432f6 100644 --- a/config.h +++ b/config.h @@ -102,6 +102,12 @@ settings_t defaults = { .code = 0,.sym = NoSymbol,.is_valid = false }, /* ignore this */ +.mouse_left_click = MOUSE_CLOSE_CURRENT, + +.mouse_middle_click = MOUSE_DO_ACTION, + +.mouse_right_click = MOUSE_CLOSE_ALL, + }; rule_t default_rules[] = { diff --git a/docs/dunst.pod b/docs/dunst.pod index 41ccfb6..743ffd2 100644 --- a/docs/dunst.pod +++ b/docs/dunst.pod @@ -472,6 +472,30 @@ single notification. To avoid the corners clipping the icon or text the corner radius will be automatically lowered to half of the notification height if it exceeds it. +=item B (values: [none/do_action/close_current/close_all]) + +Defines action of mouse click. + +=over 4 + +=item B + +Don't do anything. + +=item B (default for mouse_middle_click) + +If the notification has exactly one action, or one is marked as default, invoke it. If there are multiple and no default, open the context menu. + +=item B (default for mouse_left_click) + +Close current notification. + +=item B (default for mouse_right_click) + +Close all notifications. + +=back + =back =head2 Shortcut section diff --git a/dunstrc b/dunstrc index 406c7a7..b3f99fb 100644 --- a/dunstrc +++ b/dunstrc @@ -226,6 +226,19 @@ # layout changes. force_xinerama = false + ### mouse + + # Defines action of mouse event + # Possible values are: + # * none: Don't do anything. + # * do_action: If the notification has exactly one action, or one is marked as default, + # invoke it. If there are multiple and no default, open the context menu. + # * close_current: Close current notification. + # * close_all: Close all notifications. + mouse_left_click = close_current + mouse_middle_click = do_action + mouse_right_click = close_all + # Experimental features that may or may not work correctly. Do not expect them # to have a consistent behaviour across releases. [experimental] diff --git a/src/settings.c b/src/settings.c index f278ac6..5d3fbff 100644 --- a/src/settings.c +++ b/src/settings.c @@ -49,6 +49,23 @@ static enum markup_mode parse_markup_mode(const char *mode) } } +static enum mouse_action parse_mouse_action(const char *action) +{ + if (strcmp(action, "none") == 0) + return MOUSE_NONE; + else if (strcmp(action, "do_action") == 0) + return MOUSE_DO_ACTION; + else if (strcmp(action, "close_current") == 0) + return MOUSE_CLOSE_CURRENT; + else if (strcmp(action, "close_all") == 0) + return MOUSE_CLOSE_ALL; + else { + LOG_W("Unknown mouse action: '%s'", action); + return MOUSE_NONE; + } +} + + static enum urgency ini_get_urgency(const char *section, const char *key, const int def) { int ret = def; @@ -516,6 +533,55 @@ void load_settings(char *cmdline_config_path) ); } + + { + char *c = option_get_string( + "global", + "mouse_left_click", "-left_click", NULL, + "Action of Left click event" + ); + + if (c) { + settings.mouse_left_click = parse_mouse_action(c); + } else { + settings.mouse_left_click = defaults.mouse_left_click; + } + + g_free(c); + } + + { + char *c = option_get_string( + "global", + "mouse_middle_click", "-mouse_middle_click", NULL, + "Action of middle click event" + ); + + if (c) { + settings.mouse_middle_click = parse_mouse_action(c); + } else { + settings.mouse_middle_click = defaults.mouse_middle_click; + } + + g_free(c); + } + + { + char *c = option_get_string( + "global", + "mouse_right_click", "-mouse_right_click", NULL, + "Action of right click event" + ); + + if (c) { + settings.mouse_right_click = parse_mouse_action(c); + } else { + settings.mouse_right_click = defaults.mouse_right_click; + } + + g_free(c); + } + settings.lowbgcolor = option_get_string( "urgency_low", "background", "-lb", defaults.lowbgcolor, diff --git a/src/settings.h b/src/settings.h index ece154e..272e079 100644 --- a/src/settings.h +++ b/src/settings.h @@ -12,6 +12,7 @@ enum icon_position_t { icons_left, icons_right, icons_off }; enum separator_color { SEP_FOREGROUND, SEP_AUTO, SEP_FRAME, SEP_CUSTOM }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; enum markup_mode { MARKUP_NULL, MARKUP_NO, MARKUP_STRIP, MARKUP_FULL }; +enum mouse_action { MOUSE_NONE, MOUSE_DO_ACTION, MOUSE_CLOSE_CURRENT, MOUSE_CLOSE_ALL }; struct geometry { int x; @@ -85,6 +86,9 @@ typedef struct _settings { keyboard_shortcut context_ks; bool force_xinerama; int corner_radius; + enum mouse_action mouse_left_click; + enum mouse_action mouse_middle_click; + enum mouse_action mouse_right_click; } settings_t; extern settings_t settings; diff --git a/src/x11/x.c b/src/x11/x.c index 8e94598..21eed84 100644 --- a/src/x11/x.c +++ b/src/x11/x.c @@ -386,13 +386,30 @@ bool x_is_idle(void) */ static void x_handle_click(XEvent ev) { - if (ev.xbutton.button == Button3) { + enum mouse_action act; + + switch (ev.xbutton.button) { + case Button1: + act = settings.mouse_left_click; + break; + case Button2: + act = settings.mouse_middle_click; + break; + case Button3: + act = settings.mouse_right_click; + break; + default: + LOG_W("Unsupported mouse button: '%d'", ev.xbutton.button); + return; + } + + if (act == MOUSE_CLOSE_ALL) { queues_history_push_all(); return; } - if (ev.xbutton.button == Button1 || ev.xbutton.button == Button2) { + if (act == MOUSE_DO_ACTION || act == MOUSE_CLOSE_CURRENT) { int y = settings.separator_height; notification *n = NULL; int first = true; @@ -408,7 +425,7 @@ static void x_handle_click(XEvent ev) } if (n) { - if (ev.xbutton.button == Button1) + if (act == MOUSE_CLOSE_CURRENT) queues_notification_close(n, REASON_USER); else notification_do_action(n);