summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-05-13 20:32:53 +0100
committerMaxime Coste <frrrwww@gmail.com>2016-05-14 08:17:52 +0100
commitba421e45f7b97c5e7ba28efe4f148fb3ba87a22c (patch)
treeb3f80be6aabacc03718e7ff9b9afb8202e548309
parent7f2b3f01322617bc7f215f0487151661b2f11aa5 (diff)
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
-rw-r--r--src/buffer_manager.cc1
-rw-r--r--src/client.cc2
-rw-r--r--src/client_manager.cc9
-rw-r--r--src/client_manager.hh4
-rw-r--r--src/main.cc1
-rw-r--r--src/window.cc11
6 files changed, 19 insertions, 9 deletions
diff --git a/src/buffer_manager.cc b/src/buffer_manager.cc
index bb9f7902..82b17037 100644
--- a/src/buffer_manager.cc
+++ b/src/buffer_manager.cc
@@ -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;
}
diff --git a/src/client.cc b/src/client.cc
index 6d875c39..b91a2254 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -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);
}
diff --git a/src/client_manager.cc b/src/client_manager.cc
index aff88d93..96165538 100644
--- a/src/client_manager.cc
+++ b/src/client_manager.cc
@@ -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;
diff --git a/src/client_manager.hh b/src/client_manager.hh
index c6ba1c35..7f2b603c 100644
--- a/src/client_manager.hh
+++ b/src/client_manager.hh
@@ -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;
};
}
diff --git a/src/main.cc b/src/main.cc
index 994edeee..f3d8b41f 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -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();
diff --git a/src/window.cc b/src/window.cc
index 0e7c3b96..de3f4ea4 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -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();
}