From a39a3d22996b403dc1ca3ebe529a8470911d6944 Mon Sep 17 00:00:00 2001 From: Michael Mackus Date: Tue, 1 Nov 2016 20:12:51 -0700 Subject: [PATCH] Ensure all events are turned into input --- src/events.c | 32 ++++++++++++++++++++++++-------- src/events.h | 4 ++-- src/map.c | 26 +++++++++++--------------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/events.c b/src/events.c index 92debb7..311a6ed 100644 --- a/src/events.c +++ b/src/events.c @@ -14,7 +14,7 @@ void queue_event(GdkEventKey* e) { if (vb.mode->id != 'i') { /* events are only needed for input mode */ - return; + return free_events(); } GdkEventKey **newqueue = realloc(events.queue, (events.qlen + 1) * sizeof **newqueue); @@ -39,14 +39,32 @@ void queue_event(GdkEventKey* e) events.qlen ++; } +/** + * Free latest event & decrement qlen. + */ +void pop_event() +{ + if (events.qlen == 0) { + return; + } + + free(events.queue[events.qlen - 1]); + events.qlen --; +} + /** * Process events in the queue, sending the key events to GDK. */ -void process_events() +void process_events(bool is_timeout) { if (vb.mode->id != 'i') { /* events are only needed for input mode */ - return; + return free_events(); + } + + if (!is_timeout || events.qlen > 1) { + /* pop last event to prevent duplicate input */ + pop_event(); } events.processing = true; /* signal not to map our events */ @@ -55,10 +73,9 @@ void process_events() { GdkEventKey* event = events.queue[i]; gtk_main_do_event ((GdkEvent*) event); - gdk_event_free ((GdkEvent*) event); } - events.qlen = 0; + free_events(); events.processing = false; } @@ -75,12 +92,11 @@ bool is_processing_events() * Clear the event queue by resetting the length. Provided in order to * encapsulate the "events" global struct. */ -void clear_events() +void free_events() { for (int i = 0; i < events.qlen; ++i) { - GdkEventKey* event = events.queue[events.qlen]; - gdk_event_free ((GdkEvent*) event); + free(events.queue[i]); } events.qlen = 0; diff --git a/src/events.h b/src/events.h index 32d5889..ce58c33 100644 --- a/src/events.h +++ b/src/events.h @@ -7,8 +7,8 @@ #include "map.h" void queue_event(GdkEventKey* e); -void clear_events(); -void process_events(); +void free_events(); +void process_events(bool is_timeout); bool is_processing_events(); extern VbCore vb; diff --git a/src/map.c b/src/map.c index ade7e69..72734b7 100644 --- a/src/map.c +++ b/src/map.c @@ -175,20 +175,21 @@ gboolean map_keypress(GtkWidget *widget, GdkEventKey* event, gpointer data) vb.state.typed = true; vb.state.processed_key = true; + queue_event(event); + MapState res = map_handle_keys(string, len, true); /* reset the typed flag */ vb.state.typed = false; if (res == MAP_NOMATCH) { - /* consume any unprocessed events */ - process_events(); - } else if (res == MAP_AMBIGUOUS) { - /* queue event for later processing */ - queue_event(event); - } else if (res == MAP_DONE) { - /* we're done - clear events */ - clear_events(); + if (!vb.state.processed_key) { + /* consume any unprocessed events */ + process_events(false); + } else { + /* we're done - clear events */ + free_events(); + } } return vb.state.processed_key; @@ -669,13 +670,8 @@ static gboolean do_timeout(gpointer data) /* signalize the timeout to the key handler */ MapState res = map_handle_keys((guchar*)"", 0, true); - if (res == MAP_DONE) { - /* we're done - clear events */ - clear_events(); - } else { - /* consume any unprocessed events */ - process_events(); - } + /* consume any unprocessed events */ + process_events(true); /* we return true to not automatically remove the resource - this is * required to prevent critical error when we remove the source in -- 2.20.1