From 8b0eb94b4331434a8ccd7d367bc8eb5c9ac64aaa Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 26 May 2018 13:30:39 +0200 Subject: update sample --- examples/skhdrc | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'examples/skhdrc') diff --git a/examples/skhdrc b/examples/skhdrc index 2b0e6d8..94c40ca 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -111,6 +111,17 @@ shift + alt - left : chunkc tiling::window --grid-layout 1:2:0:0:1:1 # make floating window fill right-half of screen shift + alt - right : chunkc tiling::window --grid-layout 1:2:1:0:1:1 +# fast focus desktop +cmd + alt - z : chunkc tiling::desktop --focus prev +cmd + alt - c : chunkc tiling::desktop --focus next +cmd + alt - 1 : chunkc tiling::desktop --focus 1 +cmd + alt - 2 : chunkc tiling::desktop --focus 2 +cmd + alt - 3 : chunkc tiling::desktop --focus 3 +cmd + alt - 4 : chunkc tiling::desktop --focus 4 +cmd + alt - 5 : chunkc tiling::desktop --focus 5 +cmd + alt - 6 : chunkc tiling::desktop --focus 6 +cmd + alt - 7 : chunkc tiling::desktop --focus 7 + # send window to desktop shift + alt - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop) shift + alt - z : chunkc tiling::window --send-to-desktop prev @@ -121,17 +132,19 @@ shift + alt - 3 : chunkc tiling::window --send-to-desktop 3 shift + alt - 4 : chunkc tiling::window --send-to-desktop 4 shift + alt - 5 : chunkc tiling::window --send-to-desktop 5 shift + alt - 6 : chunkc tiling::window --send-to-desktop 6 +shift + alt - 7 : chunkc tiling::window --send-to-desktop 7 # send window to desktop and follow focus -shift + cmd - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop); qes -k "cmd + alt - $(chunkc get _last_active_desktop)" -shift + cmd - z : chunkc tiling::window --send-to-desktop prev; qes -k "cmd + alt - z" -shift + cmd - c : chunkc tiling::window --send-to-desktop next; qes -k "cmd + alt - c" -shift + cmd - 1 : chunkc tiling::window --send-to-desktop 1; qes -k "cmd + alt - 1" -shift + cmd - 2 : chunkc tiling::window --send-to-desktop 2; qes -k "cmd + alt - 2" -shift + cmd - 3 : chunkc tiling::window --send-to-desktop 3; qes -k "cmd + alt - 3" -shift + cmd - 4 : chunkc tiling::window --send-to-desktop 4; qes -k "cmd + alt - 4" -shift + cmd - 5 : chunkc tiling::window --send-to-desktop 5; qes -k "cmd + alt - 5" -shift + cmd - 6 : chunkc tiling::window --send-to-desktop 6; qes -k "cmd + alt - 6" +shift + cmd - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop); chunkc tiling::desktop --focus $(chunkc get _last_active_desktop) +shift + cmd - z : chunkc tiling::window --send-to-desktop prev; chunkc tiling::desktop --focus prev +shift + cmd - c : chunkc tiling::window --send-to-desktop next; chunkc tiling::desktop --focus next +shift + cmd - 1 : chunkc tiling::window --send-to-desktop 1; chunkc tiling::desktop --focus 1 +shift + cmd - 2 : chunkc tiling::window --send-to-desktop 2; chunkc tiling::desktop --focus 2 +shift + cmd - 3 : chunkc tiling::window --send-to-desktop 3; chunkc tiling::desktop --focus 3 +shift + cmd - 4 : chunkc tiling::window --send-to-desktop 4; chunkc tiling::desktop --focus 4 +shift + cmd - 5 : chunkc tiling::window --send-to-desktop 5; chunkc tiling::desktop --focus 5 +shift + cmd - 6 : chunkc tiling::window --send-to-desktop 6; chunkc tiling::desktop --focus 6 +shift + cmd - 7 : chunkc tiling::window --send-to-desktop 7; chunkc tiling::desktop --focus 7 # focus monitor ctrl + alt - z : chunkc tiling::monitor -f prev @@ -210,7 +223,3 @@ ctrl + alt - s : chunkc tiling::desktop --layout monocle ctrl + alt - d : chunkc tiling::desktop --layout float ctrl + alt - w : chunkc tiling::desktop --deserialize ~/.chunkwm_layouts/dev_1 - -cmd - 7 : qes -k "shift + alt - 7" -cmd - 8 : qes -k "shift + alt - 8" -cmd - 9 : qes -k "shift + alt - 9" -- cgit v1.2.3 From d110e8451c00005aa90fb3da617309d9bcf06b94 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 26 May 2018 13:48:57 +0200 Subject: update sample binds --- examples/skhdrc | 1 + 1 file changed, 1 insertion(+) (limited to 'examples/skhdrc') diff --git a/examples/skhdrc b/examples/skhdrc index 94c40ca..81b2c8c 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -112,6 +112,7 @@ shift + alt - left : chunkc tiling::window --grid-layout 1:2:0:0:1:1 shift + alt - right : chunkc tiling::window --grid-layout 1:2:1:0:1:1 # fast focus desktop +cmd + alt - x : chunkc tiling::desktop --focus $(chunkc get _last_active_desktop) cmd + alt - z : chunkc tiling::desktop --focus prev cmd + alt - c : chunkc tiling::desktop --focus next cmd + alt - 1 : chunkc tiling::desktop --focus 1 -- cgit v1.2.3 From 7892d89487e410a450de198a7bbdfa535321fdc6 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 27 May 2018 21:57:28 +0200 Subject: fix annoying issue; setsid --- examples/skhdrc | 8 ++++---- src/hotkey.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'examples/skhdrc') diff --git a/examples/skhdrc b/examples/skhdrc index 81b2c8c..c531b6f 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -70,7 +70,7 @@ # default, test < cmd - return : open -na /Applications/Terminal.app # open terminal, blazingly fast compared to iTerm/Hyper -cmd - return : open -na /Applications/Kitty.app +cmd - return : /Applications/Kitty.app/Contents/MacOS/kitty --single-instance # open qutebrowser cmd + shift - return : ~/Scripts/qtb.sh @@ -121,7 +121,7 @@ cmd + alt - 3 : chunkc tiling::desktop --focus 3 cmd + alt - 4 : chunkc tiling::desktop --focus 4 cmd + alt - 5 : chunkc tiling::desktop --focus 5 cmd + alt - 6 : chunkc tiling::desktop --focus 6 -cmd + alt - 7 : chunkc tiling::desktop --focus 7 +# cmd + alt - 7 : chunkc tiling::desktop --focus 7 # send window to desktop shift + alt - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop) @@ -133,7 +133,7 @@ shift + alt - 3 : chunkc tiling::window --send-to-desktop 3 shift + alt - 4 : chunkc tiling::window --send-to-desktop 4 shift + alt - 5 : chunkc tiling::window --send-to-desktop 5 shift + alt - 6 : chunkc tiling::window --send-to-desktop 6 -shift + alt - 7 : chunkc tiling::window --send-to-desktop 7 +# shift + alt - 7 : chunkc tiling::window --send-to-desktop 7 # send window to desktop and follow focus shift + cmd - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop); chunkc tiling::desktop --focus $(chunkc get _last_active_desktop) @@ -145,7 +145,7 @@ shift + cmd - 3 : chunkc tiling::window --send-to-desktop 3; chunkc tiling::desk shift + cmd - 4 : chunkc tiling::window --send-to-desktop 4; chunkc tiling::desktop --focus 4 shift + cmd - 5 : chunkc tiling::window --send-to-desktop 5; chunkc tiling::desktop --focus 5 shift + cmd - 6 : chunkc tiling::window --send-to-desktop 6; chunkc tiling::desktop --focus 6 -shift + cmd - 7 : chunkc tiling::window --send-to-desktop 7; chunkc tiling::desktop --focus 7 +# shift + cmd - 7 : chunkc tiling::window --send-to-desktop 7; chunkc tiling::desktop --focus 7 # focus monitor ctrl + alt - z : chunkc tiling::monitor -f prev diff --git a/src/hotkey.c b/src/hotkey.c index a37e27c..0677ae9 100644 --- a/src/hotkey.c +++ b/src/hotkey.c @@ -102,6 +102,7 @@ fork_and_exec(char *command) int cpid = fork(); if (cpid == 0) { + setsid(); char *exec[] = { shell, arg, command, NULL}; int status_code = execvp(exec[0], exec); exit(status_code); -- cgit v1.2.3 From 54b7f52ec0bd932e66c7f31de0899c79ea463124 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 27 May 2018 22:45:18 +0200 Subject: fix terminal launch bind --- examples/skhdrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/skhdrc') diff --git a/examples/skhdrc b/examples/skhdrc index c531b6f..83b4ef0 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -70,7 +70,7 @@ # default, test < cmd - return : open -na /Applications/Terminal.app # open terminal, blazingly fast compared to iTerm/Hyper -cmd - return : /Applications/Kitty.app/Contents/MacOS/kitty --single-instance +cmd - return : /Applications/Kitty.app/Contents/MacOS/kitty --single-instance -d ~ # open qutebrowser cmd + shift - return : ~/Scripts/qtb.sh -- cgit v1.2.3 From 2804aa714970975632ffaab9eb9a58a6f1ecaeae Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Tue, 10 Jul 2018 14:43:13 +0200 Subject: update sample --- examples/skhdrc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'examples/skhdrc') diff --git a/examples/skhdrc b/examples/skhdrc index 83b4ef0..c7658c2 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -75,6 +75,9 @@ cmd - return : /Applications/Kitty.app/Contents/MacOS/kitty --single-instance -d # open qutebrowser cmd + shift - return : ~/Scripts/qtb.sh +# open mpv +cmd - m : open -na /Applications/mpv.app $(pbpaste) + # close focused window alt - w : chunkc tiling::window --close @@ -111,6 +114,19 @@ shift + alt - left : chunkc tiling::window --grid-layout 1:2:0:0:1:1 # make floating window fill right-half of screen shift + alt - right : chunkc tiling::window --grid-layout 1:2:1:0:1:1 +# create desktop, move window and follow focus +shift + cmd - n : chunkc tiling::desktop --create;\ + id=$(chunkc tiling::query --desktops-for-monitor $(chunkc tiling::query --monitor-for-desktop $(chunkc tiling::query --desktop id)));\ + chunkc tiling::window --send-to-desktop $(echo ${id##* });\ + chunkc tiling::desktop --focus $(echo ${id##* }) + +# create desktop and follow focus +cmd + alt - n : chunkc tiling::desktop --create;\ + id=$(chunkc tiling::query --desktops-for-monitor $(chunkc tiling::query --monitor-for-desktop $(chunkc tiling::query --desktop id)));\ + chunkc tiling::desktop --focus $(echo ${id##* }) +# destroy desktop +cmd + alt - w : chunkc tiling::desktop --annihilate + # fast focus desktop cmd + alt - x : chunkc tiling::desktop --focus $(chunkc get _last_active_desktop) cmd + alt - z : chunkc tiling::desktop --focus prev @@ -211,8 +227,11 @@ alt - q : chunkc tiling::window --toggle fade alt - t : chunkc tiling::window --toggle float;\ chunkc tiling::window --grid-layout 4:4:1:1:2:2 +# toggle sticky +alt - s : chunkc tiling::window --toggle sticky + # toggle sticky, float and resize to picture-in-picture size -alt - s : chunkc tiling::window --toggle sticky;\ +alt - p : chunkc tiling::window --toggle sticky;\ chunkc tiling::window --grid-layout 5:5:4:0:1:1 # float next window to be tiled -- cgit v1.2.3 From 8c1a567dc93697f60b33cc60066a234df7e0e1ca Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Thu, 30 Aug 2018 17:27:55 +0200 Subject: update readme and sample config --- README.md | 45 ++++++++++++++++++++++----------------- examples/skhdrc | 66 ++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 66 insertions(+), 45 deletions(-) (limited to 'examples/skhdrc') diff --git a/README.md b/README.md index 4d3197a..b645b3b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ feature comparison between **skhd** and **khd** | hotkey passthrough | [x] | [x] | | modal hotkey-system | [x] | [x] | | use media-keys as hotkey | [x] | [ ] | -| application specific hotkey| [ ] | [x] | +| application specific hotkey| [x] | [x] | | modifier only hotkey | [ ] | [x] | | caps-lock as hotkey | [ ] | [x] | | mouse-buttons as hotkey | [ ] | [x] | @@ -72,35 +72,42 @@ A list of all built-in modifier and literal keywords can be found [here](https:/ A hotkey is written according to the following rules: ``` -hotkey = '<' | +hotkey = '<' | -mode = 'name of mode' | ',' +mode = 'name of mode' | ',' -action = ':' | '->' ':' - ';' | '->' ';' +action = '[' ']' | '->' '[' ']' + ':' | '->' ':' + ';' | '->' ';' -keysym = '-' | +keysym = '-' | -mod = 'modifier keyword' | '+' +mod = 'modifier keyword' | '+' -key = | +key = | -literal = 'single letter or built-in keyword' +literal = 'single letter or built-in keyword' -keycode = 'apple keyboard kVK_ values (0x3C)' +keycode = 'apple keyboard kVK_ values (0x3C)' --> = keypress is not consumed by skhd +proc_map_lst = * -command = command is executed through '$SHELL -c' and - follows valid shell syntax. if the $SHELL environment - variable is not set, it will default to '/bin/bash'. - when bash is used, the ';' delimeter can be specified - to chain commands. +proc_map = ':' - to allow a command to extend into multiple lines, - prepend '\' at the end of the previous line. +string = '"' 'sequence of characters' '"' - an EOL character signifies the end of the bind. +command = command is executed through '$SHELL -c' and + follows valid shell syntax. if the $SHELL environment + variable is not set, it will default to '/bin/bash'. + when bash is used, the ';' delimeter can be specified + to chain commands. + + to allow a command to extend into multiple lines, + prepend '\' at the end of the previous line. + + an EOL character signifies the end of the bind. + +-> = keypress is not consumed by skhd ``` A mode is declared according to the following rules: diff --git a/examples/skhdrc b/examples/skhdrc index c7658c2..5336e71 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -3,36 +3,42 @@ # # A hotkey is written according to the following rules: # -# hotkey = '<' | +# hotkey = '<' | # -# mode = 'name of mode' | ',' +# mode = 'name of mode' | ',' # -# action = ':' | '->' ':' -# ';' | '->' ';' +# action = '[' ']' | '->' '[' ']' +# ':' | '->' ':' +# ';' | '->' ';' # -# keysym = '-' | +# keysym = '-' | # -# mod = 'built-in mod keyword' | '+' +# mod = 'modifier keyword' | '+' # -# key = | +# key = | # -# literal = 'single letter or built-in keyword' +# literal = 'single letter or built-in keyword' # -# keycode = 'apple keyboard kVK_ values (0x3C)' +# keycode = 'apple keyboard kVK_ values (0x3C)' # -# -> = keypress is not consumed by skhd +# proc_map_lst = * # -# command = command is executed through '$SHELL -c' and -# follows valid shell syntax. if the $SHELL environment -# variable is not set, it will default to '/bin/bash'. -# when bash is used, the ';' delimeter can be specified -# to chain commands. +# proc_map = ':' # -# to allow a command to extend into multiple lines, -# prepend '\' at the end of the previous line. +# string = '"' 'sequence of characters' '"' # -# an EOL character signifies the end of the bind. +# command = command is executed through '$SHELL -c' and +# follows valid shell syntax. if the $SHELL environment +# variable is not set, it will default to '/bin/bash'. +# when bash is used, the ';' delimeter can be specified +# to chain commands. # +# to allow a command to extend into multiple lines, +# prepend '\' at the end of the previous line. +# +# an EOL character signifies the end of the bind. +# +# -> = keypress is not consumed by skhd # # NOTE(koekeishiya): A mode is declared according to the following rules: # @@ -43,16 +49,16 @@ # # @ = capture keypresses regardless of being bound to an action # -# command = command is executed through '$SHELL -c' and -# follows valid shell syntax. if the $SHELL environment -# variable is not set, it will default to '/bin/bash'. -# when bash is used, the ';' delimeter can be specified -# to chain commands. +# command = command is executed through '$SHELL -c' and +# follows valid shell syntax. if the $SHELL environment +# variable is not set, it will default to '/bin/bash'. +# when bash is used, the ';' delimeter can be specified +# to chain commands. # -# to allow a command to extend into multiple lines, -# prepend '\' at the end of the previous line. +# to allow a command to extend into multiple lines, +# prepend '\' at the end of the previous line. # -# an EOL character signifies the end of the bind. +# an EOL character signifies the end of the bind. # add an on_enter command to the default mode # :: default : chunkc border::color 0xff775759 @@ -69,6 +75,14 @@ # launch a new terminal instance when in either 'default' or 'test' mode # default, test < cmd - return : open -na /Applications/Terminal.app +# application specific bindings +# +# cmd - n [ +# "kitty" : echo "hello kitty" +# "qutebrowser" : echo "hello qutebrowser" +# "finder" : false +# ] + # open terminal, blazingly fast compared to iTerm/Hyper cmd - return : /Applications/Kitty.app/Contents/MacOS/kitty --single-instance -d ~ -- cgit v1.2.3 From 5287a3192799d8f9bbdca01fa457cd6cb3e7eba5 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 23 Feb 2019 17:18:49 +0100 Subject: #62 implement option to unbind certain applications etc. --- README.md | 7 ++++++- examples/skhdrc | 6 +++++- src/hotkey.c | 13 ++++++++++--- src/hotkey.h | 1 + src/parse.c | 18 +++++++++++++++++- src/tokenize.c | 2 ++ src/tokenize.h | 2 ++ 7 files changed, 43 insertions(+), 6 deletions(-) (limited to 'examples/skhdrc') diff --git a/README.md b/README.md index b645b3b..a4ddf41 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,8 @@ keycode = 'apple keyboard kVK_ values (0x3C)' proc_map_lst = * -proc_map = ':' +proc_map = ':' | ':' '~' | + '*' ':' | '*' '~' string = '"' 'sequence of characters' '"' @@ -108,6 +109,10 @@ command = command is executed through '$SHELL -c' and an EOL character signifies the end of the bind. -> = keypress is not consumed by skhd + +* = matches every application not specified in + +~ = application is unbound and keypress is forwarded per usual, when specified in a ``` A mode is declared according to the following rules: diff --git a/examples/skhdrc b/examples/skhdrc index 5336e71..e68433c 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -23,7 +23,8 @@ # # proc_map_lst = * # -# proc_map = ':' +# proc_map = ':' | ':' '~' | +# '*' ':' | '*' '~' # # string = '"' 'sequence of characters' '"' # @@ -79,7 +80,9 @@ # # cmd - n [ # "kitty" : echo "hello kitty" +# * : echo "hello everyone" # "qutebrowser" : echo "hello qutebrowser" +# "terminal" ~ # "finder" : false # ] @@ -257,3 +260,4 @@ ctrl + alt - s : chunkc tiling::desktop --layout monocle ctrl + alt - d : chunkc tiling::desktop --layout float ctrl + alt - w : chunkc tiling::desktop --deserialize ~/.chunkwm_layouts/dev_1 + diff --git a/src/hotkey.c b/src/hotkey.c index 0c8b9f0..2f0df3a 100644 --- a/src/hotkey.c +++ b/src/hotkey.c @@ -145,14 +145,21 @@ should_capture_hotkey(uint32_t capture) internal inline char * find_process_command_mapping(struct hotkey *hotkey, uint32_t *capture, struct carbon_event *carbon) { + char *result = NULL; + bool found = false; + for (int i = 0; i < buf_len(hotkey->process_name); ++i) { if (same_string(carbon->process_name, hotkey->process_name[i])) { - return hotkey->command[i]; + result = hotkey->command[i]; + found = true; + break; } } - *capture &= ~HOTKEY_FOUND; - return NULL; + if (!found) result = hotkey->wildcard_command; + if (!result) *capture &= ~HOTKEY_FOUND; + + return result; } bool find_and_exec_hotkey(struct hotkey *k, struct table *t, struct mode **m, struct carbon_event *carbon) diff --git a/src/hotkey.h b/src/hotkey.h index 71d2e1d..641875d 100644 --- a/src/hotkey.h +++ b/src/hotkey.h @@ -73,6 +73,7 @@ struct hotkey uint32_t key; char **process_name; char **command; + char *wildcard_command; struct mode **mode_list; }; diff --git a/src/parse.c b/src/parse.c index a5760b7..760485d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -92,8 +92,24 @@ parse_process_command_list(struct parser *parser, struct hotkey *hotkey) if (parser_match(parser, Token_Command)) { parse_command(parser, hotkey); parse_process_command_list(parser, hotkey); + } else if (parser_match(parser, Token_Unbound)) { + buf_push(hotkey->command, NULL); + parse_process_command_list(parser, hotkey); + } else { + parser_report_error(parser, parser_peek(parser), "expected '~' or ':' followed by command\n"); + } + } else if (parser_match(parser, Token_Wildcard)) { + if (parser_match(parser, Token_Command)) { + struct token command = parser_previous(parser); + char *result = copy_string_count(command.text, command.length); + debug("\tcmd: '%s'\n", result); + hotkey->wildcard_command = result; + parse_process_command_list(parser, hotkey); + } else if (parser_match(parser, Token_Unbound)) { + hotkey->wildcard_command = NULL; + parse_process_command_list(parser, hotkey); } else { - parser_report_error(parser, parser_peek(parser), "expected ':' followed by command\n"); + parser_report_error(parser, parser_peek(parser), "expected '~' or ':' followed by command\n"); } } else if (parser_match(parser, Token_EndList)) { if (!buf_len(hotkey->process_name)) { diff --git a/src/tokenize.c b/src/tokenize.c index 8445a71..a0fd93d 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -146,6 +146,8 @@ get_token(struct tokenizer *tokenizer) case ',': { token.type = Token_Comma; } break; case '<': { token.type = Token_Insert; } break; case '@': { token.type = Token_Capture; } break; + case '~': { token.type = Token_Unbound; } break; + case '*': { token.type = Token_Wildcard; } break; case '[': { token.type = Token_BeginList; } break; case ']': { token.type = Token_EndList; } break; case '"': { diff --git a/src/tokenize.h b/src/tokenize.h index 73cdb30..ff82dee 100644 --- a/src/tokenize.h +++ b/src/tokenize.h @@ -49,6 +49,8 @@ enum token_type Token_Dash, Token_Arrow, Token_Capture, + Token_Unbound, + Token_Wildcard, Token_String, Token_BeginList, -- cgit v1.2.3 From 8a952517b0ec62eb87e8053e26eb845a21b3978c Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 23 Feb 2019 17:34:15 +0100 Subject: #62 implement option to unbind certain applications etc. --- README.md | 2 +- examples/skhdrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'examples/skhdrc') diff --git a/README.md b/README.md index a4ddf41..4f916dc 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ keycode = 'apple keyboard kVK_ values (0x3C)' proc_map_lst = * -proc_map = ':' | ':' '~' | +proc_map = ':' | '~' | '*' ':' | '*' '~' string = '"' 'sequence of characters' '"' diff --git a/examples/skhdrc b/examples/skhdrc index e68433c..747ccf7 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -23,7 +23,7 @@ # # proc_map_lst = * # -# proc_map = ':' | ':' '~' | +# proc_map = ':' | '~' | # '*' ':' | '*' '~' # # string = '"' 'sequence of characters' '"' -- cgit v1.2.3 From 600cf250cf6e00efb71117070b7b28074997e8cb Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 24 Feb 2019 13:28:59 +0100 Subject: #54 more accurate profiling information --- README.md | 6 ++--- examples/skhdrc | 1 - makefile | 10 ++------- src/skhd.c | 37 ++++++++---------------------- src/timing.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 40 deletions(-) create mode 100644 src/timing.h (limited to 'examples/skhdrc') diff --git a/README.md b/README.md index 4f916dc..e0b9ded 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,15 @@ Requires xcode-8 command-line tools. make install # release version make # debug version - make fast_profile # release version with profiling information - make profile # debug version with profiling information - ### Usage ``` -V | --verbose: Output debug information skhd -V +-P | --profile: Output profiling information + skhd -P + -v | --version: Print version number to stdout skhd -v diff --git a/examples/skhdrc b/examples/skhdrc index 747ccf7..ffd0613 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -260,4 +260,3 @@ ctrl + alt - s : chunkc tiling::desktop --layout monocle ctrl + alt - d : chunkc tiling::desktop --layout float ctrl + alt - w : chunkc tiling::desktop --deserialize ~/.chunkwm_layouts/dev_1 - diff --git a/makefile b/makefile index 50c5ee8..bbf993f 100644 --- a/makefile +++ b/makefile @@ -1,22 +1,16 @@ -FRAMEWORKS = -framework Carbon +FRAMEWORKS = -framework Carbon -framework CoreAudio BUILD_PATH = ./bin BUILD_FLAGS = -std=c99 -Wall -g -O0 SKHD_SRC = ./src/skhd.c BINS = $(BUILD_PATH)/skhd -.PHONY: all clean install profile fast_profile +.PHONY: all clean install all: clean $(BINS) install: BUILD_FLAGS=-std=c99 -O3 install: clean $(BINS) -profile: BUILD_FLAGS=-std=c99 -Wall -g -O0 -DSKHD_PROFILE -profile: clean $(BINS) - -fast_profile: BUILD_FLAGS=-std=c99 -O3 -DSKHD_PROFILE -fast_profile: clean $(BINS) - clean: rm -rf $(BUILD_PATH) diff --git a/src/skhd.c b/src/skhd.c index 77168c8..d586c9e 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -8,6 +8,7 @@ #include #include +#include "timing.h" #include "log.h" #define HASHTABLE_IMPLEMENTATION #include "hashtable.h" @@ -34,30 +35,6 @@ extern bool CGSIsSecureEventInputSet(); #define secure_keyboard_entry_enabled CGSIsSecureEventInputSet -#ifdef SKHD_PROFILE -#define BEGIN_SCOPED_TIMED_BLOCK(note) \ - do { \ - char *timed_note = note; \ - clock_t timed_block_begin = clock() -#define END_SCOPED_TIMED_BLOCK() \ - clock_t timed_block_end = clock(); \ - double timed_block_elapsed = ((timed_block_end - timed_block_begin) / (double)CLOCKS_PER_SEC) * 1000.0f; \ - printf("%.4fms (%s)\n", timed_block_elapsed, timed_note); \ - } while (0) -#define BEGIN_TIMED_BLOCK(note) \ - char *timed_note = note; \ - 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) * 1000.0f; \ - printf("%.4fms (%s)\n", timed_block_elapsed, timed_note) -#else -#define BEGIN_SCOPED_TIMED_BLOCK(note) -#define END_SCOPED_TIMED_BLOCK() -#define BEGIN_TIMED_BLOCK(note) -#define END_TIMED_BLOCK() -#endif - #define SKHD_CONFIG_FILE ".skhdrc" internal unsigned major_version = 0; @@ -140,9 +117,10 @@ internal bool parse_arguments(int argc, char **argv) { int option; - const char *short_option = "Vvc:k:t:"; + const char *short_option = "VPvc:k:t:"; struct option long_option[] = { { "verbose", no_argument, NULL, 'V' }, + { "profile", no_argument, NULL, 'P' }, { "version", no_argument, NULL, 'v' }, { "config", required_argument, NULL, 'c' }, { "key", required_argument, NULL, 'k' }, @@ -155,6 +133,9 @@ parse_arguments(int argc, char **argv) case 'V': { verbose = true; } break; + case 'P': { + profile = true; + } break; case 'v': { printf("skhd version %d.%d.%d\n", major_version, minor_version, patch_version); return true; @@ -214,12 +195,12 @@ use_default_config_path(void) int main(int argc, char **argv) { - BEGIN_TIMED_BLOCK("startup"); - BEGIN_SCOPED_TIMED_BLOCK("initialization"); if (parse_arguments(argc, argv)) { return EXIT_SUCCESS; } + BEGIN_SCOPED_TIMED_BLOCK("total_time"); + BEGIN_SCOPED_TIMED_BLOCK("init"); if (getuid() == 0 || geteuid() == 0) { error("skhd: running as root is not allowed! abort..\n"); } @@ -274,7 +255,7 @@ int main(int argc, char **argv) warn("skhd: could not watch '%s'\n", config_file); } END_SCOPED_TIMED_BLOCK(); - END_TIMED_BLOCK(); + END_SCOPED_TIMED_BLOCK(); CFRunLoopRun(); return EXIT_SUCCESS; diff --git a/src/timing.h b/src/timing.h new file mode 100644 index 0000000..44e91a8 --- /dev/null +++ b/src/timing.h @@ -0,0 +1,70 @@ +#ifndef MACOS_TIMING_H +#define MACOS_TIMING_H + +#include +#include + +#define BEGIN_SCOPED_TIMED_BLOCK(note) \ + do { \ + struct timing_info timing; \ + if (profile) begin_timing(&timing, note) +#define END_SCOPED_TIMED_BLOCK() \ + if (profile) end_timing(&timing); \ + } while (0) + +#define BEGIN_TIMED_BLOCK(note) \ + struct timing_info timing; \ + if (profile) begin_timing(&timing, note) +#define END_TIMED_BLOCK() \ + if (profile) end_timing(&timing) + +static bool profile; + +struct timing_info +{ + char *note; + uint64_t start; + uint64_t end; + float ms; +}; + +void begin_timing(struct timing_info *timing, char *note); +void end_timing(struct timing_info *timing); + +static inline uint64_t +macos_get_wall_clock(void) +{ + uint64_t result = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); + return result; +} + +static inline float +macos_get_seconds_elapsed(uint64_t start, uint64_t end) +{ + float result = ((float)(end - start) / 1000.0f) / 1000000.0f; + return result; +} + +static inline float +macos_get_milliseconds_elapsed(uint64_t start, uint64_t end) +{ + float result = 1000.0f * macos_get_seconds_elapsed(start, end); + return result; +} + +void begin_timing(struct timing_info *timing, char *note) { + timing->note = note; + timing->start = macos_get_wall_clock(); +} + +void end_timing(struct timing_info *timing) { + timing->end = macos_get_wall_clock(); + timing->ms = macos_get_milliseconds_elapsed(timing->start, timing->end); + if (timing->note) { + printf("%6.4fms (%s)\n", timing->ms, timing->note); + } else { + printf("%6.4fms\n", timing->ms); + } +} + +#endif -- cgit v1.2.3 From 56b94a6eed9fe4642382f533666dc19901fad3fc Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 3 Mar 2019 18:39:34 +0100 Subject: #53 allow opt-out for applications --- README.md | 14 +++++++++++++- examples/skhdrc | 8 ++++++++ src/hotkey.c | 14 ++++++++++++-- src/hotkey.h | 5 +++-- src/parse.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/parse.h | 3 ++- src/skhd.c | 10 ++++++++-- src/tokenize.c | 17 +++++++++++++++++ src/tokenize.h | 1 + 9 files changed, 104 insertions(+), 9 deletions(-) (limited to 'examples/skhdrc') diff --git a/README.md b/README.md index e0b9ded..3ab4481 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ feature comparison between **skhd** and **khd** | hotload config file | [x] | [ ] | | hotkey passthrough | [x] | [x] | | modal hotkey-system | [x] | [x] | -| use media-keys as hotkey | [x] | [ ] | | application specific hotkey| [x] | [x] | +| blacklist applications | [x] | [ ] | +| use media-keys as hotkey | [x] | [ ] | | modifier only hotkey | [ ] | [x] | | caps-lock as hotkey | [ ] | [x] | | mouse-buttons as hotkey | [ ] | [x] | @@ -136,3 +137,14 @@ command = command is executed through '$SHELL -c' and an EOL character signifies the end of the bind. ``` + +General options that configure the behaviour of **skhd**: +``` +# prevents skhd from monitoring events for listed processes +.blacklist [ + "terminal" + "qutebrowser" + "kitty" + "google chrome" +] +``` diff --git a/examples/skhdrc b/examples/skhdrc index ffd0613..bf0f7a3 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -86,6 +86,14 @@ # "finder" : false # ] +# prevent skhd from monitoring events for specific applications +# +# .blacklist [ +# "kitty" +# "terminal" +# "qutebrowser" +# ] + # open terminal, blazingly fast compared to iTerm/Hyper cmd - return : /Applications/Kitty.app/Contents/MacOS/kitty --single-instance -d ~ diff --git a/src/hotkey.c b/src/hotkey.c index 9b6b85a..780aa3a 100644 --- a/src/hotkey.c +++ b/src/hotkey.c @@ -74,7 +74,7 @@ unsigned long hash_hotkey(struct hotkey *a) return a->key; } -bool same_mode(char *a, char *b) +bool compare_string(char *a, char *b) { while (*a && *b && *a == *b) { ++a; @@ -83,7 +83,7 @@ bool same_mode(char *a, char *b) return *a == '\0' && *b == '\0'; } -unsigned long hash_mode(char *key) +unsigned long hash_string(char *key) { unsigned long hash = 0, high; while(*key) { @@ -228,6 +228,16 @@ next:; } } +void free_blacklist(struct table *blacklst) +{ + int count; + void **items = table_reset(blacklst, &count); + for (int index = 0; index < count; ++index) { + char *item = (char *) items[index]; + free(item); + } +} + internal void cgevent_lrmod_flag_to_hotkey_lrmod_flag(CGEventFlags eventflags, uint32_t *flags, int mod) { diff --git a/src/hotkey.h b/src/hotkey.h index 372715d..4611b09 100644 --- a/src/hotkey.h +++ b/src/hotkey.h @@ -100,8 +100,8 @@ clear_flags(struct hotkey *hotkey, uint32_t flag) #undef internal -bool same_mode(char *a, char *b); -unsigned long hash_mode(char *key); +bool compare_string(char *a, char *b); +unsigned long hash_string(char *key); bool same_hotkey(struct hotkey *a, struct hotkey *b); unsigned long hash_hotkey(struct hotkey *a); @@ -111,6 +111,7 @@ bool intercept_systemkey(CGEventRef event, struct hotkey *eventkey); bool find_and_exec_hotkey(struct hotkey *k, struct table *t, struct mode **m, struct carbon_event *carbon); void free_mode_map(struct table *mode_map); +void free_blacklist(struct table *blacklst); void init_shell(void); diff --git a/src/parse.c b/src/parse.c index 760485d..4e673f4 100644 --- a/src/parse.c +++ b/src/parse.c @@ -384,6 +384,41 @@ void parse_declaration(struct parser *parser) } } +void parse_option_blacklist(struct parser *parser) +{ + if (parser_match(parser, Token_String)) { + struct token name_token = parser_previous(parser); + char *name = copy_string_count(name_token.text, name_token.length); + for (char *s = name; *s; ++s) *s = tolower(*s); + debug("\t%s\n", name); + table_add(parser->blacklst, name, name); + parse_option_blacklist(parser); + } else if (parser_match(parser, Token_EndList)) { + if (parser->blacklst->count == 0) { + parser_report_error(parser, parser_previous(parser), "list must contain at least one value\n"); + } + } else { + parser_report_error(parser, parser_peek(parser), "expected process name or ']'\n"); + } +} + +void parse_option(struct parser *parser) +{ + parser_match(parser, Token_Option); + struct token option = parser_previous(parser); + if (token_equals(option, "blacklist")) { + if (parser_match(parser, Token_BeginList)) { + debug("blacklist :: #%d {\n", option.line); + parse_option_blacklist(parser); + debug("}\n"); + } else { + parser_report_error(parser, option, "expected '[' followed by list of process names\n"); + } + } else { + parser_report_error(parser, option, "invalid option specified\n"); + } +} + void parse_config(struct parser *parser) { struct mode *mode; @@ -392,6 +427,7 @@ void parse_config(struct parser *parser) while (!parser_eof(parser)) { if (parser->error) { free_mode_map(parser->mode_map); + free_blacklist(parser->blacklst); return; } @@ -408,6 +444,8 @@ void parse_config(struct parser *parser) } } else if (parser_check(parser, Token_Decl)) { parse_declaration(parser); + } else if (parser_check(parser, Token_Option)) { + parse_option(parser); } else { parser_report_error(parser, parser_peek(parser), "expected decl, modifier or key-literal\n"); } @@ -512,12 +550,13 @@ void parser_report_error(struct parser *parser, struct token token, const char * parser->error = true; } -bool parser_init(struct parser *parser, struct table *mode_map, char *file) +bool parser_init(struct parser *parser, struct table *mode_map, struct table *blacklst, char *file) { memset(parser, 0, sizeof(struct parser)); char *buffer = read_file(file); if (buffer) { parser->mode_map = mode_map; + parser->blacklst = blacklst; tokenizer_init(&parser->tokenizer, buffer); parser_advance(parser); return true; diff --git a/src/parse.h b/src/parse.h index 35bc62e..95813c2 100644 --- a/src/parse.h +++ b/src/parse.h @@ -11,6 +11,7 @@ struct parser struct token current_token; struct tokenizer tokenizer; struct table *mode_map; + struct table *blacklst; bool error; }; @@ -23,7 +24,7 @@ bool parser_eof(struct parser *parser); struct token parser_advance(struct parser *parser); bool parser_check(struct parser *parser, enum token_type type); bool parser_match(struct parser *parser, enum token_type type); -bool parser_init(struct parser *parser, struct table *mode_map, char *file); +bool parser_init(struct parser *parser, struct table *mode_map, struct table *blacklst, char *file); bool parser_init_text(struct parser *parser, char *text); void parser_destroy(struct parser *parser); void parser_report_error(struct parser *parser, struct token token, const char *format, ...); diff --git a/src/skhd.c b/src/skhd.c index 05e955f..ceea857 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -48,13 +48,14 @@ global struct event_tap event_tap; global struct hotloader hotloader; global struct mode *current_mode; global struct table mode_map; +global struct table blacklst; global char *config_file; internal void parse_config_helper(char *absolutepath) { struct parser parser; - if (parser_init(&parser, &mode_map, absolutepath)) { + if (parser_init(&parser, &mode_map, &blacklst, absolutepath)) { parse_config(&parser); parser_destroy(&parser); } else { @@ -68,6 +69,7 @@ internal HOTLOADER_CALLBACK(config_handler) BEGIN_TIMED_BLOCK("hotload_config"); debug("skhd: config-file has been modified.. reloading config\n"); free_mode_map(&mode_map); + free_blacklist(&blacklst); parse_config_helper(absolutepath); END_TIMED_BLOCK(); } @@ -78,6 +80,7 @@ internal CF_NOTIFICATION_CALLBACK(keymap_handler) if (initialize_keycode_map()) { debug("skhd: input source changed.. reloading config\n"); free_mode_map(&mode_map); + free_blacklist(&blacklst); parse_config_helper(config_file); } END_TIMED_BLOCK(); @@ -93,6 +96,7 @@ internal EVENT_TAP_CALLBACK(key_handler) CGEventTapEnable(event_tap->handle, 1); } break; case kCGEventKeyDown: { + if (table_find(&blacklst, carbon.process_name)) return event; if (!current_mode) return event; BEGIN_TIMED_BLOCK("handle_keypress"); @@ -103,6 +107,7 @@ internal EVENT_TAP_CALLBACK(key_handler) if (result) return NULL; } break; case NX_SYSDEFINED: { + if (table_find(&blacklst, carbon.process_name)) return event; if (!current_mode) return event; struct hotkey eventkey; @@ -236,7 +241,8 @@ int main(int argc, char **argv) signal(SIGCHLD, SIG_IGN); init_shell(); - table_init(&mode_map, 13, (table_hash_func) hash_mode, (table_compare_func) same_mode); + table_init(&mode_map, 13, (table_hash_func) hash_string, (table_compare_func) compare_string); + table_init(&blacklst, 13, (table_hash_func) hash_string, (table_compare_func) compare_string); END_SCOPED_TIMED_BLOCK(); BEGIN_SCOPED_TIMED_BLOCK("parse_config"); diff --git a/src/tokenize.c b/src/tokenize.c index a0fd93d..eaf0e3a 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -79,6 +79,14 @@ eat_string(struct tokenizer *tokenizer) } } +internal void +eat_option(struct tokenizer *tokenizer) +{ + while (*tokenizer->at && !isspace(*tokenizer->at)) { + advance(tokenizer); + } +} + internal inline bool isidentifier(char c) { @@ -150,6 +158,15 @@ get_token(struct tokenizer *tokenizer) case '*': { token.type = Token_Wildcard; } break; case '[': { token.type = Token_BeginList; } break; case ']': { token.type = Token_EndList; } break; + case '.': { + token.text = tokenizer->at; + token.line = tokenizer->line; + token.cursor = tokenizer->cursor; + + eat_option(tokenizer); + token.length = tokenizer->at - token.text; + token.type = Token_Option; + } break; case '"': { token.text = tokenizer->at; token.line = tokenizer->line; diff --git a/src/tokenize.h b/src/tokenize.h index 4592ac9..4df5df3 100644 --- a/src/tokenize.h +++ b/src/tokenize.h @@ -56,6 +56,7 @@ enum token_type Token_Unbound, Token_Wildcard, Token_String, + Token_Option, Token_BeginList, Token_EndList, -- cgit v1.2.3 From ac494e3f72e397aaf3245b0401bd1b963bd4ebd3 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sun, 3 Mar 2019 22:24:14 +0100 Subject: #58 load/include additional config files --- README.md | 10 ++++++- examples/skhdrc | 9 ++++++- src/parse.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/parse.h | 10 ++++++- src/skhd.c | 30 +++++++++++++-------- 5 files changed, 121 insertions(+), 20 deletions(-) (limited to 'examples/skhdrc') diff --git a/README.md b/README.md index 3ab4481..24b9226 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,15 @@ command = command is executed through '$SHELL -c' and General options that configure the behaviour of **skhd**: ``` -# prevents skhd from monitoring events for listed processes +# specify a file that should be included as an additional config-file. +# treated as an absolutepath if the filename begins with '/' otherwise +# the file is relative to the path of the config-file it was loaded from. + +.load "/Users/Koe/.config/partial_skhdrc" +.load "partial_skhdrc" + +# prevents skhd from monitoring events for listed processes. + .blacklist [ "terminal" "qutebrowser" diff --git a/examples/skhdrc b/examples/skhdrc index bf0f7a3..48b5424 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -86,7 +86,14 @@ # "finder" : false # ] -# prevent skhd from monitoring events for specific applications +# specify a file that should be included as an additional config-file. +# treated as an absolutepath if the filename begins with '/' otherwise +# the file is relative to the path of the config-file it was loaded from. +# +# .load "/Users/Koe/.config/partial_skhdrc" +# .load "partial_skhdrc" + +# prevent skhd from monitoring events for specific applications. # # .blacklist [ # "kitty" diff --git a/src/parse.c b/src/parse.c index 4e673f4..9f14389 100644 --- a/src/parse.c +++ b/src/parse.c @@ -402,6 +402,32 @@ void parse_option_blacklist(struct parser *parser) } } +void parse_option_load(struct parser *parser, struct token option) +{ + struct token filename_token = parser_previous(parser); + char *filename = copy_string_count(filename_token.text, filename_token.length); + debug("\t%s\n", filename); + + if (*filename != '/') { + char *directory = file_directory(parser->file); + + size_t directory_length = strlen(directory); + size_t filename_length = strlen(filename); + size_t total_length = directory_length + filename_length + 2; + + char *absolutepath = malloc(total_length * sizeof(char)); + snprintf(absolutepath, total_length, "%s/%s", directory, filename); + free(filename); + + filename = absolutepath; + } + + buf_push(parser->load_directives, ((struct load_directive) { + .file = filename, + .option = option + })); +} + void parse_option(struct parser *parser) { parser_match(parser, Token_Option); @@ -414,22 +440,26 @@ void parse_option(struct parser *parser) } else { parser_report_error(parser, option, "expected '[' followed by list of process names\n"); } + } else if (token_equals(option, "load")) { + if (parser_match(parser, Token_String)) { + debug("load :: #%d {\n", option.line); + parse_option_load(parser, option); + debug("}\n"); + } else { + parser_report_error(parser, option, "expected filename\n"); + } } else { parser_report_error(parser, option, "invalid option specified\n"); } } -void parse_config(struct parser *parser) +bool parse_config(struct parser *parser) { struct mode *mode; struct hotkey *hotkey; while (!parser_eof(parser)) { - if (parser->error) { - free_mode_map(parser->mode_map); - free_blacklist(parser->blacklst); - return; - } + if (parser->error) break; if ((parser_check(parser, Token_Identifier)) || (parser_check(parser, Token_Modifier)) || @@ -450,6 +480,14 @@ void parse_config(struct parser *parser) parser_report_error(parser, parser_peek(parser), "expected decl, modifier or key-literal\n"); } } + + if (parser->error) { + free_mode_map(parser->mode_map); + free_blacklist(parser->blacklst); + return false; + } + + return true; } struct hotkey * @@ -550,11 +588,43 @@ void parser_report_error(struct parser *parser, struct token token, const char * parser->error = true; } +void parser_do_directives(struct parser *parser, struct hotloader *hotloader) +{ + bool error = false; + + for (int i = 0; i < buf_len(parser->load_directives); ++i) { + struct load_directive load = parser->load_directives[i]; + + struct parser directive_parser; + if (parser_init(&directive_parser, parser->mode_map, parser->blacklst, load.file)) { + hotloader_add_file(hotloader, load.file); + + if (parse_config(&directive_parser)) { + parser_do_directives(&directive_parser, hotloader); + } else { + error = true; + } + parser_destroy(&directive_parser); + } else { + warn("skhd: could not open file '%s' from load directive #%d:%d\n", load.file, load.option.line, load.option.cursor); + } + + free(load.file); + } + buf_free(parser->load_directives); + + if (error) { + free_mode_map(parser->mode_map); + free_blacklist(parser->blacklst); + } +} + bool parser_init(struct parser *parser, struct table *mode_map, struct table *blacklst, char *file) { memset(parser, 0, sizeof(struct parser)); char *buffer = read_file(file); if (buffer) { + parser->file = file; parser->mode_map = mode_map; parser->blacklst = blacklst; tokenizer_init(&parser->tokenizer, buffer); diff --git a/src/parse.h b/src/parse.h index 95813c2..6576f7a 100644 --- a/src/parse.h +++ b/src/parse.h @@ -4,18 +4,26 @@ #include "tokenize.h" #include +struct load_directive +{ + char *file; + struct token option; +}; + struct table; struct parser { + char *file; struct token previous_token; struct token current_token; struct tokenizer tokenizer; struct table *mode_map; struct table *blacklst; + struct load_directive *load_directives; bool error; }; -void parse_config(struct parser *parser); +bool parse_config(struct parser *parser); struct hotkey *parse_keypress(struct parser *parser); struct token parser_peek(struct parser *parser); diff --git a/src/skhd.c b/src/skhd.c index ceea857..c90c4b6 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -51,16 +51,33 @@ global struct table mode_map; global struct table blacklst; global char *config_file; +internal HOTLOADER_CALLBACK(config_handler); + internal void parse_config_helper(char *absolutepath) { struct parser parser; if (parser_init(&parser, &mode_map, &blacklst, absolutepath)) { - parse_config(&parser); + hotloader_end(&hotloader); + hotloader_add_file(&hotloader, absolutepath); + + if (parse_config(&parser)) { + parser_do_directives(&parser, &hotloader); + } parser_destroy(&parser); + + if (hotloader_begin(&hotloader, config_handler)) { + debug("skhd: watching files for changes:\n", absolutepath); + for (int i = 0; i < hotloader.watch_count; ++i) { + debug("\t%s\n", hotloader.watch_list[i].file_info.absolutepath); + } + } else { + warn("skhd: could not start watcher.. hotloading is not enabled\n"); + } } else { warn("skhd: could not open file '%s'\n", absolutepath); } + current_mode = table_find(&mode_map, "default"); } @@ -70,7 +87,7 @@ internal HOTLOADER_CALLBACK(config_handler) debug("skhd: config-file has been modified.. reloading config\n"); free_mode_map(&mode_map); free_blacklist(&blacklst); - parse_config_helper(absolutepath); + parse_config_helper(config_file); END_TIMED_BLOCK(); } @@ -254,15 +271,6 @@ int main(int argc, char **argv) event_tap.mask = (1 << kCGEventKeyDown) | (1 << NX_SYSDEFINED); event_tap_begin(&event_tap, key_handler); END_SCOPED_TIMED_BLOCK(); - - BEGIN_SCOPED_TIMED_BLOCK("begin_hotloader"); - if (hotloader_add_file(&hotloader, config_file) && - hotloader_begin(&hotloader, config_handler)) { - debug("skhd: watching '%s' for changes\n", config_file); - } else { - warn("skhd: could not watch '%s'\n", config_file); - } - END_SCOPED_TIMED_BLOCK(); END_SCOPED_TIMED_BLOCK(); CFRunLoopRun(); -- cgit v1.2.3 From 52cde83ab83b115f0c136a48b5825d57753c94b8 Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Sat, 13 Apr 2019 15:43:37 +0200 Subject: update sample config --- examples/skhdrc | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'examples/skhdrc') diff --git a/examples/skhdrc b/examples/skhdrc index 48b5424..3486c1f 100644 --- a/examples/skhdrc +++ b/examples/skhdrc @@ -41,6 +41,10 @@ # # -> = keypress is not consumed by skhd # +# * = matches every application not specified in +# +# ~ = application is unbound and keypress is forwarded per usual, when specified in a +# # NOTE(koekeishiya): A mode is declared according to the following rules: # # mode_decl = '::' '@' ':' | '::' ':' | @@ -169,19 +173,10 @@ cmd + alt - 3 : chunkc tiling::desktop --focus 3 cmd + alt - 4 : chunkc tiling::desktop --focus 4 cmd + alt - 5 : chunkc tiling::desktop --focus 5 cmd + alt - 6 : chunkc tiling::desktop --focus 6 -# cmd + alt - 7 : chunkc tiling::desktop --focus 7 - -# send window to desktop -shift + alt - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop) -shift + alt - z : chunkc tiling::window --send-to-desktop prev -shift + alt - c : chunkc tiling::window --send-to-desktop next -shift + alt - 1 : chunkc tiling::window --send-to-desktop 1 -shift + alt - 2 : chunkc tiling::window --send-to-desktop 2 -shift + alt - 3 : chunkc tiling::window --send-to-desktop 3 -shift + alt - 4 : chunkc tiling::window --send-to-desktop 4 -shift + alt - 5 : chunkc tiling::window --send-to-desktop 5 -shift + alt - 6 : chunkc tiling::window --send-to-desktop 6 -# shift + alt - 7 : chunkc tiling::window --send-to-desktop 7 +cmd + alt - 7 : chunkc tiling::desktop --focus 7 +cmd + alt - 8 : chunkc tiling::desktop --focus 8 +cmd + alt - 9 : chunkc tiling::desktop --focus 9 +cmd + alt - 0 : chunkc tiling::desktop --focus 10 # send window to desktop and follow focus shift + cmd - x : chunkc tiling::window --send-to-desktop $(chunkc get _last_active_desktop); chunkc tiling::desktop --focus $(chunkc get _last_active_desktop) @@ -193,7 +188,10 @@ shift + cmd - 3 : chunkc tiling::window --send-to-desktop 3; chunkc tiling::desk shift + cmd - 4 : chunkc tiling::window --send-to-desktop 4; chunkc tiling::desktop --focus 4 shift + cmd - 5 : chunkc tiling::window --send-to-desktop 5; chunkc tiling::desktop --focus 5 shift + cmd - 6 : chunkc tiling::window --send-to-desktop 6; chunkc tiling::desktop --focus 6 -# shift + cmd - 7 : chunkc tiling::window --send-to-desktop 7; chunkc tiling::desktop --focus 7 +shift + cmd - 7 : chunkc tiling::window --send-to-desktop 7; chunkc tiling::desktop --focus 7 +shift + cmd - 8 : chunkc tiling::window --send-to-desktop 8; chunkc tiling::desktop --focus 8 +shift + cmd - 9 : chunkc tiling::window --send-to-desktop 9; chunkc tiling::desktop --focus 9 +shift + cmd - 0 : chunkc tiling::window --send-to-desktop 10; chunkc tiling::desktop --focus 10 # focus monitor ctrl + alt - z : chunkc tiling::monitor -f prev -- cgit v1.2.3