ltk

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltk.git (fast, but not encrypted)
git clone https://lumidify.org/ltk.git (encrypted, but very slow)
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltk.git (over tor)
Log | Files | Refs | README | LICENSE

commit 9b2b4596605e6594a2538f6b3bce3ffd9e90c652
parent 5a0a7594e75569bc17cc48a0ec0e5975ec51d54d
Author: lumidify <nobody@lumidify.org>
Date:   Fri, 10 May 2024 17:59:26 +0200

Move keypress/keyrelease handling to separate functions

Diffstat:
Msrc/ltk/combobox.c | 19+++----------------
Msrc/ltk/entry.c | 55+++++++++++++++++++++----------------------------------
Msrc/ltk/label.c | 2+-
Msrc/ltk/label.h | 1-
Msrc/ltk/menu.c | 1+
Msrc/ltk/menu.h | 1-
Msrc/ltk/scrollbar.c | 2++
Msrc/ltk/scrollbar.h | 1-
Msrc/ltk/widget.c | 41+++++++++++++++++++++++++++++++++++++++++
Msrc/ltk/widget_internal.h | 3+++
Msrc/ltk/window.c | 31++++---------------------------
Msrc/ltk/window.h | 2--
12 files changed, 76 insertions(+), 83 deletions(-)

