diff --git a/changelog b/changelog index 789f3ab18f8..8bf8d5c4c06 100644 --- a/changelog +++ b/changelog @@ -144,7 +144,7 @@ Version 1.3-svn: * fix the completion when controlling multiple sides (bug #8101, patch #653) * smarter focus handling when user input is irrelevant to the current focus but relevant to another widget - * fix (partially) the "keylogger" effect when joining the MP Lobby + * fix the "keylogger" effect when joining the MP Lobby * menus can now stay scrolled to the bottom if they were already scrolled to the bottom * friends list diff --git a/src/events.cpp b/src/events.cpp index c762d8e2b3b..9d1a250f813 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -17,6 +17,7 @@ #include "cursor.hpp" #include "events.hpp" #include "gp2x.hpp" +#include "log.hpp" #include "preferences_display.hpp" #include "sound.hpp" #include "video.hpp" @@ -29,6 +30,11 @@ #include #include +#define ERR_GEN LOG_STREAM(err, general) + + +unsigned input_blocker::instance_count = 0; //static initialization + namespace events { @@ -272,10 +278,17 @@ void pump() switch(event.type) { - case SDL_APPMOUSEFOCUS: { + case SDL_ACTIVEEVENT: { SDL_ActiveEvent& ae = reinterpret_cast(event); - if(ae.state == SDL_APPMOUSEFOCUS || ae.state == SDL_APPINPUTFOCUS) { - cursor::set_focus(ae.gain == 1); + if((ae.state & SDL_APPMOUSEFOCUS) != 0 || (ae.state & SDL_APPINPUTFOCUS) != 0) { + cursor::set_focus(ae.gain != 0); + events::flush( SDL_EVENTMASK(SDL_KEYDOWN)| + SDL_EVENTMASK(SDL_KEYUP)| + SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)| + SDL_EVENTMASK(SDL_MOUSEBUTTONUP)| + SDL_EVENTMASK(SDL_JOYBUTTONDOWN)| + SDL_EVENTMASK(SDL_JOYBUTTONUP) + ); } break; } @@ -446,4 +459,29 @@ void raise_help_string_event(int mousex, int mousey) } } +int flush(Uint32 event_mask) +{ + int flush_count = 0; + SDL_Event temp_event; + std::vector< SDL_Event > keepers; + SDL_Delay(10); + while(SDL_PollEvent(&temp_event) > 0) { + if((SDL_EVENTMASK(temp_event.type) & event_mask) == 0) { + keepers.push_back( temp_event ); + } else { + ++flush_count; + } + } + + //FIXME: there is a chance new events are added before kept events are replaced + std::vector::iterator itor; + for(itor = keepers.begin(); itor != keepers.end(); ++itor) + { + if(SDL_PushEvent(itor) != 0) { + ERR_GEN << "failed to return an event to the queue."; + } + } + return flush_count; +} + } diff --git a/src/events.hpp b/src/events.hpp index b67d3c48173..0c2966665d2 100644 --- a/src/events.hpp +++ b/src/events.hpp @@ -86,6 +86,7 @@ struct event_context //causes events to be dispatched to all handler objects. void pump(); +int flush(Uint32 event_mask=SDL_ALLEVENTS); void raise_process_event(); void raise_draw_event(); @@ -96,4 +97,39 @@ void raise_help_string_event(int mousex, int mousey); typedef std::vector handler_vector; +struct input_blocker +{ + static unsigned instance_count; + input_blocker() + { + SDL_EventState(SDL_KEYDOWN, SDL_IGNORE); + SDL_EventState(SDL_KEYUP, SDL_IGNORE); + SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE); + SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE); + SDL_EventState(SDL_JOYBUTTONDOWN, SDL_IGNORE); + SDL_EventState(SDL_JOYBUTTONUP, SDL_IGNORE); + instance_count++; + } + + ~input_blocker() + { + instance_count--; + if(instance_count == 0) { + events::flush( SDL_EVENTMASK(SDL_KEYDOWN)| + SDL_EVENTMASK(SDL_KEYUP)| + SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)| + SDL_EVENTMASK(SDL_MOUSEBUTTONUP)| + SDL_EVENTMASK(SDL_JOYBUTTONDOWN)| + SDL_EVENTMASK(SDL_JOYBUTTONUP) + ); + SDL_EventState(SDL_KEYDOWN, SDL_ENABLE); + SDL_EventState(SDL_KEYUP, SDL_ENABLE); + SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE); + SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE); + SDL_EventState(SDL_JOYBUTTONDOWN, SDL_ENABLE); + SDL_EventState(SDL_JOYBUTTONUP, SDL_ENABLE); + } + } +}; + #endif diff --git a/src/sdl_utils.cpp b/src/sdl_utils.cpp index 0f5416f6c7f..02c52699470 100644 --- a/src/sdl_utils.cpp +++ b/src/sdl_utils.cpp @@ -25,8 +25,6 @@ #include #include -unsigned input_blocker::instance_count = 0; //static initialization - SDLKey sdl_keysym_from_name(std::string const &keyname) { static bool initialized = false; diff --git a/src/sdl_utils.hpp b/src/sdl_utils.hpp index 3554178c9d1..526968cc6db 100644 --- a/src/sdl_utils.hpp +++ b/src/sdl_utils.hpp @@ -167,34 +167,6 @@ struct pixel_data int r, g, b; }; -struct input_blocker -{ - static unsigned instance_count; - input_blocker() - { - SDL_EventState(SDL_KEYDOWN, SDL_IGNORE); - SDL_EventState(SDL_KEYUP, SDL_IGNORE); - SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE); - SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE); - SDL_EventState(SDL_JOYBUTTONDOWN, SDL_IGNORE); - SDL_EventState(SDL_JOYBUTTONUP, SDL_IGNORE); - instance_count++; - } - - ~input_blocker() - { - instance_count--; - if(instance_count == 0) { - SDL_EventState(SDL_KEYDOWN, SDL_ENABLE); - SDL_EventState(SDL_KEYUP, SDL_ENABLE); - SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE); - SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE); - SDL_EventState(SDL_JOYBUTTONDOWN, SDL_ENABLE); - SDL_EventState(SDL_JOYBUTTONUP, SDL_ENABLE); - } - } -}; - struct surface_lock { surface_lock(surface const &surf) : surface_(surf), locked_(false)