<commit_before>#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include "types.h"
#include "parse.h"

hotkey_t *find_hotkey(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool *replay_event)
{
    int hits = 0;

    for (hotkey_t *hk = hotkeys; hk != NULL; hk = hk->next) {
        chain_t *c = hk->chain;
        if (chained && c->state == c->head)
            continue;
        if (match_chord(c->state, event_type, keysym, button, modfield)) {
            if (replay_event != NULL && c->state->replay_event)
                *replay_event = true;
            if (c->state == c->tail) {
                if (chained)
                    abort_chain();
                return hk;
            } else {
                c->state = c->state->next;
            }
            hits++;
        } else if (chained && c->state->event_type == event_type) {
            c->state = c->head;
        }
    }

    if (hits > 0) {
        chained = true;
        if (timeout > 0)
            alarm(timeout);
    } else if (!chained) {
        *replay_event = true;
        for (hotkey_t *hk = hotkeys; *replay_event && hk != NULL; hk = hk->next) {
            chord_t *c = hk->chain->head;
            for (chord_t *cc = c; cc != NULL; cc = cc->more)
                if (cc->keysym == keysym && cc->button == button && cc->modfield == modfield)
                    *replay_event = false;
        }
    }

    return NULL;
}

bool match_chord(chord_t *chord, uint8_t event_type, xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield) {
    for (chord_t *c = chord; c != NULL; c = c->more)
        if (c->event_type == event_type && c->keysym == keysym && c->button == button && c->modfield == modfield)
            return true;
    return false;
}

chord_t *make_chord(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool replay_event)
{
    chord_t *chord;
    if (button == XCB_NONE) {<commit_msg>When there's no waiters, abort the chain<commit_after>#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include "types.h"
#include "parse.h"

hotkey_t *find_hotkey(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool *replay_event)
{
    int hits = 0;
    int num_waiters = 0;

    for (hotkey_t *hk = hotkeys; hk != NULL; hk = hk->next) {
        chain_t *c = hk->chain;
        if (chained && c->state == c->head)
            continue;
        if (match_chord(c->state, event_type, keysym, button, modfield)) {
            if (replay_event != NULL && c->state->replay_event)
                *replay_event = true;
            if (c->state == c->tail) {
                if (chained)
                    abort_chain();
                return hk;
            } else {
                c->state = c->state->next;
                num_waiters++;
            }
            hits++;
        } else if (chained) {
            if (c->state->event_type == event_type)
                    c->state = c->head;
            else
                num_waiters++;
        }
    }

    if (hits > 0) {
        chained = true;
        if (timeout > 0)
            alarm(timeout);
    } else if (!chained) {
        *replay_event = true;
        for (hotkey_t *hk = hotkeys; *replay_event && hk != NULL; hk = hk->next) {
            chord_t *c = hk->chain->head;
            for (chord_t *cc = c; cc != NULL; cc = cc->more)
                if (cc->keysym == keysym && cc->button == button && cc->modfield == modfield)
                    *replay_event = false;
        }
    }

    PRINTF("num waiters %i\n", num_waiters);

    if (chained && num_waiters == 0)
        abort_chain();

    return NULL;
}

bool match_chord(chord_t *chord, uint8_t event_type, xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield) {
    for (chord_t *c = chord; c != NULL; c = c->more)
        if (c->event_type == event_type && c->keysym == keysym && c->button == button && c->modfield == modfield)
            return true;
    return false;
}

chord_t *make_chord(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool replay_event)
{
    chord_t *chord;
    if (button == XCB_NONE) {
{'fraction_non_alphanumeric': 0.13769485120453473, 'fraction_numerical': 0.006140765233821445, 'mean_word_length': 1.9781997187060478, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1280040', 'n_tokens_mistral': 1526, 'n_tokens_neox': 1481, 'n_words': 354}