diff options
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | data-device.c | 2 | ||||
| -rw-r--r-- | input_field.c | 17 | ||||
| -rw-r--r-- | input_field.h | 4 | ||||
| -rw-r--r-- | keybind.c | 28 | ||||
| -rw-r--r-- | keybind.h | 7 | ||||
| -rw-r--r-- | keyboard.c | 2 | ||||
| -rw-r--r-- | main.c | 9 |
8 files changed, 59 insertions, 13 deletions
@@ -44,9 +44,10 @@ cursor_color = (0.9, 0.9, 0.9, 0.5) - [x] "prompt" - [x] fuzzy filter - [x] config file -- [x] border +- [ ] border, top padding in vertical and set exact height - [ ] unicode + text shaping Stretch: - [ ] clean up the code (src folder, rename some files) - [ ] input fluff (icons, descriptions, output names) +- [ ] arguments to override config such as fancy scroll? diff --git a/data-device.c b/data-device.c index 3132716..3dadfea 100644 --- a/data-device.c +++ b/data-device.c @@ -65,7 +65,7 @@ static void data_device_handle_selection(void *data, // remove newlines int i, j; for (i = 0, j = 0; i < state->clipboard_size; i++) { - if (state->clipboard[i] != '\n' && state->clipboard[i] != '\r') { + if (state->clipboard[i] != '\n' && state->clipboard[i] != '\r' && state->clipboard[i] != '\t') { state->clipboard[j++] = state->clipboard[i]; } } diff --git a/input_field.c b/input_field.c index 78e0a05..6a4dd54 100644 --- a/input_field.c +++ b/input_field.c @@ -13,7 +13,7 @@ int orderless_compare(const void *a, const void *b) { return ((item_display_t*)a)->perc < ((item_display_t*)b)->perc; } -void filter_items(client_state* state) { +void refilter_items(client_state* state) { if (!state->items) return; // get null terminated input buffer @@ -80,12 +80,12 @@ void filter_items(client_state* state) { } void update_text_buffer(client_state* state) { - filter_items(state); + refilter_items(state); destroy_text_buffer(&state->input_buffer_grafix); init_text_buffer(state, &state->input_buffer_grafix, state->input_buffer, array_size(state->input_buffer)); } -key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { +key_repeat_t execute_keypress(client_state* state, xkb_keysym_t keysym) { bool ctrl = xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE); bool alt = xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE); @@ -97,6 +97,7 @@ key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { case XKB_KEY_f: return forward_word(state); case XKB_KEY_b: return backward_word(state); } + return KEY_NO_REPEAT; } else if (ctrl) { switch (keysym) { @@ -107,8 +108,8 @@ key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { case XKB_KEY_n: return select_next(state); case XKB_KEY_p: return select_previous(state); - case XKB_KEY_e: return goto_end(state); case XKB_KEY_a: return goto_start(state); + case XKB_KEY_e: return goto_end(state); case XKB_KEY_f: return forward_char(state); case XKB_KEY_b: return backward_char(state); @@ -121,6 +122,7 @@ key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { case XKB_KEY_BackSpace: return kill_to_start(state); case XKB_KEY_Delete: return clear_input(state); } + return KEY_NO_REPEAT; } else if (alt) { switch (keysym) { @@ -128,7 +130,10 @@ key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { case XKB_KEY_BackSpace: return delete_word_backward(state); case XKB_KEY_f: return forward_word(state); case XKB_KEY_b: return backward_word(state); + case XKB_KEY_less: return select_first(state); + case XKB_KEY_greater: return select_last(state); } + return KEY_NO_REPEAT; } switch (keysym) { case XKB_KEY_Tab: return insert_selected(state); @@ -139,6 +144,10 @@ key_repeat_t type_key(client_state* state, xkb_keysym_t keysym) { case XKB_KEY_BackSpace: case XKB_KEY_Delete: return delete_char_backward(state); + case XKB_KEY_Down: return select_next(state); + case XKB_KEY_Up: return select_previous(state); + case XKB_KEY_Left: return backward_char_or_select_previous(state); + case XKB_KEY_Right: return forward_char_or_select_next(state); } // type char into buffer diff --git a/input_field.h b/input_field.h index 6ec588e..6c93f2a 100644 --- a/input_field.h +++ b/input_field.h @@ -5,8 +5,8 @@ #include "keybind.h" // returns true if the key should repeat -key_repeat_t type_key(client_state* state, xkb_keysym_t keysym); -void filter_items(client_state* state); +key_repeat_t execute_keypress(client_state* state, xkb_keysym_t keysym); +void refilter_items(client_state* state); void update_text_buffer(client_state* state); #endif @@ -56,6 +56,24 @@ key_repeat_t select_previous(client_state* state) { return KEY_REPEAT; } +key_repeat_t select_first(client_state* state) { + if (state->selected_filtered_item != -1) { + state->selected_filtered_item = 0; + rect_t prompt, input, options; + calculate_layout(state, &prompt, &input, &options, true, false); + } + return KEY_NO_REPEAT; +} + +key_repeat_t select_last(client_state* state) { + if (state->selected_filtered_item != -1) { + state->selected_filtered_item = array_size(state->filtered_items) - 1; + rect_t prompt, input, options; + calculate_layout(state, &prompt, &input, &options, true, false); + } + return KEY_NO_REPEAT; +} + key_repeat_t goto_end(client_state* state) { state->cursor_index = array_size(state->input_buffer); return KEY_NO_REPEAT; @@ -66,6 +84,16 @@ key_repeat_t goto_start(client_state* state) { return KEY_NO_REPEAT; } +key_repeat_t forward_char_or_select_next(client_state* state) { + if (state->cursor_index < array_size(state->input_buffer)) return forward_char(state); + else return select_next(state); +} + +key_repeat_t backward_char_or_select_previous(client_state* state) { + if (state->cursor_index > 0) return backward_char(state); + else return select_previous(state); +} + key_repeat_t forward_char(client_state* state) { if (state->cursor_index < array_size(state->input_buffer)) { state->cursor_index++; @@ -15,8 +15,11 @@ key_repeat_t submit_line(client_state* state); // options key_repeat_t select_next(client_state* state); key_repeat_t select_previous(client_state* state); -// select first -// select last +key_repeat_t select_first(client_state* state); +key_repeat_t select_last(client_state* state); + +key_repeat_t forward_char_or_select_next(client_state* state); +key_repeat_t backward_char_or_select_previous(client_state* state); // input key_repeat_t insert_selected(client_state* state); @@ -81,7 +81,7 @@ void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) { // if the key is one we should repeat - if (type_key(state, keysym)) { + if (execute_keypress(state, keysym) == KEY_REPEAT) { // start repeat state->repeat_key = keysym; struct itimerspec timer = {0}; @@ -106,7 +106,7 @@ int main(int argc, char* argv[]) { array_for_all(item_t, item, state.items) { init_text_buffer(&state, &item->text_buffer, item->text, strlen(item->text)); } - filter_items(&state); + refilter_items(&state); // event loop while (state.running) { @@ -166,7 +166,12 @@ void poll_events(client_state* state) { uint64_t repeats; if (read(state->key_repeat_timer_fd, &repeats, sizeof(repeats)) == 8) { for (uint64_t i = 0; i < repeats; i++) { - type_key(state, state->repeat_key); + if (execute_keypress(state, state->repeat_key) == KEY_NO_REPEAT) { + // stop key repeat if we shouldn't repeat anymore + struct itimerspec timer = {0}; + timerfd_settime(state->key_repeat_timer_fd, 0, &timer, NULL); + break; + } } event = true; } |
