From 847c2c873c06a3866981834d29eccef1041f5410 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Thu, 10 May 2018 15:24:28 +0200 Subject: #15 modes can now capture keypresses; code cleanup --- src/hotkey.c | 118 ++++++++++++++++++++++++++++----------------------------- src/hotkey.h | 4 +- src/parse.c | 7 ++++ src/skhd.c | 16 ++++---- src/tokenize.c | 1 + src/tokenize.h | 1 + 6 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/hotkey.c b/src/hotkey.c index af1e410..2de3a10 100644 --- a/src/hotkey.c +++ b/src/hotkey.c @@ -106,99 +106,99 @@ fork_and_exec(char *command) bool find_and_exec_hotkey(struct hotkey *eventkey, struct table *mode_map, struct mode **current_mode) { - bool result = false; struct hotkey *hotkey; if ((hotkey = table_find(&(*current_mode)->hotkey_map, eventkey))) { + bool capture = (*current_mode)->capture || !has_flags(hotkey, Hotkey_Flag_Passthrough); + char *command = hotkey->command; + if (has_flags(hotkey, Hotkey_Flag_Activate)) { *current_mode = table_find(mode_map, hotkey->command); - if ((*current_mode)->command) { - fork_and_exec((*current_mode)->command); - } - result = has_flags(hotkey, Hotkey_Flag_Passthrough) ? false : true; - } else if (fork_and_exec(hotkey->command)) { - result = has_flags(hotkey, Hotkey_Flag_Passthrough) ? false : true; + command = (*current_mode)->command; + if (!command) return capture; } + + if (fork_and_exec(command)) return capture; } - return result; + return false; } -internal void -free_hotkeys(struct table *hotkey_map, struct table *freed_pointers) +void free_mode_map(struct table *mode_map) { - int count; - void **hotkeys = table_reset(hotkey_map, &count); - - for (int index = 0; index < count; ++index) { - struct hotkey *hotkey = (struct hotkey *) hotkeys[index]; - if (table_find(freed_pointers, hotkey)) { - // we have already freed this pointer, do nothing! - // printf("info: %p has already been freed!\n", hotkey); - } else { - table_add(freed_pointers, hotkey, hotkey); + int mode_count; + void **modes = table_reset(mode_map, &mode_count); + if (!mode_count) return; + + struct hotkey **freed_pointers = NULL; + for (int mode_index = 0; mode_index < mode_count; ++mode_index) { + struct mode *mode = (struct mode *) modes[mode_index]; + int hk_count; + void **hotkeys = table_reset(&mode->hotkey_map, &hk_count); + + for (int hk_index = 0; hk_index < hk_count; ++hk_index) { + struct hotkey *hotkey = (struct hotkey *) hotkeys[hk_index]; + for (int i = 0; i < buf_len(freed_pointers); ++i) { + if (freed_pointers[i] == hotkey) { + continue; + } + } + buf_push(freed_pointers, hotkey); + buf_free(hotkey->mode_list); free(hotkey->command); free(hotkey); } - } - - if (count) { - free(hotkeys); - } -} -unsigned long hash_pointer(struct hotkey *a) { return (unsigned long)a; } -bool same_pointer(struct hotkey *a, struct hotkey *b) { return a == b; } - -void free_mode_map(struct table *mode_map) -{ - int count; - struct table freed_pointers; - void **modes = table_reset(mode_map, &count); - - if (count) { - table_init(&freed_pointers, 13, - (table_hash_func) hash_pointer, - (table_compare_func) same_pointer); - } - - for (int index = 0; index < count; ++index) { - struct mode *mode = (struct mode *) modes[index]; + if (hk_count) free(hotkeys); if (mode->command) free(mode->command); if (mode->name) free(mode->name); - free_hotkeys(&mode->hotkey_map, &freed_pointers); free(mode); } - if (count) { + if (mode_count) { free(modes); - table_free(&freed_pointers); + buf_free(freed_pointers); } } internal void -cgevent_lrmod_flag_to_hotkey_lrmod_flag(CGEventFlags flags, struct hotkey *eventkey, int mod) +cgevent_lrmod_flag_to_hotkey_lrmod_flag(CGEventFlags eventflags, uint32_t *flags, int mod) { enum osx_event_mask mask = cgevent_lrmod_flag[mod]; enum osx_event_mask lmask = cgevent_lrmod_flag[mod + LMOD_OFFS]; enum osx_event_mask rmask = cgevent_lrmod_flag[mod + RMOD_OFFS]; - if ((flags & mask) == mask) { - bool left = (flags & lmask) == lmask; - bool right = (flags & rmask) == rmask; + if ((eventflags & mask) == mask) { + bool left = (eventflags & lmask) == lmask; + bool right = (eventflags & rmask) == rmask; - if (left) add_flags(eventkey, hotkey_lrmod_flag[mod + LMOD_OFFS]); - if (right) add_flags(eventkey, hotkey_lrmod_flag[mod + RMOD_OFFS]); - if (!left && !right) add_flags(eventkey, hotkey_lrmod_flag[mod]); + if (left) *flags |= hotkey_lrmod_flag[mod + LMOD_OFFS]; + if (right) *flags |= hotkey_lrmod_flag[mod + RMOD_OFFS]; + if (!left && !right) *flags |= hotkey_lrmod_flag[mod]; } } -void cgeventflags_to_hotkeyflags(CGEventFlags flags, struct hotkey *eventkey) +internal uint32_t +cgevent_flags_to_hotkey_flags(uint32_t eventflags) { - cgevent_lrmod_flag_to_hotkey_lrmod_flag(flags, eventkey, LRMOD_ALT); - cgevent_lrmod_flag_to_hotkey_lrmod_flag(flags, eventkey, LRMOD_CMD); - cgevent_lrmod_flag_to_hotkey_lrmod_flag(flags, eventkey, LRMOD_CTRL); - cgevent_lrmod_flag_to_hotkey_lrmod_flag(flags, eventkey, LRMOD_SHIFT); + uint32_t flags = 0; + + cgevent_lrmod_flag_to_hotkey_lrmod_flag(eventflags, &flags, LRMOD_ALT); + cgevent_lrmod_flag_to_hotkey_lrmod_flag(eventflags, &flags, LRMOD_CMD); + cgevent_lrmod_flag_to_hotkey_lrmod_flag(eventflags, &flags, LRMOD_CTRL); + cgevent_lrmod_flag_to_hotkey_lrmod_flag(eventflags, &flags, LRMOD_SHIFT); if ((flags & Event_Mask_Fn) == Event_Mask_Fn) { - add_flags(eventkey, Hotkey_Flag_Fn); + flags |= Hotkey_Flag_Fn; } + + return flags; +} + +struct hotkey +create_eventkey(CGEventRef event) +{ + struct hotkey eventkey = { + .key = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode), + .flags = cgevent_flags_to_hotkey_flags(CGEventGetFlags(event)) + }; + return eventkey; } diff --git a/src/hotkey.h b/src/hotkey.h index 576dadf..82a936f 100644 --- a/src/hotkey.h +++ b/src/hotkey.h @@ -53,6 +53,7 @@ struct mode int cursor; char *name; char *command; + bool capture; struct table hotkey_map; }; @@ -89,9 +90,8 @@ unsigned long hash_mode(char *key); bool same_hotkey(struct hotkey *a, struct hotkey *b); unsigned long hash_hotkey(struct hotkey *a); +struct hotkey create_eventkey(CGEventRef event); bool find_and_exec_hotkey(struct hotkey *eventkey, struct table *mode_map, struct mode **current_mode); -void cgeventflags_to_hotkeyflags(CGEventFlags flags, struct hotkey *eventkey); - void free_mode_map(struct table *mode_map); #endif diff --git a/src/parse.c b/src/parse.c index d219d8c..7bde2dc 100644 --- a/src/parse.c +++ b/src/parse.c @@ -30,6 +30,7 @@ find_or_init_default_mode(struct parser *parser) (table_hash_func) hash_hotkey, (table_compare_func) same_hotkey); + default_mode->capture = false; default_mode->command = NULL; table_add(parser->mode_map, default_mode->name, default_mode); @@ -286,6 +287,12 @@ parse_mode_decl(struct parser *parser) (table_hash_func) hash_hotkey, (table_compare_func) same_hotkey); + if (parser_match(parser, Token_Capture)) { + mode->capture = true; + } else { + mode->capture = false; + } + if (parser_match(parser, Token_Command)) { mode->command = copy_string_count(parser->previous_token.text, parser->previous_token.length); } else { diff --git a/src/skhd.c b/src/skhd.c index 7ef1533..7250ba5 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -31,13 +31,16 @@ extern bool CGSIsSecureEventInputSet(); #define secure_keyboard_entry_enabled CGSIsSecureEventInputSet -#if 0 +#if 1 #define BEGIN_TIMED_BLOCK() \ clock_t timed_block_begin = clock() #define END_TIMED_BLOCK() \ clock_t timed_block_end = clock(); \ - double timed_block_elapsed = (timed_block_end -timed_block_begin) / (double)CLOCKS_PER_SEC; \ - printf("elapsed time: %f\n", timed_block_elapsed) + double timed_block_elapsed = ((timed_block_end - timed_block_begin) / (double)CLOCKS_PER_SEC) * 1000.0f; \ + printf("elapsed time: %.4fms\n", timed_block_elapsed) +#else +#define BEGIN_TIMED_BLOCK() +#define END_TIMED_BLOCK() #endif internal unsigned major_version = 0; @@ -98,11 +101,10 @@ internal EVENT_TAP_CALLBACK(key_handler) } break; case kCGEventKeyDown: { if (!current_mode) return event; - uint32_t flags = CGEventGetFlags(event); - uint32_t key = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); - struct hotkey eventkey = { .flags = 0, .key = key }; - cgeventflags_to_hotkeyflags(flags, &eventkey); + BEGIN_TIMED_BLOCK(); + struct hotkey eventkey = create_eventkey(event); bool result = find_and_exec_hotkey(&eventkey, &mode_map, ¤t_mode); + END_TIMED_BLOCK(); if (result) { return NULL; } diff --git a/src/tokenize.c b/src/tokenize.c index 82cd466..d9fd538 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -123,6 +123,7 @@ get_token(struct tokenizer *tokenizer) case '+': { token.type = Token_Plus; } break; case ',': { token.type = Token_Comma; } break; case '<': { token.type = Token_Insert; } break; + case '@': { token.type = Token_Capture; } break; case '#': { eat_comment(tokenizer); token = get_token(tokenizer); diff --git a/src/tokenize.h b/src/tokenize.h index 114ed0d..2d50e3b 100644 --- a/src/tokenize.h +++ b/src/tokenize.h @@ -43,6 +43,7 @@ enum token_type Token_Plus, Token_Dash, Token_Arrow, + Token_Capture, Token_Unknown, Token_EndOfStream, -- cgit v1.2.3