Ensure InputModes are kept alive during their idle logic

Various paths can run arbitrary commands (callbacks, hooks) which
could lead to the InputMode being popped off the mode stack, but
contrarily to the on_key method, we had no guarantees to be kept
alive.

Add a keep_alive RefPtr to this to ensure the mode survives till
the end.

Fixes #3915
This commit is contained in:
Maxime Coste 2020-12-01 20:00:38 +11:00
parent 14f7d2637c
commit 586f79c30d

View File

@ -178,6 +178,7 @@ public:
m_idle_timer{TimePoint::max(),
context().flags() & Context::Flags::Draft ?
Timer::Callback{} : [this](Timer&) {
RefPtr<InputMode> keep_alive{this}; // hook could trigger pop_mode()
context().hooks().run_hook(Hook::NormalIdle, "", context());
}},
m_fs_check_timer{TimePoint::max(),
@ -754,6 +755,7 @@ public:
m_auto_complete{context().options()["autocomplete"].get<AutoComplete>() & AutoComplete::Prompt},
m_idle_timer{TimePoint::max(), context().flags() & Context::Flags::Draft ?
Timer::Callback{} : [this](Timer&) {
RefPtr<InputMode> keep_alive{this}; // hook or m_callback could trigger pop_mode()
if (m_auto_complete and m_refresh_completion_pending)
refresh_completions(CompletionFlags::Fast);
if (m_line_changed)
@ -1213,6 +1215,7 @@ public:
m_auto_complete{context().options()["autocomplete"].get<AutoComplete>() & AutoComplete::Insert},
m_idle_timer{TimePoint::max(), context().flags() & Context::Flags::Draft ?
Timer::Callback{} : [this](Timer&) {
RefPtr<InputMode> keep_alive{this}; // hook could trigger pop_mode()
m_completer.update(m_auto_complete);
context().hooks().run_hook(Hook::InsertIdle, "", context());
}},