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:
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 = <k_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 = <k_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 = <k_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 = <k_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"