Merge pull request #572 from aginor/master

Fix bug #24209 and add a global event context
This commit is contained in:
Andreas 2016-01-01 20:02:49 +13:00
commit cb74629a88
4 changed files with 99 additions and 15 deletions

View file

@ -141,6 +141,10 @@ void context::set_focus(const sdl_handler* ptr)
//in that context. The current context is the one on the top of the stack //in that context. The current context is the one on the top of the stack
std::deque<context> event_contexts; std::deque<context> event_contexts;
//add a global context for event handlers. Whichever object has joined this will always
//receive all events, regardless of the current context.
context global_context;
std::vector<pump_monitor*> pump_monitors; std::vector<pump_monitor*> pump_monitors;
} //end anon namespace } //end anon namespace
@ -185,7 +189,12 @@ event_context::~event_context()
sdl_handler::~sdl_handler() sdl_handler::~sdl_handler()
{ {
if (has_joined_)
leave(); leave();
if (has_joined_global_)
leave_global();
#if !SDL_VERSION_ATLEAST(2, 0, 0) #if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_EnableUNICODE(unicode_); SDL_EnableUNICODE(unicode_);
#endif #endif
@ -227,6 +236,38 @@ void sdl_handler::leave()
has_joined_ = false; has_joined_ = false;
} }
void sdl_handler::join_global()
{
if(has_joined_global_) {
leave_global(); // should not be in multiple event contexts
}
//join self
global_context.add_handler(this);
has_joined_global_ = true;
//instruct members to join
sdl_handler_vector members = handler_members();
if(!members.empty()) {
for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
(*i)->join_global();
}
}
}
void sdl_handler::leave_global()
{
sdl_handler_vector members = handler_members();
if(!members.empty()) {
for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
(*i)->leave_global();
}
}
global_context.remove_handler(this);
has_joined_global_ = false;
}
void focus_handler(const sdl_handler* ptr) void focus_handler(const sdl_handler* ptr)
{ {
if(event_contexts.empty() == false) { if(event_contexts.empty() == false) {
@ -398,22 +439,14 @@ void pump()
case SDL_WINDOWEVENT_EXPOSED: case SDL_WINDOWEVENT_EXPOSED:
update_whole_screen(); update_whole_screen();
if (display::get_singleton())
display::get_singleton()->redraw_everything();
break; break;
case SDL_WINDOWEVENT_RESIZED: { case SDL_WINDOWEVENT_RESIZED:
info.resize_dimensions.first = event.window.data1; info.resize_dimensions.first = event.window.data1;
info.resize_dimensions.second = event.window.data2; info.resize_dimensions.second = event.window.data2;
break; break;
case SDL_WINDOWEVENT_MOVED:
case SDL_WINDOWEVENT_CLOSE:
break;
default:
if (display::get_singleton())
display::get_singleton()->redraw_everything();
}
} }
break; break;
#else #else
case SDL_ACTIVEEVENT: { case SDL_ACTIVEEVENT: {
@ -500,6 +533,11 @@ void pump()
} }
} }
const std::vector<sdl_handler*>& event_handlers = global_context.handlers;
for(size_t i1 = 0, i2 = event_handlers.size(); i1 != i2 && i1 < event_handlers.size(); ++i1) {
event_handlers[i1]->handle_event(event);
}
if(event_contexts.empty() == false) { if(event_contexts.empty() == false) {
const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers; const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
@ -510,6 +548,7 @@ void pump()
event_handlers[i1]->handle_event(event); event_handlers[i1]->handle_event(event);
} }
} }
} }
//inform the pump monitors that an events::pump() has occurred //inform the pump monitors that an events::pump() has occurred

View file

@ -55,6 +55,9 @@ public:
virtual void join(); /*joins the current event context*/ virtual void join(); /*joins the current event context*/
virtual void leave(); /*leave the event context*/ virtual void leave(); /*leave the event context*/
virtual void join_global(); /*join the global event context*/
virtual void leave_global(); /*leave the global event context*/
protected: protected:
sdl_handler(const bool auto_join=true); sdl_handler(const bool auto_join=true);
virtual ~sdl_handler(); virtual ~sdl_handler();
@ -68,6 +71,7 @@ private:
int unicode_; int unicode_;
#endif #endif
bool has_joined_; bool has_joined_;
bool has_joined_global_;
}; };
void focus_handler(const sdl_handler* ptr); void focus_handler(const sdl_handler* ptr);

View file

@ -60,10 +60,7 @@ void resize_monitor::process(events::pump_info &info) {
} }
} }
#else #else
if(info.resize_dimensions.first > 0 && UNUSED(info);
info.resize_dimensions.second > 0
&& display::get_singleton())
display::get_singleton()->redraw_everything();
#endif #endif
} }
@ -355,6 +352,41 @@ void update_whole_screen()
{ {
update_all = true; update_all = true;
} }
void CVideo::video_event_handler::handle_event(const SDL_Event &event)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (event.type == SDL_WINDOWEVENT) {
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
case SDL_WINDOWEVENT_RESTORED:
case SDL_WINDOWEVENT_SHOWN:
case SDL_WINDOWEVENT_EXPOSED:
if (display::get_singleton())
display::get_singleton()->redraw_everything();
break;
#if !SDL_VERSION_ATLEAST(2, 0, 4) && defined(_WIN32)
case SDL_WINDOWEVENT_FOCUS_GAINED:
if(SDL_GetWindowFlags(*window) & SDL_WINDOW_MAXIMIZED) {
SDL_RestoreWindow(*window);
SDL_MaximizeWindow(*window);
}
if(SDL_GetWindowFlags(*window) & SDL_WINDOW_FULLSCREEN_DESKTOP) {
SDL_RestoreWindow(*window);
SDL_SetWindowFullscreen(*window, SDL_WINDOW_FULLSCREEN_DESKTOP);
}
break;
#endif
}
}
#else
UNUSED(event);
#endif
}
CVideo::CVideo(FAKE_TYPES type) : CVideo::CVideo(FAKE_TYPES type) :
#ifdef SDL_GPU #ifdef SDL_GPU
shader_(), shader_(),
@ -581,6 +613,7 @@ int CVideo::setMode( int x, int y, int bits_per_pixel, int flags )
// Note that x and y in this particular case refer to width and height of the window, not co-ordinates. // Note that x and y in this particular case refer to width and height of the window, not co-ordinates.
window = new sdl::twindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, x, y, flags, SDL_RENDERER_SOFTWARE); window = new sdl::twindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, x, y, flags, SDL_RENDERER_SOFTWARE);
window->set_minimum_size(preferences::min_allowed_width(), preferences::min_allowed_height()); window->set_minimum_size(preferences::min_allowed_width(), preferences::min_allowed_height());
event_handler_.join_global();
} else { } else {
if(fullScreen) { if(fullScreen) {
window->full_screen(); window->full_screen();

View file

@ -218,6 +218,12 @@ class CVideo : private boost::noncopyable {
private: private:
class video_event_handler : public events::sdl_handler {
public:
virtual void handle_event(const SDL_Event &event);
video_event_handler() : sdl_handler(false) {}
};
void initSDL(); void initSDL();
#ifdef SDL_GPU #ifdef SDL_GPU
void update_overlay(SDL_Rect *rect = NULL); void update_overlay(SDL_Rect *rect = NULL);
@ -233,6 +239,8 @@ private:
//if there is no display at all, but we 'fake' it for clients //if there is no display at all, but we 'fake' it for clients
bool fake_screen_; bool fake_screen_;
video_event_handler event_handler_;
//variables for help strings //variables for help strings
int help_string_; int help_string_;