Delay window deletion until we get back to main loop

Avoid WinResize hooks while redrawing, ensure window resize only
take place while handling user input.

Fixes #672
This commit is contained in:
Maxime Coste 2016-05-13 20:32:53 +01:00
parent 7f2b3f0132
commit ba421e45f7
6 changed files with 19 additions and 9 deletions

View File

@ -109,6 +109,7 @@ void BufferManager::clear_buffer_trash()
// Do that again, to be tolerant in some corner cases, where a buffer is
// deleted during its creation
ClientManager::instance().ensure_no_client_uses_buffer(*buffer);
ClientManager::instance().clear_window_trash();
delete buffer;
}

View File

@ -85,7 +85,7 @@ void Client::handle_available_input(EventMode mode)
else if (*key == Key::FocusOut)
context().hooks().run_hook("FocusOut", context().name(), context());
else if (key->modifiers == Key::Modifiers::Resize)
force_redraw();
m_window->set_dimensions(m_ui->dimensions());
else
m_input_handler.handle_key(*key);
}

View File

@ -143,9 +143,18 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
auto end = std::remove_if(m_free_windows.begin(), m_free_windows.end(),
[&buffer](const WindowAndSelections& ws)
{ return &ws.window->buffer() == &buffer; });
for (auto it = end; it != m_free_windows.end(); ++it)
m_window_trash.push_back(std::move(it->window));
m_free_windows.erase(end, m_free_windows.end());
}
void ClientManager::clear_window_trash()
{
m_window_trash.clear();
}
bool ClientManager::validate_client_name(StringView name) const
{
return const_cast<ClientManager*>(this)->get_client_ifp(name) == nullptr;

View File

@ -35,7 +35,7 @@ public:
void clear();
void ensure_no_client_uses_buffer(Buffer& buffer);
void ensure_no_client_uses_buffer(Buffer& buffer);
WindowAndSelections get_free_window(Buffer& buffer);
void add_free_window(std::unique_ptr<Window>&& window, SelectionList selections);
@ -57,11 +57,13 @@ public:
CandidateList complete_client_name(StringView name,
ByteCount cursor_pos = -1) const;
void clear_window_trash();
private:
String generate_name() const;
ClientList m_clients;
Vector<WindowAndSelections, MemoryDomain::Client> m_free_windows;
Vector<std::unique_ptr<Window>> m_window_trash;
};
}

View File

@ -580,6 +580,7 @@ int run_server(StringView session, StringView init_command,
client_manager.redraw_clients();
event_manager.handle_next_events(EventMode::Normal);
client_manager.handle_pending_inputs();
client_manager.clear_window_trash();
buffer_manager.clear_buffer_trash();
string_registry.purge_unused();

View File

@ -80,8 +80,7 @@ Window::Setup Window::build_setup(const Context& context) const
for (auto& sel : context.selections())
selections.push_back({sel.cursor(), sel.anchor()});
return { m_position,
context.client().dimensions(),
return { m_position, m_dimensions,
context.buffer().timestamp(),
context.selections().main_index(),
std::move(selections) };
@ -92,7 +91,7 @@ bool Window::needs_redraw(const Context& context) const
auto& selections = context.selections();
if (m_position != m_last_setup.position or
context.client().dimensions() != m_last_setup.dimensions or
m_dimensions != m_last_setup.dimensions or
context.buffer().timestamp() != m_last_setup.timestamp or
selections.main_index() != m_last_setup.main_selection or
selections.size() != m_last_setup.selections.size())
@ -120,7 +119,6 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
DisplayBuffer::LineList& lines = m_display_buffer.lines();
lines.clear();
set_dimensions(context.client().dimensions());
if (m_dimensions == CharCoord{0,0})
return m_display_buffer;
@ -365,9 +363,8 @@ void Window::clear_display_buffer()
void Window::on_option_changed(const Option& option)
{
run_hook_in_own_context("WinSetOption",
format("{}={}", option.name(), option.get_as_string()));
run_hook_in_own_context("WinSetOption", format("{}={}", option.name(),
option.get_as_string()));
// an highlighter might depend on the option, so we need to redraw
force_redraw();
}