Skip to content

Commit

Permalink
Merge pull request #572 from aginor/master
Browse files Browse the repository at this point in the history
Fix bug #24209 and add a global event context
  • Loading branch information
aginor committed Jan 1, 2016
2 parents 6c0ecb6 + 544b615 commit cb74629
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 15 deletions.
61 changes: 50 additions & 11 deletions src/events.cpp
Expand Up @@ -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
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;

} //end anon namespace
Expand Down Expand Up @@ -185,7 +189,12 @@ event_context::~event_context()

sdl_handler::~sdl_handler()
{
leave();
if (has_joined_)
leave();

if (has_joined_global_)
leave_global();

#if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_EnableUNICODE(unicode_);
#endif
Expand Down Expand Up @@ -227,6 +236,38 @@ void sdl_handler::leave()
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)
{
if(event_contexts.empty() == false) {
Expand Down Expand Up @@ -398,22 +439,14 @@ void pump()

case SDL_WINDOWEVENT_EXPOSED:
update_whole_screen();
if (display::get_singleton())
display::get_singleton()->redraw_everything();
break;

case SDL_WINDOWEVENT_RESIZED: {
case SDL_WINDOWEVENT_RESIZED:
info.resize_dimensions.first = event.window.data1;
info.resize_dimensions.second = event.window.data2;
break;
case SDL_WINDOWEVENT_MOVED:
case SDL_WINDOWEVENT_CLOSE:
break;
default:
if (display::get_singleton())
display::get_singleton()->redraw_everything();
}
}

break;
#else
case SDL_ACTIVEEVENT: {
Expand Down Expand Up @@ -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) {

const std::vector<sdl_handler*>& event_handlers = event_contexts.back().handlers;
Expand All @@ -510,6 +548,7 @@ void pump()
event_handlers[i1]->handle_event(event);
}
}

}

//inform the pump monitors that an events::pump() has occurred
Expand Down
4 changes: 4 additions & 0 deletions src/events.hpp
Expand Up @@ -55,6 +55,9 @@ class sdl_handler
virtual void join(); /*joins the current 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:
sdl_handler(const bool auto_join=true);
virtual ~sdl_handler();
Expand All @@ -68,6 +71,7 @@ class sdl_handler
int unicode_;
#endif
bool has_joined_;
bool has_joined_global_;
};

void focus_handler(const sdl_handler* ptr);
Expand Down
41 changes: 37 additions & 4 deletions src/video.cpp
Expand Up @@ -60,10 +60,7 @@ void resize_monitor::process(events::pump_info &info) {
}
}
#else
if(info.resize_dimensions.first > 0 &&
info.resize_dimensions.second > 0
&& display::get_singleton())
display::get_singleton()->redraw_everything();
UNUSED(info);
#endif
}

Expand Down Expand Up @@ -355,6 +352,41 @@ void update_whole_screen()
{
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) :
#ifdef SDL_GPU
shader_(),
Expand Down Expand Up @@ -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.
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());
event_handler_.join_global();
} else {
if(fullScreen) {
window->full_screen();
Expand Down
8 changes: 8 additions & 0 deletions src/video.hpp
Expand Up @@ -218,6 +218,12 @@ class CVideo : private boost::noncopyable {

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();
#ifdef SDL_GPU
void update_overlay(SDL_Rect *rect = NULL);
Expand All @@ -233,6 +239,8 @@ class CVideo : private boost::noncopyable {
//if there is no display at all, but we 'fake' it for clients
bool fake_screen_;

video_event_handler event_handler_;

//variables for help strings
int help_string_;

Expand Down

0 comments on commit cb74629

Please sign in to comment.