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 
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();
}