Skip to content

Commit

Permalink
General sequences for keysym and commands
Browse files Browse the repository at this point in the history
  • Loading branch information
baskerville committed Jan 5, 2013
1 parent cd2c0a4 commit dde1b81
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
57 changes: 35 additions & 22 deletions keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
12 changes: 6 additions & 6 deletions sxhkd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]))
Expand All @@ -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)
Expand All @@ -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);
Expand Down

0 comments on commit dde1b81

Please sign in to comment.