Allow a mouse button to perform 1 or more actions in series.

The user provides a comma-separated list of valid mouse actions
that will be performed one after another when a notification is
clicked. If any one of the provided actions is invalid, the value
reverts to its default state.
This commit is contained in:
Michael Krasnitski 2020-03-22 02:37:04 -04:00
parent 94be674cf8
commit 506b4f2cfa
6 changed files with 70 additions and 51 deletions

View File

@ -103,11 +103,11 @@ struct settings defaults = {
.code = 0,.sym = NoSymbol,.is_valid = false .code = 0,.sym = NoSymbol,.is_valid = false
}, /* ignore this */ }, /* ignore this */
.mouse_left_click = MOUSE_CLOSE_CURRENT, .mouse_left_click = (enum mouse_action []){MOUSE_CLOSE_CURRENT, -1},
.mouse_middle_click = MOUSE_DO_ACTION, .mouse_middle_click = (enum mouse_action []){MOUSE_DO_ACTION, -1},
.mouse_right_click = MOUSE_CLOSE_ALL, .mouse_right_click = (enum mouse_action []){MOUSE_CLOSE_ALL, -1},
}; };

View File

@ -141,6 +141,27 @@ bool string_parse_mouse_action(const char *s, enum mouse_action *ret)
return false; return false;
} }
bool string_parse_mouse_action_list(char **s, enum mouse_action **ret)
{
ASSERT_OR_RET(s, false);
ASSERT_OR_RET(ret, false);
int len = 0;
while (s[len])
len++;
*ret = g_malloc((len + 1) * sizeof(enum mouse_action));
for (int i = 0; i < len; i++) {
if (!string_parse_mouse_action(s[i], *ret + i)) {
LOG_W("Unknown mouse action value: '%s'", s[i]);
g_free(*ret);
return false;
}
}
(*ret)[len] = -1; // sentinel end value
return true;
}
bool string_parse_sepcolor(const char *s, struct separator_color_data *ret) bool string_parse_sepcolor(const char *s, struct separator_color_data *ret)
{ {
ASSERT_OR_RET(STR_FULL(s), false); ASSERT_OR_RET(STR_FULL(s), false);
@ -484,7 +505,8 @@ char *cmdline_get_path(const char *key, const char *def, const char *description
return string_to_path(g_strdup(def)); return string_to_path(g_strdup(def));
} }
char **cmdline_get_list(const char *key, const char *def, const char *description){ char **cmdline_get_list(const char *key, const char *def, const char *description)
{
cmdline_usage_append(key, "list", description); cmdline_usage_append(key, "list", description);
const char *str = cmdline_get_value(key); const char *str = cmdline_get_value(key);

View File

@ -17,6 +17,7 @@ bool string_parse_icon_position(const char *s, enum icon_position *ret);
bool string_parse_vertical_alignment(const char *s, enum vertical_alignment *ret); bool string_parse_vertical_alignment(const char *s, enum vertical_alignment *ret);
bool string_parse_markup_mode(const char *s, enum markup_mode *ret); bool string_parse_markup_mode(const char *s, enum markup_mode *ret);
bool string_parse_mouse_action(const char *s, enum mouse_action *ret); bool string_parse_mouse_action(const char *s, enum mouse_action *ret);
bool string_parse_mouse_action_list(char **s, enum mouse_action **ret);
bool string_parse_sepcolor(const char *s, struct separator_color_data *ret); bool string_parse_sepcolor(const char *s, struct separator_color_data *ret);
bool string_parse_urgency(const char *s, enum urgency *ret); bool string_parse_urgency(const char *s, enum urgency *ret);

View File

@ -529,48 +529,42 @@ void load_settings(char *cmdline_config_path)
} }
{ {
char *c = option_get_string( char **c = option_get_list(
"global", "global",
"mouse_left_click", "-left_click", NULL, "mouse_left_click", "-mouse_left_click", NULL,
"Action of Left click event" "Action of Left click event"
); );
if (!string_parse_mouse_action(c, &settings.mouse_left_click)) { if (!string_parse_mouse_action_list(c, &settings.mouse_left_click)) {
if (c)
LOG_W("Unknown mouse action value: '%s'", c);
settings.mouse_left_click = defaults.mouse_left_click; settings.mouse_left_click = defaults.mouse_left_click;
} }
g_free(c); free_string_array(c);
} }
{ {
char *c = option_get_string( char **c = option_get_list(
"global", "global",
"mouse_middle_click", "-mouse_middle_click", NULL, "mouse_middle_click", "-mouse_middle_click", NULL,
"Action of middle click event" "Action of middle click event"
); );
if (!string_parse_mouse_action(c, &settings.mouse_middle_click)) { if (!string_parse_mouse_action_list(c, &settings.mouse_middle_click)) {
if (c)
LOG_W("Unknown mouse action value: '%s'", c);
settings.mouse_middle_click = defaults.mouse_middle_click; settings.mouse_middle_click = defaults.mouse_middle_click;
} }
g_free(c); free_string_array(c);
} }
{ {
char *c = option_get_string( char **c = option_get_list(
"global", "global",
"mouse_right_click", "-mouse_right_click", NULL, "mouse_right_click", "-mouse_right_click", NULL,
"Action of right click event" "Action of right click event"
); );
if (!string_parse_mouse_action(c, &settings.mouse_right_click)) { if (!string_parse_mouse_action_list(c, &settings.mouse_right_click)) {
if (c)
LOG_W("Unknown mouse action value: '%s'", c);
settings.mouse_right_click = defaults.mouse_right_click; settings.mouse_right_click = defaults.mouse_right_click;
} }
g_free(c); free_string_array(c);
} }
settings.colors_low.bg = option_get_string( settings.colors_low.bg = option_get_string(

View File

@ -88,9 +88,9 @@ struct settings {
struct keyboard_shortcut context_ks; struct keyboard_shortcut context_ks;
bool force_xinerama; bool force_xinerama;
int corner_radius; int corner_radius;
enum mouse_action mouse_left_click; enum mouse_action *mouse_left_click;
enum mouse_action mouse_middle_click; enum mouse_action *mouse_middle_click;
enum mouse_action mouse_right_click; enum mouse_action *mouse_right_click;
}; };
extern struct settings settings; extern struct settings settings;

View File

@ -400,26 +400,27 @@ bool x_is_idle(void)
*/ */
static void x_handle_click(XEvent ev) static void x_handle_click(XEvent ev)
{ {
enum mouse_action act; enum mouse_action *acts;
switch (ev.xbutton.button) { switch (ev.xbutton.button) {
case Button1: case Button1:
act = settings.mouse_left_click; acts = settings.mouse_left_click;
break; break;
case Button2: case Button2:
act = settings.mouse_middle_click; acts = settings.mouse_middle_click;
break; break;
case Button3: case Button3:
act = settings.mouse_right_click; acts = settings.mouse_right_click;
break; break;
default: default:
LOG_W("Unsupported mouse button: '%d'", ev.xbutton.button); LOG_W("Unsupported mouse button: '%d'", ev.xbutton.button);
return; return;
} }
for (int i = 0; acts[i]; i++) {
enum mouse_action act = acts[i];
if (act == MOUSE_CLOSE_ALL) { if (act == MOUSE_CLOSE_ALL) {
queues_history_push_all(); queues_history_push_all();
return; return;
} }
@ -446,6 +447,7 @@ static void x_handle_click(XEvent ev)
} }
} }
} }
}
void x_free(void) void x_free(void)
{ {