<commit_before>#include <plugin.hpp>
#include <output.hpp>
#include <core.hpp>
#include <linux/input.h>
#include <linux/input-event-codes.h>
#include <signal-definitions.hpp>

static bool begins_with(std::string word, std::string prefix)
{
    if (word.length() < prefix.length())
        return false;

    return word.substr(0, prefix.length()) == prefix;
}

/* Initial repeat delay passed */
static int repeat_delay_timeout_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // disconnect
};

/* Between each repeat */
static int repeat_once_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // continue timer
}

/* Provides a way to bind specific commands to activator bindings.
 *
 * It supports 2 modes:
 *
 * 1. Regular bindings
 * 2. Repeatable bindings - for example, if the user binds a keybinding, then
 * after a specific delay the command begins to be executed repeatedly, until
 * the user released the key. In the config file, repeatable bindings have the
 * prefix repeatable_
 * 3. Always bindings - bindings that can be executed even if a plugin is already
 * active, or if the screen is locked. They have a prefix always_
 * */

class wayfire_command : public wf::plugin_interface_t
{
    std::vector<activator_callback> bindings;

    struct
    {
        uint32_t pressed_button = 0;
        uint32_t pressed_key = 0;
        std::string repeat_command;
    } repeat;

    wl_event_source *repeat_source = NULL, *repeat_delay_source = NULL;

    enum binding_mode {
        BINDING_NORMAL,
        BINDING_REPEAT,
        BINDING_ALWAYS,
    };
    bool on_binding(std::string command, binding_mode mode, wf_activator_source source,
        uint32_t value)
    {
        /* We already have a repeatable command, do not accept further bindings */
        if (repeat.pressed_key || repeat.pressed_button)
            return false;

        if (!output->activate_plugin(grab_interface, mode == BINDING_ALWAYS))
            return false;

        wf::get_core().run(command.c_str());

        /* No repeat necessary in any of those cases */
        if (mode != BINDING_REPEAT || source == ACTIVATOR_SOURCE_GESTURE ||
            value == 0)
        {
            output->deactivate_plugin(grab_interface);
            return false;
        }

        repeat.repeat_command = command;
        if (source == ACTIVATOR_SOURCE_KEYBINDING) {
            repeat.pressed_key = value;
        } else {
            repeat.pressed_button = value;
        }

        repeat_delay_source = wl_event_loop_add_timer(wf::get_core().ev_loop,
            repeat_delay_timeout_handler, &on_repeat_delay_timeout);

        wl_event_source_timer_update(repeat_delay_source,
            wf::get_core().config->get_section("input")
                ->get_option("kb_repeat_delay", "400")->as_int());

        wf::get_core().connect_signal("pointer_button", &on_button_event);<commit_msg>command: return true when binding was successfully handled<commit_after>#include <plugin.hpp>
#include <output.hpp>
#include <core.hpp>
#include <linux/input.h>
#include <linux/input-event-codes.h>
#include <signal-definitions.hpp>

static bool begins_with(std::string word, std::string prefix)
{
    if (word.length() < prefix.length())
        return false;

    return word.substr(0, prefix.length()) == prefix;
}

/* Initial repeat delay passed */
static int repeat_delay_timeout_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // disconnect
};

/* Between each repeat */
static int repeat_once_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // continue timer
}

/* Provides a way to bind specific commands to activator bindings.
 *
 * It supports 2 modes:
 *
 * 1. Regular bindings
 * 2. Repeatable bindings - for example, if the user binds a keybinding, then
 * after a specific delay the command begins to be executed repeatedly, until
 * the user released the key. In the config file, repeatable bindings have the
 * prefix repeatable_
 * 3. Always bindings - bindings that can be executed even if a plugin is already
 * active, or if the screen is locked. They have a prefix always_
 * */

class wayfire_command : public wf::plugin_interface_t
{
    std::vector<activator_callback> bindings;

    struct
    {
        uint32_t pressed_button = 0;
        uint32_t pressed_key = 0;
        std::string repeat_command;
    } repeat;

    wl_event_source *repeat_source = NULL, *repeat_delay_source = NULL;

    enum binding_mode {
        BINDING_NORMAL,
        BINDING_REPEAT,
        BINDING_ALWAYS,
    };
    bool on_binding(std::string command, binding_mode mode, wf_activator_source source,
        uint32_t value)
    {
        /* We already have a repeatable command, do not accept further bindings */
        if (repeat.pressed_key || repeat.pressed_button)
            return false;

        if (!output->activate_plugin(grab_interface, mode == BINDING_ALWAYS))
            return false;

        wf::get_core().run(command.c_str());

        /* No repeat necessary in any of those cases */
        if (mode != BINDING_REPEAT || source == ACTIVATOR_SOURCE_GESTURE ||
            value == 0)
        {
            output->deactivate_plugin(grab_interface);
            return true;
        }

        repeat.repeat_command = command;
        if (source == ACTIVATOR_SOURCE_KEYBINDING) {
            repeat.pressed_key = value;
        } else {
            repeat.pressed_button = value;
        }

        repeat_delay_source = wl_event_loop_add_timer(wf::get_core().ev_loop,
            repeat_delay_timeout_handler, &on_repeat_delay_timeout);

        wl_event_source_timer_update(repeat_delay_source,
            wf::get_core().config->get_section("input")
                ->get_option("kb_repeat_delay", "400")->as_int());

        wf::get_core().connect_signal("pointer_button", &on_button_event);
{'fraction_non_alphanumeric': 0.10488696808510638, 'fraction_numerical': 0.006316489361702127, 'mean_word_length': 3.038255033557047, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 35, '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': '5267211', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1738, 'n_words': 468}