diff --git a/src/ltk/combobox.c b/src/ltk/combobox.c @@ -373,7 +373,7 @@ choose_external(ltk_widget *self, ltk_key_event *event) { (void)event; ltk_combobox *combo = LTK_CAST_COMBOBOX(self); if (!combo->dropdown || ltk_menu_get_num_entries(combo->dropdown) == 0) - return 0; + return 1; ltk_general_config *config = ltk_config_get_general(); /* FIXME: allow arguments to key mappings - this would allow to have different key mappings for different editors instead of just one command */ @@ -390,25 +390,12 @@ choose_external(ltk_widget *self, ltk_key_event *event) { ltk_call_cmd(self, config->option_chooser, txtbuf_get_text(tmpbuf), txtbuf_len(tmpbuf)); txtbuf_destroy(tmpbuf); } - return 0; + return 1; } static int ltk_combobox_key_press(ltk_widget *self, ltk_key_event *event) { - ltk_keypress_binding b; - for (size_t i = 0; i < ltk_array_len(keypresses); i++) { - b = ltk_array_get(keypresses, i).b; - if ((b.mods == event->modmask && b.sym != LTK_KEY_NONE && b.sym == event->sym) || - (b.mods == (event->modmask & ~LTK_MOD_SHIFT) && - ((b.text && event->mapped && !strcmp(b.text, event->mapped)) || - (b.rawtext && event->text && !strcmp(b.rawtext, event->text))))) { - ltk_array_get(keypresses, i).cb.func(self, event); - self->dirty = 1; - ltk_window_invalidate_widget_rect(self->window, self); - return 1; - } - } - return 0; + return ltk_widget_handle_keypress_bindings(self, event, keypresses, 0); } const char * diff --git a/src/ltk/entry.c b/src/ltk/entry.c @@ -300,7 +300,7 @@ cursor_to_beginning(ltk_widget *self, ltk_key_event *event) { wipe_selection(entry); entry->pos = 0; ensure_cursor_shown(entry); - return 0; + return 1; } static int @@ -310,7 +310,7 @@ cursor_to_end(ltk_widget *self, ltk_key_event *event) { wipe_selection(entry); entry->pos = entry->len; ensure_cursor_shown(entry); - return 0; + return 1; } static int @@ -323,7 +323,7 @@ cursor_left(ltk_widget *self, ltk_key_event *event) { entry->pos = ltk_text_line_move_cursor_visually(entry->tl, entry->pos, -1, NULL); wipe_selection(entry); ensure_cursor_shown(entry); - return 0; + return 1; } static int @@ -336,7 +336,7 @@ cursor_right(ltk_widget *self, ltk_key_event *event) { entry->pos = ltk_text_line_move_cursor_visually(entry->tl, entry->pos, 1, NULL); wipe_selection(entry); ensure_cursor_shown(entry); - return 0; + return 1; } static void @@ -368,12 +368,12 @@ selection_to_primary(ltk_widget *self, ltk_key_event *event) { (void)event; ltk_entry *entry = LTK_CAST_ENTRY(self); if (entry->sel_end == entry->sel_start) - return 0; + return 1; txtbuf *primary = ltk_clipboard_get_primary_buffer(ltk_get_clipboard()); txtbuf_clear(primary); txtbuf_appendn(primary, entry->text + entry->sel_start, entry->sel_end - entry->sel_start); ltk_clipboard_set_primary_selection_owner(ltk_get_clipboard()); - return 0; + return 1; } static int @@ -381,12 +381,12 @@ selection_to_clipboard(ltk_widget *self, ltk_key_event *event) { (void)event; ltk_entry *entry = LTK_CAST_ENTRY(self); if (entry->sel_end == entry->sel_start) - return 0; + return 1; txtbuf *clip = ltk_clipboard_get_clipboard_buffer(ltk_get_clipboard()); txtbuf_clear(clip); txtbuf_appendn(clip, entry->text + entry->sel_start, entry->sel_end - entry->sel_start); ltk_clipboard_set_clipboard_selection_owner(ltk_get_clipboard()); - return 0; + return 1; } static int @@ -394,7 +394,7 @@ switch_selection_side(ltk_widget *self, ltk_key_event *event) { (void)event; ltk_entry *entry = LTK_CAST_ENTRY(self); entry->sel_side = !entry->sel_side; - return 0; + return 1; } static int @@ -404,7 +404,7 @@ paste_primary(ltk_widget *self, ltk_key_event *event) { txtbuf *buf = ltk_clipboard_get_primary_text(ltk_get_clipboard()); if (buf) insert_text(entry, buf->text, buf->len, 1); - return 0; + return 1; } static int @@ -414,7 +414,7 @@ paste_clipboard(ltk_widget *self, ltk_key_event *event) { txtbuf *buf = ltk_clipboard_get_clipboard_text(ltk_get_clipboard()); if (buf) insert_text(entry, buf->text, buf->len, 1); - return 0; + return 1; } static int @@ -422,7 +422,7 @@ expand_selection_left(ltk_widget *self, ltk_key_event *event) { (void)event; ltk_entry *entry = LTK_CAST_ENTRY(self); expand_selection(entry, -1); - return 0; + return 1; } static int @@ -430,7 +430,7 @@ expand_selection_right(ltk_widget *self, ltk_key_event *event) { (void)event; ltk_entry *entry = LTK_CAST_ENTRY(self); expand_selection(entry, 1); - return 0; + return 1; } static void @@ -457,7 +457,7 @@ delete_char_backwards(ltk_widget *self, ltk_key_event *event) { size_t new = prev_utf8(entry->text, entry->pos); delete_text(entry, new, entry->pos); } - return 0; + return 1; } static int @@ -470,7 +470,7 @@ delete_char_forwards(ltk_widget *self, ltk_key_event *event) { size_t new = next_utf8(entry->text, entry->len, entry->pos); delete_text(entry, entry->pos, new); } - return 0; + return 1; } static int @@ -481,7 +481,7 @@ select_all(ltk_widget *self, ltk_key_event *event) { if (entry->len) selection_to_primary(LTK_CAST_WIDGET(entry), NULL); entry->sel_side = 0; - return 0; + return 1; } static void @@ -580,29 +580,16 @@ edit_external(ltk_widget *self, ltk_key_event *event) { /* FIXME: change interface to not require length of cmd */ ltk_call_cmd(LTK_CAST_WIDGET(entry), config->line_editor, entry->text, entry->len); } - return 0; + return 1; } -/* FIXME: return values of callbacks are currently ignored - could this be used for anything useful? */ -/* -> maybe if multiple bindings are configured for the same key? */ static int ltk_entry_key_press(ltk_widget *self, ltk_key_event *event) { ltk_entry *entry = LTK_CAST_ENTRY(self); - ltk_keypress_binding b; - for (size_t i = 0; i < ltk_array_len(keypresses); i++) { - b = ltk_array_get(keypresses, i).b; - /* FIXME: change naming (rawtext, text, mapped...) */ - /* FIXME: a bit weird to mask out shift, but if that isn't done, it - would need to be included for all mappings with capital letters */ - if ((b.mods == event->modmask && b.sym != LTK_KEY_NONE && b.sym == event->sym) || - (b.mods == (event->modmask & ~LTK_MOD_SHIFT) && - ((b.text && event->mapped && !strcmp(b.text, event->mapped)) || - (b.rawtext && event->text && !strcmp(b.rawtext, event->text))))) { - ltk_array_get(keypresses, i).cb.func(LTK_CAST_WIDGET(entry), event); - self->dirty = 1; - ltk_window_invalidate_widget_rect(self->window, self); - return 1; - } + if (ltk_widget_handle_keypress_bindings(self, event, keypresses, 0)) { + self->dirty = 1; + ltk_window_invalidate_widget_rect(self->window, self); + return 1; } if (event->text && (event->modmask & (LTK_MOD_CTRL | LTK_MOD_ALT | LTK_MOD_SUPER)) == 0) { /* FIXME: properly handle everything */ diff --git a/src/ltk/label.c b/src/ltk/label.c @@ -15,8 +15,8 @@ */ #include <stddef.h> -#include <stdint.h> +#include "config.h" #include "memory.h" #include "color.h" #include "rect.h" diff --git a/src/ltk/label.h b/src/ltk/label.h @@ -18,7 +18,6 @@ #define LTK_LABEL_H #include "text.h" -#include "graphics.h" #include "widget.h" #include "window.h" diff --git a/src/ltk/menu.c b/src/ltk/menu.c @@ -26,6 +26,7 @@ #include <limits.h> #include "event.h" +#include "config.h" #include "memory.h" #include "color.h" #include "rect.h" diff --git a/src/ltk/menu.h b/src/ltk/menu.h @@ -19,7 +19,6 @@ #include <stddef.h> -#include "graphics.h" #include "text.h" #include "widget.h" #include "window.h" diff --git a/src/ltk/scrollbar.c b/src/ltk/scrollbar.c @@ -17,11 +17,13 @@ #include <stddef.h> #include "event.h" +#include "config.h" #include "memory.h" #include "color.h" #include "rect.h" #include "widget.h" #include "util.h" +#include "graphics.h" #include "scrollbar.h" #include "eventdefs.h" diff --git a/src/ltk/scrollbar.h b/src/ltk/scrollbar.h @@ -17,7 +17,6 @@ #ifndef LTK_SCROLLBAR_H #define LTK_SCROLLBAR_H -#include "graphics.h" #include "widget.h" #include "window.h" diff --git a/src/ltk/widget.c b/src/ltk/widget.c @@ -14,13 +14,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <stddef.h> #include <string.h> #include "rect.h" +#include "config.h" #include "widget.h" #include "window.h" #include "memory.h" #include "array.h" +#include "eventdefs.h" LTK_ARRAY_INIT_FUNC_DECL_STATIC(signal, ltk_signal_callback_info) LTK_ARRAY_INIT_IMPL_STATIC(signal, ltk_signal_callback_info) @@ -309,3 +312,41 @@ ltk_widget_recalc_ideal_size(ltk_widget *widget) { if (widget->vtable->recalc_ideal_size) widget->vtable->recalc_ideal_size(widget); } + +int +ltk_widget_handle_keypress_bindings(ltk_widget *widget, ltk_key_event *event, ltk_array(keypress) *keypresses, int handled) { + if (!keypresses) + return 0; + ltk_keypress_binding *b; + for (size_t i = 0; i < ltk_array_len(keypresses); i++) { + b = &ltk_array_get(keypresses, i).b; + if ((!(b->flags & LTK_KEY_BINDING_RUN_ALWAYS) && handled)) + continue; + /* FIXME: change naming (rawtext, text, mapped...) */ + /* FIXME: a bit weird to mask out shift, but if that isn't done, it + would need to be included for all mappings with capital letters */ + if ((b->mods == event->modmask && b->sym != LTK_KEY_NONE && b->sym == event->sym) || + (b->mods == (event->modmask & ~LTK_MOD_SHIFT) && + ((b->text && event->mapped && !strcmp(b->text, event->mapped)) || + (b->rawtext && event->text && !strcmp(b->rawtext, event->text))))) { + handled |= ltk_array_get(keypresses, i).cb.func(widget, event); + } + } + return handled; +} + +int +ltk_widget_handle_keyrelease_bindings(ltk_widget *widget, ltk_key_event *event, ltk_array(keyrelease) *keyreleases, int handled) { + if (!keyreleases) + return 0; + ltk_keyrelease_binding *b = NULL; + for (size_t i = 0; i < ltk_array_len(keyreleases); i++) { + b = &ltk_array_get(keyreleases, i).b; + if (b->mods != event->modmask || (!(b->flags & LTK_KEY_BINDING_RUN_ALWAYS) && handled)) { + continue; + } else if (b->sym != LTK_KEY_NONE && event->sym == b->sym) { + handled |= ltk_array_get(keyreleases, i).cb.func(widget, event); + } + } + return handled; +} diff --git a/src/ltk/widget_internal.h b/src/ltk/widget_internal.h @@ -66,4 +66,7 @@ void ltk_window_get_keybinding_parseinfo( -> first option maybe just set callback, etc. of current cmd to NULL so widget can still be destroyed */ int ltk_call_cmd(ltk_widget *caller, ltk_array(cmd) *cmd, const char *text, size_t textlen); +int ltk_widget_handle_keypress_bindings(ltk_widget *widget, ltk_key_event *event, ltk_array(keypress) *keypresses, int handled); +int ltk_widget_handle_keyrelease_bindings(ltk_widget *widget, ltk_key_event *event, ltk_array(keyrelease) *keyreleases, int handled); + #endif /* LTK_WIDGET_INTERNAL_H */ diff --git a/src/ltk/window.c b/src/ltk/window.c @@ -15,18 +15,19 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <stdlib.h> #include <string.h> #include <math.h> #include "ltk.h" #include "util.h" +#include "color.h" #include "array.h" #include "widget.h" #include "window.h" #include "memory.h" #include "config.h" #include "eventdefs.h" +#include "widget_internal.h" #define MAX_WINDOW_FONT_SIZE 20000 @@ -190,21 +191,7 @@ ltk_window_key_press_event(ltk_widget *self, ltk_key_event *event) { } } } - if (!keypresses) - return 1; - ltk_keypress_binding *b = NULL; - /* FIXME: move into separate function and share between window, entry, etc. */ - for (size_t i = 0; i < ltk_array_len(keypresses); i++) { - b = &ltk_array_get(keypresses, i).b; - if ((!(b->flags & LTK_KEY_BINDING_RUN_ALWAYS) && handled)) - continue; - if ((b->mods == event->modmask && b->sym != LTK_KEY_NONE && b->sym == event->sym) || - (b->mods == (event->modmask & ~LTK_MOD_SHIFT) && - ((b->text && event->mapped && !strcmp(b->text, event->mapped)) || - (b->rawtext && event->text && !strcmp(b->rawtext, event->text))))) { - handled |= ltk_array_get(keypresses, i).cb.func(LTK_CAST_WIDGET(window), event); - } - } + ltk_widget_handle_keypress_bindings(self, event, keypresses, handled); return 1; } @@ -224,17 +211,7 @@ ltk_window_key_release_event(ltk_widget *self, ltk_key_event *event) { } } } - if (!keyreleases) - return 1; - ltk_keyrelease_binding *b = NULL; - for (size_t i = 0; i < ltk_array_len(keyreleases); i++) { - b = &ltk_array_get(keyreleases, i).b; - if (b->mods != event->modmask || (!(b->flags & LTK_KEY_BINDING_RUN_ALWAYS) && handled)) { - continue; - } else if (b->sym != LTK_KEY_NONE && event->sym == b->sym) { - handled |= ltk_array_get(keyreleases, i).cb.func(LTK_CAST_WIDGET(window), event); - } - } + ltk_widget_handle_keyrelease_bindings(self, event, keyreleases, handled); return 1; } diff --git a/src/ltk/window.h b/src/ltk/window.h @@ -18,8 +18,6 @@ #define LTK_WINDOW_H #include <stddef.h> -#include "color.h" -#include "config.h" #include "event.h" #include "graphics.h" #include "rect.h"