From 3834440298e2cf120dbddcfce959cc7e40c335ac Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 21 Jun 2015 19:56:23 +0100 Subject: [PATCH] Rework window redraw handling, should redraw window less often --- src/client.cc | 9 +-------- src/client_manager.cc | 2 +- src/commands.cc | 4 ---- src/normal.cc | 4 ++++ src/window.cc | 35 +++++++++++++++++++++++++++++------ src/window.hh | 9 ++++++--- 6 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/client.cc b/src/client.cc index a77ac917..3397de15 100644 --- a/src/client.cc +++ b/src/client.cc @@ -70,10 +70,7 @@ void Client::handle_available_input(EventMode mode) if (*key == ctrl('c')) killpg(getpgrp(), SIGINT); else - { m_input_handler.handle_key(*key); - context().window().forget_timestamp(); - } } } catch (Kakoune::runtime_error& error) @@ -148,12 +145,8 @@ void Client::redraw_ifn() { Face default_face = get_face("Default"); - if (context().window().timestamp() != context().buffer().timestamp()) + if (context().window().needs_redraw(context())) { - CharCoord dimensions = context().ui().dimensions(); - if (dimensions == CharCoord{0,0}) - return; - context().window().set_dimensions(dimensions); context().window().update_display_buffer(context()); context().ui().draw(context().window().display_buffer(), default_face); diff --git a/src/client_manager.cc b/src/client_manager.cc index 99340da8..922ee250 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -86,7 +86,7 @@ WindowAndSelections ClientManager::get_free_window(Buffer& buffer) if (it == m_free_windows.rend()) return { make_unique(buffer), { buffer, Selection{} } }; - it->window->forget_timestamp(); + it->window->force_redraw(); WindowAndSelections res = std::move(*it); m_free_windows.erase(it.base()-1); res.selections.update(); diff --git a/src/commands.cc b/src/commands.cc index 97586f17..9cf58a62 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1244,10 +1244,6 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) func(parser, *real_context); } - - // force redraw of this client window - if (real_context != &context and real_context->has_window()) - real_context->window().forget_timestamp(); } const CommandDesc exec_string_cmd = { diff --git a/src/normal.cc b/src/normal.cc index 84724b11..4cd8dddf 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -686,6 +686,10 @@ void use_selection_as_search_pattern(Context& context, NormalParams) get_face("Information") }); } RegisterManager::instance()['/'] = patterns; + + // Hack, as Window do not take register state into account + if (context.has_window()) + context.window().force_redraw(); } void select_regex(Context& context, NormalParams) diff --git a/src/window.cc b/src/window.cc index 18ca03cc..75b90b51 100644 --- a/src/window.cc +++ b/src/window.cc @@ -4,7 +4,8 @@ #include "context.hh" #include "highlighter.hh" #include "hook_manager.hh" -#include "client.hh" +#include "input_handler.hh" +#include "user_interface.hh" #include #include @@ -60,14 +61,36 @@ void Window::scroll(CharCount offset) m_position.column = std::max(0_char, m_position.column + offset); } +size_t Window::compute_hash(const Context& context) const +{ + size_t res = hash_values(m_position, context.ui().dimensions(), context.buffer().timestamp()); + + auto& selections = context.selections(); + res = combine_hash(res, hash_value(selections.main_index())); + for (auto& sel : selections) + res = combine_hash(res, hash_values((const ByteCoord&)sel.cursor(), sel.anchor())); + + return res; +} + +bool Window::needs_redraw(const Context& context) const +{ + size_t hash = compute_hash(context); + return hash != m_hash; +} + void Window::update_display_buffer(const Context& context) { - kak_assert(&buffer() == &context.buffer()); - scroll_to_keep_selection_visible_ifn(context); - DisplayBuffer::LineList& lines = m_display_buffer.lines(); lines.clear(); + m_dimensions = context.ui().dimensions(); + if (m_dimensions == CharCoord{0,0}) + return; + + kak_assert(&buffer() == &context.buffer()); + scroll_to_keep_selection_visible_ifn(context); + for (LineCount line = 0; line < m_dimensions.line; ++line) { LineCount buffer_line = m_position.line + line; @@ -86,7 +109,7 @@ void Window::update_display_buffer(const Context& context) line.trim(m_position.column, m_dimensions.column, true); m_display_buffer.optimize(); - m_timestamp = buffer().timestamp(); + m_hash = compute_hash(context); } void Window::set_position(CharCoord position) @@ -294,7 +317,7 @@ void Window::on_option_changed(const Option& option) format("{}={}", option.name(), option.get_as_string())); // an highlighter might depend on the option, so we need to redraw - forget_timestamp(); + force_redraw(); } diff --git a/src/window.hh b/src/window.hh index f83377d7..9fb1a971 100644 --- a/src/window.hh +++ b/src/window.hh @@ -38,8 +38,8 @@ public: Buffer& buffer() const { return *m_buffer; } - size_t timestamp() const { return m_timestamp; } - void forget_timestamp() { m_timestamp = -1; } + bool needs_redraw(const Context& context) const; + void force_redraw() { m_hash = -1; } ByteCoord offset_coord(ByteCoord coord, CharCount offset); ByteCoordAndTarget offset_coord(ByteCoordAndTarget coord, LineCount offset); @@ -53,6 +53,8 @@ private: void run_hook_in_own_context(StringView hook_name, StringView param); + size_t compute_hash(const Context& context) const; + SafePtr m_buffer; CharCoord m_position; @@ -62,7 +64,8 @@ private: HighlighterGroup m_highlighters; HighlighterGroup m_builtin_highlighters; - size_t m_timestamp = -1; + // hash used to determine if a redraw is necessary + size_t m_hash = -1; }; }