commit dde1b8195300c5fe9c258f0c41d712ecf0f8d300
parent cd2c0a4e31e3a5a58998684c39316f1f36589b37
Author: Bastien Dejean <nihilhill@gmail.com>
Date: Sat, 5 Jan 2013 18:54:13 +0100
General sequences for keysym and commands
Diffstat:
4 files changed, 43 insertions(+), 30 deletions(-)
diff --git a/README.md b/README.md
@@ -34,7 +34,7 @@ The keysym names are those your will get from `xev` (minus the prefix if any).
Mouse hotkeys can be defined by using one of the following special keysym names: `button1`, `button2`, `button3`, ..., `button24`.
-`KEYSYM` can also be a sequence of the form `{KEYSYM_1,KEYSYM_2,...,KEYSYM_N}`, in which case, `COMMAND` must also contain a sequence with *N* elements: the pairing of the two sequences generates *N* hotkeys.
+`KEYSYM` can contain a sequence of the form `{STRING_1,STRING_2,...,STRING_N}`, in which case, `COMMAND` must also contain a sequence with *N* elements: the pairing of the two sequences generates *N* hotkeys.
What is actually executed is `/bin/sh -c COMMAND`, which means you can use environment variables in `COMMAND`.
diff --git a/keys.c b/keys.c
@@ -2518,11 +2518,11 @@ bool parse_modifier(char *name, uint16_t *modfield)
return false;
}
-bool parse_sequence(char *name, char *seq)
+bool parse_fold(char *name, char *folded_keysym)
{
- if (name[0] == SEQ_BEGIN && name[strlen(name) - 1] == SEQ_END) {
- strncpy(seq, name + 1, strlen(name) - 2);
- seq[strlen(name) - 2] = '\0';
+ if (strchr(name, SEQ_BEGIN) != NULL && strrchr(name, SEQ_END) != NULL) {
+ strncpy(folded_keysym, name, strlen(name));
+ folded_keysym[strlen(name)] = '\0';
return true;
}
return false;
@@ -2545,30 +2545,43 @@ void get_lock_fields(void)
PRINTF("lock fields %u %u %u\n", num_lock, caps_lock, scroll_lock);
}
-void unfold_hotkeys(char *keysym_seq, uint16_t modfield, xcb_event_mask_t event_mask, char *command)
+bool extract_sequence(char *string, char *prefix, char *sequence, char *suffix)
{
- char *begin = strchr(command, SEQ_BEGIN);
- char *end = strrchr(command, SEQ_END);
- if (begin == NULL || end == NULL || ((end - begin - 1) < SEQ_MIN_LEN)) {
- warn("Invalid sequence for command '%s'.\n", command);
- return;
- }
- char *ks_ptr, *cmd_ptr;
- char unfolded_command[MAXLEN];
- char command_seq[MAXLEN];
+ char *begin = strchr(string, SEQ_BEGIN);
+ char *end = strrchr(string, SEQ_END);
+ if (begin == NULL || end == NULL || ((end - begin - 1) < SEQ_MIN_LEN))
+ return false;
+ strncpy(sequence, begin + 1, end - begin - 1);
+ strncpy(prefix, string, begin - string);
+ strncpy(suffix, end + 1, strlen(string) - (1 + end - string));
+ sequence[end - begin - 1] = '\0';
+ prefix[begin - string] = '\0';
+ suffix[strlen(string) - (1 + end - string)] = '\0';
+ return true;
+}
+
+void unfold_hotkeys(char *folded_keysym, uint16_t modfield, xcb_event_mask_t event_mask, char *folded_command)
+{
+ char keysym_sequence[MAXLEN];
+ char keysym_prefix[MAXLEN];
+ char keysym_suffix[MAXLEN];
+ char command_sequence[MAXLEN];
char command_prefix[MAXLEN];
char command_suffix[MAXLEN];
- strncpy(command_seq, begin + 1, end - begin - 1);
- strncpy(command_prefix, command, begin - command);
- strncpy(command_suffix, end + 1, strlen(command) - (1 + end - command));
- command_seq[end - begin - 1] = '\0';
- command_prefix[begin - command] = '\0';
- command_suffix[strlen(command) - (1 + end - command)] = '\0';
+ if (!extract_sequence(folded_keysym, keysym_prefix, keysym_sequence, keysym_suffix) || !extract_sequence(folded_command, command_prefix, command_sequence, command_suffix)) {
+ warn("Couldn't extract sequence from '%s' or '%s'.\n", folded_keysym, folded_command);
+ return;
+ }
+ char unfolded_keysym[MAXLEN], unfolded_command[MAXLEN];
xcb_keysym_t keysym = XCB_NO_SYMBOL;
xcb_button_t button = XCB_NONE;
- for (char *ks_item = strtok_r(keysym_seq, SEQ_SEP, &ks_ptr), *cmd_item = strtok_r(command_seq, SEQ_SEP, &cmd_ptr); ks_item != NULL && cmd_item != NULL; ks_item = strtok_r(NULL, SEQ_SEP, &ks_ptr), cmd_item = strtok_r(NULL, SEQ_SEP, &cmd_ptr)) {
+ char *ks_ptr, *cmd_ptr;
+ /* char ks_range_a = 0, ks_range_b = 0, cmd_range_a = 0, cmd_range_b = 0; */
+
+ for (char *ks_item = strtok_r(keysym_sequence, SEQ_SEP, &ks_ptr), *cmd_item = strtok_r(command_sequence, SEQ_SEP, &cmd_ptr); ks_item != NULL && cmd_item != NULL; ks_item = strtok_r(NULL, SEQ_SEP, &ks_ptr), cmd_item = strtok_r(NULL, SEQ_SEP, &cmd_ptr)) {
snprintf(unfolded_command, sizeof(unfolded_command), "%s%s%s", command_prefix, cmd_item, command_suffix);
- if (parse_key(ks_item, &keysym) || parse_button(ks_item, &button))
+ snprintf(unfolded_keysym, sizeof(unfolded_keysym), "%s%s%s", keysym_prefix, ks_item, keysym_suffix);
+ if (parse_key(unfolded_keysym, &keysym) || parse_button(unfolded_keysym, &button))
generate_hotkeys(keysym, button, modfield, event_mask, unfolded_command);
else
warn("Unknown sequence keysym: '%s'.\n", ks_item);
diff --git a/keys.h b/keys.h
@@ -23,7 +23,7 @@ xcb_keycode_t *keycodes_from_keysym(xcb_keysym_t);
bool parse_key(char *, xcb_keysym_t *);
bool parse_button(char *, xcb_button_t *);
bool parse_modifier(char *, uint16_t *);
-bool parse_sequence(char *, char *);
+bool parse_fold(char *, char *);
xcb_event_mask_t key_to_mouse(xcb_event_mask_t);
void get_lock_fields(void);
void unfold_hotkeys(char *, uint16_t, xcb_event_mask_t, char *);
diff --git a/sxhkd.c b/sxhkd.c
@@ -73,13 +73,13 @@ void load_config(void)
xcb_button_t button = XCB_NONE;
uint16_t modfield = 0;
xcb_event_mask_t event_mask = XCB_KEY_PRESS;
- char keysym_seq[MAXLEN] = {'\0'};
+ char folded_keysym[MAXLEN] = {'\0'};
while (fgets(line, sizeof(line), cfg) != NULL) {
if (strlen(line) < 2 || line[0] == START_COMMENT) {
continue;
} else if (isspace(line[0])) {
- if (keysym == XCB_NO_SYMBOL && button == XCB_NONE && strlen(keysym_seq) == 0)
+ if (keysym == XCB_NO_SYMBOL && button == XCB_NONE && strlen(folded_keysym) == 0)
continue;
unsigned int i = strlen(line) - 1;
while (i > 0 && isspace(line[i]))
@@ -89,16 +89,16 @@ void load_config(void)
i++;
if (i < strlen(line)) {
char *command = line + i;
- if (strlen(keysym_seq) == 0)
+ if (strlen(folded_keysym) == 0)
generate_hotkeys(keysym, button, modfield, event_mask, command);
else
- unfold_hotkeys(keysym_seq, modfield, event_mask, command);
+ unfold_hotkeys(folded_keysym, modfield, event_mask, command);
}
keysym = XCB_NO_SYMBOL;
button = XCB_NONE;
modfield = 0;
event_mask = XCB_KEY_PRESS;
- keysym_seq[0] = '\0';
+ folded_keysym[0] = '\0';
} else {
char *name = strtok(line, TOK_SEP);
if (name == NULL)
@@ -108,7 +108,7 @@ void load_config(void)
event_mask = XCB_KEY_RELEASE;
name++;
}
- if (!parse_modifier(name, &modfield) && !parse_key(name, &keysym) && !parse_button(name, &button) && !parse_sequence(name, keysym_seq)) {
+ if (!parse_modifier(name, &modfield) && !parse_key(name, &keysym) && !parse_button(name, &button) && !parse_fold(name, folded_keysym)) {
warn("Unrecognized key name: '%s'.\n", name);
}
} while ((name = strtok(NULL, TOK_SEP)) != NULL);