From 42f03fb71f7e9200917a0dccfb09715ae8c0b5f3 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 16 Jun 2017 10:19:08 +0100 Subject: [PATCH] Hide info/menu when they are anchored to an invisible buffer coord Fixes #1444 --- src/client.cc | 43 ++++++++++++++++++++++++------------------- src/client.hh | 4 ++-- src/input_handler.cc | 2 +- src/optional.hh | 2 ++ src/window.cc | 6 +++--- src/window.hh | 3 ++- 6 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/client.cc b/src/client.cc index aea878c0..22e574bb 100644 --- a/src/client.cc +++ b/src/client.cc @@ -209,38 +209,43 @@ void Client::redraw_ifn() return; if (m_ui_pending & Draw) - { m_ui->draw(window.update_display_buffer(context()), get_face("Default"), get_face("BufferPadding")); - if (not m_menu.items.empty() and m_menu.style == MenuStyle::Inline and - m_menu.ui_anchor != window.display_position(m_menu.anchor)) - m_ui_pending |= (MenuShow | MenuSelect); - if (not m_info.content.empty() and is_inline(m_info.style) and - m_info.ui_anchor != window.display_position(m_info.anchor)) - m_ui_pending |= InfoShow; + const bool update_menu_anchor = (m_ui_pending & Draw) and not (m_ui_pending & MenuHide) and + not m_menu.items.empty() and m_menu.style == MenuStyle::Inline; + if ((m_ui_pending & MenuShow) or update_menu_anchor) + { + auto anchor = m_menu.style == MenuStyle::Inline ? + window.display_position(m_menu.anchor) : DisplayCoord{}; + if (not (m_ui_pending & MenuShow) and m_menu.ui_anchor != anchor) + m_ui_pending |= anchor ? (MenuShow | MenuSelect) : MenuHide; + m_menu.ui_anchor = anchor; } - if (m_ui_pending & MenuShow) - { - m_menu.ui_anchor = m_menu.style == MenuStyle::Inline ? - window.display_position(m_menu.anchor) : DisplayCoord{}; - m_ui->menu_show(m_menu.items, m_menu.ui_anchor, + if (m_ui_pending & MenuShow and m_menu.ui_anchor) + m_ui->menu_show(m_menu.items, *m_menu.ui_anchor, get_face("MenuForeground"), get_face("MenuBackground"), m_menu.style); - } - if (m_ui_pending & MenuSelect) + if (m_ui_pending & MenuSelect and m_menu.ui_anchor) m_ui->menu_select(m_menu.selected); if (m_ui_pending & MenuHide) m_ui->menu_hide(); - if (m_ui_pending & InfoShow) + const bool update_info_anchor = (m_ui_pending & Draw) and not (m_ui_pending & InfoHide) and + not m_info.content.empty() and is_inline(m_info.style); + if ((m_ui_pending & InfoShow) or update_info_anchor) { - m_info.ui_anchor = is_inline(m_info.style) ? - window.display_position(m_info.anchor) : DisplayCoord{}; - m_ui->info_show(m_info.title, m_info.content, m_info.ui_anchor, - get_face("Information"), m_info.style); + auto anchor = is_inline(m_info.style) ? + window.display_position(m_info.anchor) : DisplayCoord{}; + if (not (m_ui_pending & MenuShow) and m_info.ui_anchor != anchor) + m_ui_pending |= anchor ? InfoShow : InfoHide; + m_info.ui_anchor = anchor; } + + if (m_ui_pending & InfoShow and m_info.ui_anchor) + m_ui->info_show(m_info.title, m_info.content, *m_info.ui_anchor, + get_face("Information"), m_info.style); if (m_ui_pending & InfoHide) m_ui->info_hide(); diff --git a/src/client.hh b/src/client.hh index 5b16a978..09329c6c 100644 --- a/src/client.hh +++ b/src/client.hh @@ -103,7 +103,7 @@ private: { Vector items; BufferCoord anchor; - DisplayCoord ui_anchor; + Optional ui_anchor; MenuStyle style; int selected; } m_menu{}; @@ -113,7 +113,7 @@ private: String title; String content; BufferCoord anchor; - DisplayCoord ui_anchor; + Optional ui_anchor; InfoStyle style; } m_info{}; diff --git a/src/input_handler.cc b/src/input_handler.cc index 8b91d1a4..65405057 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -41,7 +41,7 @@ public: virtual std::pair get_cursor_info() const { - DisplayCoord coord = context().window().display_position(context().selections().main().cursor()); + DisplayCoord coord = *context().window().display_position(context().selections().main().cursor()); return {CursorMode::Buffer, coord}; } diff --git a/src/optional.hh b/src/optional.hh index 623d6b23..153b5449 100644 --- a/src/optional.hh +++ b/src/optional.hh @@ -57,6 +57,8 @@ public: (not m_valid or m_value == other.m_value); } + bool operator!=(const Optional& other) const { return !(*this == other); } + template void emplace(Args&&... args) { diff --git a/src/window.cc b/src/window.cc index 9137ae28..c8d86e14 100644 --- a/src/window.cc +++ b/src/window.cc @@ -267,17 +267,17 @@ BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer, } } -DisplayCoord Window::display_position(BufferCoord coord) const +Optional Window::display_position(BufferCoord coord) const { LineCount l = 0; for (auto& line : m_display_buffer.lines()) { auto& range = line.range(); if (range.begin <= coord and coord < range.end) - return {l, find_display_column(line, buffer(), coord)}; + return DisplayCoord{l, find_display_column(line, buffer(), coord)}; ++l; } - return { 0, 0 }; + return {}; } BufferCoord Window::buffer_coord(DisplayCoord coord) const diff --git a/src/window.hh b/src/window.hh index 1c217dce..6aeaa0c0 100644 --- a/src/window.hh +++ b/src/window.hh @@ -5,6 +5,7 @@ #include "display_buffer.hh" #include "highlighter_group.hh" #include "option_manager.hh" +#include "optional.hh" #include "safe_ptr.hh" #include "scope.hh" @@ -36,7 +37,7 @@ public: const DisplayBuffer& update_display_buffer(const Context& context); - DisplayCoord display_position(BufferCoord coord) const; + Optional display_position(BufferCoord coord) const; BufferCoord buffer_coord(DisplayCoord coord) const; Highlighter& highlighters() { return m_highlighters; }