aboutsummaryrefslogtreecommitdiff
path: root/src/imv.c
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-02-16 14:35:27 +0000
committerHarry Jeffery <harry@exec64.co.uk>2019-02-16 14:35:27 +0000
commitb1f7fe555c5a7d30b03398f6f3c23675e568e3ac (patch)
treeba3c1ec2a353919dad8b029e9e464705008999a9 /src/imv.c
parent8323dfc6fca584c77abd22b03bce7af8996ab218 (diff)
downloadimv-b1f7fe555c5a7d30b03398f6f3c23675e568e3ac.tar.gz
Fix truncated path list from stdin
It turns out, the paths from stdin weren't being truncated. The issue was with the use of the SDL event queue for passing the paths back to imv's main thread. The events were being pushed correctly, but due to a workaround for a bug in SDL, instead of flushing the contents of the event queue, we now ignore window events until all events already in the queue have been handled. This fixes #141
Diffstat (limited to 'src/imv.c')
-rw-r--r--src/imv.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/imv.c b/src/imv.c
index de9a9f7..2af5878 100644
--- a/src/imv.c
+++ b/src/imv.c
@@ -128,6 +128,12 @@ struct imv {
char *title_text;
char *overlay_text;
+ /* when true, imv will ignore all window events until it encounters a
+ * ENABLE_INPUT user-event. This is required to overcome a bug where
+ * SDL will send input events to us from before we gained focus
+ */
+ bool ignore_window_events;
+
/* imv subsystems */
struct imv_binds *binds;
struct imv_navigator *navigator;
@@ -153,6 +159,7 @@ struct imv {
unsigned int NEW_IMAGE;
unsigned int BAD_IMAGE;
unsigned int NEW_PATH;
+ unsigned int ENABLE_INPUT;
} events;
struct {
int width;
@@ -911,6 +918,7 @@ static bool setup_window(struct imv *imv)
imv->events.NEW_IMAGE = SDL_RegisterEvents(1);
imv->events.BAD_IMAGE = SDL_RegisterEvents(1);
imv->events.NEW_PATH = SDL_RegisterEvents(1);
+ imv->events.ENABLE_INPUT = SDL_RegisterEvents(1);
imv->sdl_init = true;
@@ -1026,10 +1034,20 @@ static void handle_event(struct imv *imv, SDL_Event *event)
}
imv_navigator_remove(imv->navigator, err_path);
+ return;
} else if (event->type == imv->events.NEW_PATH) {
/* received a new path from the stdin reading thread */
imv_add_path(imv, event->user.data1);
free(event->user.data1);
+ /* need to update image count */
+ imv->need_redraw = true;
+ return;
+ } else if (event->type == imv->events.ENABLE_INPUT) {
+ imv->ignore_window_events = false;
+ return;
+ } else if (imv->ignore_window_events) {
+ /* Don't try and process this input event, we're in event ignoring mode */
+ return;
}
switch (event->type) {
@@ -1102,12 +1120,17 @@ static void handle_event(struct imv *imv, SDL_Event *event)
/* For some reason SDL passes events to us that occurred before we
* gained focus, and passes them *after* the focus gained event.
* Due to behavioural quirks from such events, whenever we gain focus
- * we have to clear the event queue. It's hacky, but works without
- * any visible side effects.
+ * we have to ignore all window events already in the queue.
*/
if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
- SDL_PumpEvents();
- SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
+ /* disable window event handling */
+ imv->ignore_window_events = true;
+ /* push an event to the back of the event queue to re-enable
+ * window event handling */
+ SDL_Event event;
+ SDL_zero(event);
+ event.type = imv->events.ENABLE_INPUT;
+ SDL_PushEvent(&event);
}
imv_viewport_update(imv->view, imv->image);