From a6546422134855457efc0fc020f3d17f5369d709 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Tue, 10 Jul 2018 14:45:26 +0200 Subject: #43 passthrough should correctly bypass mode keypress capture setting --- src/hotkey.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---------------- src/hotkey.h | 2 ++ src/skhd.c | 6 +++++- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/hotkey.c b/src/hotkey.c index 0677ae9..75a3647 100644 --- a/src/hotkey.c +++ b/src/hotkey.c @@ -3,6 +3,10 @@ #define internal static #define local_persist static +#define HOTKEY_FOUND ((1) << 0) +#define MODE_CAPTURE(a) ((a) << 1) +#define HOTKEY_PASSTHROUGH(a) ((a) << 2) + #define LRMOD_ALT 0 #define LRMOD_CMD 6 #define LRMOD_CTRL 9 @@ -10,6 +14,9 @@ #define LMOD_OFFS 1 #define RMOD_OFFS 2 +internal char arg[] = "-c"; +internal char *shell = NULL; + internal uint32_t cgevent_lrmod_flag[] = { Event_Mask_Alt, Event_Mask_LAlt, Event_Mask_RAlt, @@ -90,16 +97,9 @@ unsigned long hash_mode(char *key) return hash; } -internal void +internal inline void fork_and_exec(char *command) { - local_persist char arg[] = "-c"; - local_persist char *shell = NULL; - if (!shell) { - char *env_shell = getenv("SHELL"); - shell = env_shell ? env_shell : "/bin/bash"; - } - int cpid = fork(); if (cpid == 0) { setsid(); @@ -109,22 +109,44 @@ fork_and_exec(char *command) } } -internal inline bool -passthrough(struct hotkey *hotkey) +internal inline void +passthrough(struct hotkey *hotkey, uint32_t *capture) { - return !has_flags(hotkey, Hotkey_Flag_Passthrough); + *capture |= HOTKEY_PASSTHROUGH((int)has_flags(hotkey, Hotkey_Flag_Passthrough)); } internal inline struct hotkey * -find_hotkey(struct mode *mode, struct hotkey *hotkey) +find_hotkey(struct mode *mode, struct hotkey *hotkey, uint32_t *capture) { - return table_find(&mode->hotkey_map, hotkey); + struct hotkey *result = table_find(&mode->hotkey_map, hotkey); + if (result) *capture |= HOTKEY_FOUND; + return result; +} + +internal inline bool +should_capture_hotkey(uint32_t capture) +{ + if ((capture & HOTKEY_FOUND)) { + if (!(capture & MODE_CAPTURE(1)) && + !(capture & HOTKEY_PASSTHROUGH(1))) { + return true; + } + + if (!(capture & HOTKEY_PASSTHROUGH(1)) && + (capture & MODE_CAPTURE(1))) { + return true; + } + + return false; + } + + return (capture & MODE_CAPTURE(1)); } bool find_and_exec_hotkey(struct hotkey *k, struct table *t, struct mode **m) { - bool c = (*m)->capture; - for (struct hotkey *h = find_hotkey(*m, k); h; c |= passthrough(h), h = 0) { + uint32_t c = MODE_CAPTURE((int)(*m)->capture); + for (struct hotkey *h = find_hotkey(*m, k, &c); h; passthrough(h, &c), h = 0) { char *cmd = h->command; if (has_flags(h, Hotkey_Flag_Activate)) { *m = table_find(t, cmd); @@ -132,7 +154,7 @@ bool find_and_exec_hotkey(struct hotkey *k, struct table *t, struct mode **m) } if (cmd) fork_and_exec(cmd); } - return c; + return should_capture_hotkey(c); } void free_mode_map(struct table *mode_map) @@ -236,3 +258,11 @@ bool intercept_systemkey(CGEventRef event, struct hotkey *eventkey) return result; } + +void init_shell() +{ + if (!shell) { + char *env_shell = getenv("SHELL"); + shell = env_shell ? env_shell : "/bin/bash"; + } +} diff --git a/src/hotkey.h b/src/hotkey.h index 59ee243..c2caed5 100644 --- a/src/hotkey.h +++ b/src/hotkey.h @@ -97,4 +97,6 @@ bool intercept_systemkey(CGEventRef event, struct hotkey *eventkey); bool find_and_exec_hotkey(struct hotkey *eventkey, struct table *mode_map, struct mode **current_mode); void free_mode_map(struct table *mode_map); +void init_shell(); + #endif diff --git a/src/skhd.c b/src/skhd.c index d987594..34d4377 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -29,7 +29,7 @@ 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() \ @@ -99,8 +99,11 @@ internal EVENT_TAP_CALLBACK(key_handler) case kCGEventKeyDown: { if (!current_mode) return event; + 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; } break; case NX_SYSDEFINED: { @@ -205,6 +208,7 @@ int main(int argc, char **argv) table_init(&mode_map, 13, (table_hash_func) hash_mode, (table_compare_func) same_mode); parse_config_helper(config_file); signal(SIGCHLD, SIG_IGN); + init_shell(); struct event_tap event_tap; event_tap.mask = (1 << kCGEventKeyDown) | (1 << NX_SYSDEFINED); -- cgit v1.2.3