From 8be566214c153a129705ebe4f4cbf50a8c069acb Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 26 Jun 2015 23:59:28 +0800 Subject: [PATCH] fix a caret issue which happens when parent widget is hidden --- include/nana/gui/detail/basic_window.hpp | 4 +++- source/gui/detail/basic_window.cpp | 25 ++++++++++++++++++++++++ source/gui/detail/bedrock_pi.cpp | 9 +++++---- source/gui/detail/win32/bedrock.cpp | 2 +- source/gui/detail/window_layout.cpp | 2 +- source/gui/detail/window_manager.cpp | 6 +++--- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index 659f4316..c4945552 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -118,9 +118,11 @@ namespace detail bool is_ancestor_of(const basic_window* wd) const; bool visible_parents() const; + bool displayed() const; bool belong_to_lazy() const; + const basic_window * child_caret() const; //Returns a child which owns a caret - bool is_draw_through() const; ///< Determines whether it is a draw-through window. + bool is_draw_through() const; // Determines whether it is a draw-through window. public: //Override event_holder bool set_events(const std::shared_ptr&) override; diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 96aec1fa..33a91ca8 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -282,6 +282,11 @@ namespace nana return true; } + bool basic_window::displayed() const + { + return (visible && visible_parents()); + } + bool basic_window::belong_to_lazy() const { for (auto wd = this; wd; wd = wd->parent) @@ -292,6 +297,26 @@ namespace nana return false; } + const basic_window* get_child_caret(const basic_window* wd, bool this_is_a_child) + { + if (this_is_a_child && wd->together.caret) + return wd; + + for (auto child : wd->children) + { + auto caret_wd = get_child_caret(child, true); + if (caret_wd) + return caret_wd; + } + + return nullptr; + } + + const basic_window * basic_window::child_caret() const + { + return get_child_caret(this, false); + } + bool basic_window::is_draw_through() const { if (::nana::category::flags::root == this->other.category) diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index e76b0686..ce84ed94 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -63,15 +63,16 @@ namespace nana arg.window_handle = reinterpret_cast(wd); if (emit(event_code::expose, wd, arg, false, get_thread_context())) { - if (wd->together.caret) + const core_window_t * caret_wd = (wd->together.caret ? wd : wd->child_caret()); + if (caret_wd) { if (exposed) { - if (wd->root_widget->other.attribute.root->focus == wd) - wd->together.caret->visible(true); + if (wd->root_widget->other.attribute.root->focus == caret_wd) + caret_wd->together.caret->visible(true); } else - wd->together.caret->visible(false); + caret_wd->together.caret->visible(false); } if (!exposed) diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index 8cd5231c..e5635d12 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -363,7 +363,7 @@ namespace detail void bedrock::pump_event(window modal_window, bool is_modal) { const unsigned tid = ::GetCurrentThreadId(); - thread_context * context = this->open_thread_context(tid); + auto context = this->open_thread_context(tid); if(0 == context->window_count) { //test if there is not a window diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index a77eff5f..05867650 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -354,7 +354,7 @@ namespace nana nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension); for (auto wd : data_sect.effects_bground_windows) { - if (wd == sigwd || !wd->visible || !wd->visible_parents() || + if (wd == sigwd || !wd->displayed() || (false == overlap(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd))) continue; diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 30c497fa..59b54506 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -698,7 +698,7 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd) == false) return false; - if (wd->visible && wd->visible_parents()) + if (wd->displayed()) { if(forced || (false == wd->belong_to_lazy())) { @@ -722,7 +722,7 @@ namespace detail std::lock_guard lock(mutex_); //It's not worthy to redraw if visible is false - if (impl_->wd_register.available(wd) && wd->visible && wd->visible_parents()) + if (impl_->wd_register.available(wd) && wd->displayed()) window_layer::paint(wd, true, true); } @@ -1060,7 +1060,7 @@ namespace detail bool precondition = false; for (auto & tab_wd : tabs) { - if (tab_wd->visible) + if (tab_wd->displayed()) { precondition = true; break;