aboutsummaryrefslogtreecommitdiff
path: root/src/hotkey.c
diff options
context:
space:
mode:
authorkoekeishiya <aasvi93@hotmail.com>2017-10-07 23:31:15 +0200
committerkoekeishiya <aasvi93@hotmail.com>2017-10-07 23:31:15 +0200
commit94c26f456f095ec8334d9c313943c2747d27c0c2 (patch)
tree248a10b142f0a59192c931da57643b90ad3b9d4a /src/hotkey.c
parent679ae51b23bd936485e1c5c1e868e4dec4995e97 (diff)
downloadskhd-94c26f456f095ec8334d9c313943c2747d27c0c2.tar.gz
skhd-94c26f456f095ec8334d9c313943c2747d27c0c2.zip
#15 modal support
Diffstat (limited to 'src/hotkey.c')
-rw-r--r--src/hotkey.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/src/hotkey.c b/src/hotkey.c
index d9ebde6..fae753b 100644
--- a/src/hotkey.c
+++ b/src/hotkey.c
@@ -61,6 +61,29 @@ unsigned long hash_hotkey(struct hotkey *a)
return a->key;
}
+bool same_mode(char *a, char *b)
+{
+ while (*a && *b && *a == *b) {
+ ++a;
+ ++b;
+ }
+ return *a == '\0' && *b == '\0';
+}
+
+unsigned long hash_mode(char *key)
+{
+ unsigned long hash = 0, high;
+ while(*key) {
+ hash = (hash << 4) + *key++;
+ high = hash & 0xF0000000;
+ if(high) {
+ hash ^= (high >> 24);
+ }
+ hash &= ~high;
+ }
+ return hash;
+}
+
internal bool
fork_and_exec(char *command)
{
@@ -81,26 +104,36 @@ fork_and_exec(char *command)
return true;
}
-bool find_and_exec_hotkey(struct hotkey *eventkey, struct table *hotkey_map)
+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(hotkey_map, eventkey))) {
- if (fork_and_exec(hotkey->command)) {
+ if ((hotkey = table_find(&(*current_mode)->hotkey_map, eventkey))) {
+ 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;
}
}
return result;
}
-void free_hotkeys(struct table *hotkey_map)
+internal void
+free_hotkeys(struct table *hotkey_map)
{
int count;
void **hotkeys = table_reset(hotkey_map, &count);
for (int index = 0; index < count; ++index) {
struct hotkey *hotkey = (struct hotkey *) hotkeys[index];
- free(hotkey->command);
- free(hotkey);
+ // the same hotkey can be added for multiple modes
+ // we need to know if this pointer was already freed
+ // by a mode that was destroyed before us
+ // free(hotkey->command);
+ // free(hotkey);
}
if (count) {
@@ -108,6 +141,23 @@ void free_hotkeys(struct table *hotkey_map)
}
}
+void free_mode_map(struct table *mode_map)
+{
+ int count;
+ void **modes = table_reset(mode_map, &count);
+ for (int index = 0; index < count; ++index) {
+ struct mode *mode = (struct mode *) modes[index];
+ if (mode->command) free(mode->command);
+ if (mode->name) free(mode->name);
+ free_hotkeys(&mode->hotkey_map);
+ free(mode);
+ }
+
+ if (count) {
+ free(modes);
+ }
+}
+
internal void
cgevent_lrmod_flag_to_hotkey_lrmod_flag(CGEventFlags flags, struct hotkey *eventkey, int mod)
{