From 54e6bafada0f0b55246e208c3ffb85394756135f Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Wed, 18 Jul 2012 10:25:32 +0200 Subject: [PATCH] Fix missed buttons in action.c if action_wait_for_release() was called with no button pressed. If e.g. two yesno screens directly follow each other the button release of the first one was incorrectly accepted in the second one. The fix exposed another problem in action.c if action_wait_for_release() is called when no button is actually pressed. The next press was silently eaten. This time re-introducing FS#12723 is avoided by leaving the offending hunk out in yesno.c. Change-Id: Icfe57375067f51f5c8177f3585cd47ceec9dcf0d --- apps/action.c | 24 ++++++++++++++++++++++++ apps/gui/yesno.c | 6 ++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/apps/action.c b/apps/action.c index 5ebcbf771b..2492a7d08e 100644 --- a/apps/action.c +++ b/apps/action.c @@ -232,11 +232,30 @@ static int get_action_worker(int context, int timeout, /* Data from sys events can be pulled with button_get_data * multimedia button presses don't go through the action system */ if (button == BUTTON_NONE || button & (SYS_EVENT|BUTTON_MULTIMEDIA)) + { + /* no button pressed so no point in waiting for release */ + if (button == BUTTON_NONE) + wait_for_release = false; return button; + } + /* the special redraw button should result in a screen refresh */ if (button == BUTTON_REDRAW) return ACTION_REDRAW; + /* if action_wait_for_release() was called without a button being pressed + * then actually waiting for release would do the wrong thing, i.e. + * the next key press is entirely ignored. So, if here comes a normal + * button press (neither release nor repeat) the press is a fresh one and + * no point in waiting for release + * + * This logic doesn't work for touchscreen which can send normal + * button events repeatedly before the first repeat (as in BUTTON_REPEAT). + * These cannot be distinguished from the very first touch + * but there's nothing we can do about it here */ + if ((button & (BUTTON_REPEAT|BUTTON_REL)) == 0) + wait_for_release = false; + /* Don't send any buttons through untill we see the release event */ if (wait_for_release) { @@ -487,6 +506,11 @@ int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp /* Don't let get_action*() return any ACTION_* values until the current buttons * have been released. SYS_* and BUTTON_NONE will go through. * Any actions relying on _RELEASE won't get seen. + * + * Note this doesn't currently work for touchscreen targets if called + * when the screen isn't currently touched, because they can send normal + * (non-BUTTON_REPEAT) events repeatedly, if the touch coordinates change. + * This cannot be distinguished from normal buttons events. */ void action_wait_for_release(void) { diff --git a/apps/gui/yesno.c b/apps/gui/yesno.c index a2abae33ae..5ceba10a05 100644 --- a/apps/gui/yesno.c +++ b/apps/gui/yesno.c @@ -169,9 +169,10 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message, screens[i].stop_scroll(); gui_yesno_draw(&(yn[i])); } + /* make sure to eat any extranous keypresses */ - while (get_action(CONTEXT_STD+99, TIMEOUT_NOBLOCK)) - action_wait_for_release(); + action_wait_for_release(); + while (result==-1) { /* Repeat the question every 5secs (more or less) */ @@ -233,6 +234,7 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message, screens[i].scroll_stop(yn[i].vp); viewportmanager_theme_undo(i, true); } + return(result); }