summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-06-21 19:56:23 +0100
committerMaxime Coste <frrrwww@gmail.com>2015-06-21 19:56:23 +0100
commit3834440298e2cf120dbddcfce959cc7e40c335ac (patch)
tree2d6b26a3581c87f61178b0c03d5d28d524123777 /src
parent7c22ff217d5d02bb926202e48dc35ba7a19c6f66 (diff)
Rework window redraw handling, should redraw window less often
Diffstat (limited to 'src')
-rw-r--r--src/client.cc9
-rw-r--r--src/client_manager.cc2
-rw-r--r--src/commands.cc4
-rw-r--r--src/normal.cc4
-rw-r--r--src/window.cc35
-rw-r--r--src/window.hh9
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<Window>(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 <algorithm>
#include <sstream>
@@ -60,14 +61,36 @@ void Window::scroll(CharCount offset)
m_position.column = std::max(0_char, m_position.column + offset);
}
-void Window::update_display_buffer(const Context& context)
+size_t Window::compute_hash(const Context& context) const
{
- kak_assert(&buffer() == &context.buffer());
- scroll_to_keep_selection_visible_ifn(context);
+ 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)
+{
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<Buffer> 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;
};
}