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
}, /* 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;
}
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)
{
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));
}
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);
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_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_list(char **s, enum mouse_action **ret);
bool string_parse_sepcolor(const char *s, struct separator_color_data *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",
"mouse_left_click", "-left_click", NULL,
"mouse_left_click", "-mouse_left_click", NULL,
"Action of Left click event"
);
if (!string_parse_mouse_action(c, &settings.mouse_left_click)) {
if (c)
LOG_W("Unknown mouse action value: '%s'", c);
if (!string_parse_mouse_action_list(c, &settings.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",
"mouse_middle_click", "-mouse_middle_click", NULL,
"Action of middle click event"
);
if (!string_parse_mouse_action(c, &settings.mouse_middle_click)) {
if (c)
LOG_W("Unknown mouse action value: '%s'", c);
if (!string_parse_mouse_action_list(c, &settings.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",
"mouse_right_click", "-mouse_right_click", NULL,
"Action of right click event"
);
if (!string_parse_mouse_action(c, &settings.mouse_right_click)) {
if (c)
LOG_W("Unknown mouse action value: '%s'", c);
if (!string_parse_mouse_action_list(c, &settings.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(

View File

@ -88,9 +88,9 @@ struct settings {
struct 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;
enum mouse_action *mouse_left_click;
enum mouse_action *mouse_middle_click;
enum mouse_action *mouse_right_click;
};
extern struct settings settings;

View File

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