Skip to content

Instantly share code, notes, and snippets.

@jyrkive
Created July 7, 2018 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jyrkive/ca524d26010cddf00076c2c18f829dff to your computer and use it in GitHub Desktop.
Save jyrkive/ca524d26010cddf00076c2c18f829dff to your computer and use it in GitHub Desktop.
From 5d8b4f7987c8fca0e042021a61ce5c8086da3544 Mon Sep 17 00:00:00 2001
From: Jyrki Vesterinen <sandgtx@gmail.com>
Date: Sat, 7 Jul 2018 09:50:49 +0300
Subject: [PATCH] Experimental fixes for the crash when a modeless dialog
destroys itself
This commit fixes the crashes, but I'm not convinced that one of the fixes
is correct.
Setting `handled` and `halt` to true in
gui2::event::distributor::signal_handler_sdl_key_down() also means that no
one else can process the event after the event distributor. Maybe it should
be at least conditional, depending on whether the event dispatcher has
self-destructed.
---
src/events.cpp | 5 ++++-
src/gui/core/event/distributor.cpp | 8 +++++---
src/gui/core/event/distributor.hpp | 4 +++-
src/gui/dialogs/command_console.cpp | 7 +++++--
src/gui/dialogs/command_console.hpp | 2 +-
5 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/src/events.cpp b/src/events.cpp
index c882421c05..d55237e9b7 100644
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -612,7 +612,10 @@ void run_event_loop()
}
if(event_contexts.size() > 1) {
- for(auto handler : event_contexts.back().handlers) {
+ // Copy the list of handlers, in case a handler destroys itself during this loop.
+ std::vector<sdl_handler*> handlers(event_contexts.back().handlers.begin(),
+ event_contexts.back().handlers.end());
+ for(auto handler : handlers) {
handler->handle_event(event);
}
}
diff --git a/src/gui/core/event/distributor.cpp b/src/gui/core/event/distributor.cpp
index 9a8b4d9cc2..fb91d33d01 100644
--- a/src/gui/core/event/distributor.cpp
+++ b/src/gui/core/event/distributor.cpp
@@ -558,7 +558,7 @@ distributor::distributor(widget& owner,
}
owner_.connect_signal<event::SDL_KEY_DOWN>(std::bind(
- &distributor::signal_handler_sdl_key_down, this, _5, _6, _7));
+ &distributor::signal_handler_sdl_key_down, this, _5, _6, _7, _3, _4));
owner_.connect_signal<event::SDL_TEXT_INPUT>(std::bind(
&distributor::signal_handler_sdl_text_input, this, _5, _6, _7));
@@ -575,7 +575,7 @@ distributor::distributor(widget& owner,
distributor::~distributor()
{
owner_.disconnect_signal<event::SDL_KEY_DOWN>(std::bind(
- &distributor::signal_handler_sdl_key_down, this, _5, _6, _7));
+ &distributor::signal_handler_sdl_key_down, this, _5, _6, _7, _3, _4));
owner_.disconnect_signal<event::SDL_TEXT_INPUT>(std::bind(
&distributor::signal_handler_sdl_text_input, this, _5, _6, _7));
@@ -707,9 +707,11 @@ void distributor::signal_handler_keyboard_internal(event::ui_event evt, P1&& p1,
}
}
-void distributor::signal_handler_sdl_key_down(const SDL_Keycode key, const SDL_Keymod modifier, const std::string& unicode)
+void distributor::signal_handler_sdl_key_down(const SDL_Keycode key, const SDL_Keymod modifier, const std::string& unicode, bool& handled, bool& halt)
{
signal_handler_keyboard_internal<signal_keyboard_function>(event::SDL_KEY_DOWN, key, modifier, unicode);
+ handled = true;
+ halt = true;
}
void distributor::signal_handler_sdl_text_input(const std::string& unicode, int32_t start, int32_t end)
diff --git a/src/gui/core/event/distributor.hpp b/src/gui/core/event/distributor.hpp
index 686f0ce69a..a3e579c8c8 100644
--- a/src/gui/core/event/distributor.hpp
+++ b/src/gui/core/event/distributor.hpp
@@ -353,7 +353,9 @@ private:
void signal_handler_sdl_key_down(const SDL_Keycode key,
const SDL_Keymod modifier,
- const std::string& unicode);
+ const std::string& unicode,
+ bool& handled,
+ bool& halt);
void signal_handler_sdl_text_input(const std::string& unicode, int32_t start, int32_t len);
void signal_handler_sdl_text_editing(const std::string& unicode, int32_t start, int32_t len);
diff --git a/src/gui/dialogs/command_console.cpp b/src/gui/dialogs/command_console.cpp
index f6644dc373..7bb52dcc14 100644
--- a/src/gui/dialogs/command_console.cpp
+++ b/src/gui/dialogs/command_console.cpp
@@ -47,7 +47,7 @@ void command_console::post_build(window& window)
// Execute provided callback on ENTER press.
connect_signal_pre_key_press(*input_,
- std::bind(&command_console::input_key_press_callback, this, _5));
+ std::bind(&command_console::input_key_press_callback, this, _5, _3, _4));
}
void command_console::pre_show(window& window)
@@ -64,7 +64,7 @@ void command_console::window_key_press_callback(const SDL_Keycode key)
}
}
-void command_console::input_key_press_callback(const SDL_Keycode key)
+void command_console::input_key_press_callback(const SDL_Keycode key, bool& handled, bool& halt)
{
if(key == SDLK_RETURN || key == SDLK_KP_ENTER) {
// Execute callback.
@@ -74,6 +74,9 @@ void command_console::input_key_press_callback(const SDL_Keycode key)
// Dismiss dialog.
close();
+
+ handled = true;
+ halt = true;
} else if(key == SDLK_TAB) {
// TODO: implement
}
diff --git a/src/gui/dialogs/command_console.hpp b/src/gui/dialogs/command_console.hpp
index 5af8b7eb97..bf18f835ec 100644
--- a/src/gui/dialogs/command_console.hpp
+++ b/src/gui/dialogs/command_console.hpp
@@ -80,7 +80,7 @@ private:
void window_key_press_callback(const SDL_Keycode key);
- void input_key_press_callback(const SDL_Keycode key);
+ void input_key_press_callback(const SDL_Keycode key, bool& handled, bool& halt);
void close();
--
2.18.0.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment