Merge pull request #16 from taiyu-len/multikey_handling

Multikey handling
This commit is contained in:
Drew DeVault 2015-08-11 09:50:23 -04:00
commit 803a4739b6

View file

@ -55,38 +55,66 @@ void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* ge
// deny that shit // deny that shit
} }
bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers
*modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state) { *modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state) {
// TODO: handle keybindings with more than 1 non-modifier key involved enum { QSIZE = 32 };
// Note: reminder to check conflicts with mod+q+a versus mod+q static uint8_t head = 0;
static uint32_t array[QSIZE];
bool cmd_success = true; bool cmd_success = true;
struct sway_mode *mode = config->current_mode;
struct sway_mode *mode = config->current_mode;
// Lowercase if necessary // Lowercase if necessary
sym = tolower(sym); sym = tolower(sym);
//Find key, if it has been pressed
int mid = 0;
while (mid < head && array[mid] != sym) {
++mid;
}
if (state == WLC_KEY_STATE_PRESSED && mid == head && head + 1 < QSIZE) {
array[head++] = sym;
} else if (state == WLC_KEY_STATE_RELEASED && mid < head) {
memmove(array + mid, array + mid + 1, sizeof*array * (--head - mid));
}
sway_log(L_INFO,"%d", head);
// TODO: reminder to check conflicts with mod+q+a versus mod+q
int i; int i;
for (i = 0; i < mode->bindings->length; ++i) { for (i = 0; i < mode->bindings->length; ++i) {
struct sway_binding *binding = mode->bindings->items[i]; struct sway_binding *binding = mode->bindings->items[i];
if ((modifiers->mods & binding->modifiers) == binding->modifiers) { if ((modifiers->mods & binding->modifiers) == binding->modifiers) {
bool match = true; bool match;
int j; int j;
for (j = 0; j < binding->keys->length; ++j) { for (j = 0; j < binding->keys->length; ++j) {
xkb_keysym_t *k = binding->keys->items[j];
if (sym != *k) {
match = false; match = false;
xkb_keysym_t *key = binding->keys->items[j];
uint8_t k;
for (k = 0; k < head; ++k) {
if (array[k] == *key) {
match = true;
break;
}
}
if (match == false) {
break; break;
} }
} }
if (match) { if (match) {
// TODO: --released //Remove matched keys from array
int j;
for (j = 0; j < binding->keys->length; ++j) {
uint8_t k;
for (k = 0; k < head; ++k) {
memmove(array + k, array + k + 1, sizeof*array * (--head - k));
break;
}
}
if (state == WLC_KEY_STATE_PRESSED) { if (state == WLC_KEY_STATE_PRESSED) {
cmd_success = !handle_command(config, binding->command); cmd_success = !handle_command(config, binding->command);
} else { } else if (state == WLC_KEY_STATE_RELEASED) {
cmd_success = true; // TODO: --released
} }
} }
} }