From b1f7fe555c5a7d30b03398f6f3c23675e568e3ac Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Sat, 16 Feb 2019 14:35:27 +0000 Subject: 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 --- src/imv.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'src/imv.c') 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); -- cgit v1.2.3