diff --git a/include/nana/gui/detail/bedrock.hpp b/include/nana/gui/detail/bedrock.hpp index 9dc3812c..db731e97 100644 --- a/include/nana/gui/detail/bedrock.hpp +++ b/include/nana/gui/detail/bedrock.hpp @@ -1,7 +1,7 @@ /** * A Bedrock Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -43,6 +43,20 @@ namespace detail class flag_guard; + /// RAII class for window message processing + class root_guard + { + public: + /// Enables lazy_update + root_guard(bedrock& brock, basic_window* root_wd); + + /// Disables lazy-update and clears update requesters queue. + ~root_guard(); + private: + bedrock& brock_; + basic_window* const root_wd_; + }; + ~bedrock(); void pump_event(window, bool is_modal); void flush_surface(core_window_t*, bool forced, const rectangle* update_area = nullptr); diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index d9c26326..1aa18fe2 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -117,6 +117,7 @@ namespace detail void map(core_window_t*, bool forced, const rectangle* update_area = nullptr); bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr); + void update_requesters(core_window_t* root_wd); void refresh_tree(core_window_t*); void do_lazy_refresh(core_window_t*, bool force_copy_to_screen, bool refresh_tree = false); diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index 0cd1e796..fdb1181b 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -91,9 +91,26 @@ namespace nana private: bedrock *const brock_; core_window_t *const wd_; - }; + //class root_guard + bedrock::root_guard::root_guard(bedrock& brock, basic_window* root_wd): + brock_(brock), + root_wd_(root_wd) + { + root_wd_->other.attribute.root->lazy_update = true; + } + + bedrock::root_guard::~root_guard() + { + if (!brock_.wd_manager().available(root_wd_)) + return; + + root_wd_->other.attribute.root->lazy_update = false; + root_wd_->other.attribute.root->update_requesters.clear(); + } + //end class root_guard + bedrock::core_window_t* bedrock::focus() { auto wd = wd_manager().root(native_interface::get_focus_window()); diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 9c96a7cd..9b1160bf 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -556,6 +556,7 @@ namespace detail context.is_alt_pressed = false; } +#if 0 class window_proc_guard { public: @@ -576,6 +577,7 @@ namespace detail private: detail::basic_window* const root_wd_; }; +#endif void window_proc_for_xevent(Display* /*display*/, XEvent& xevent) { @@ -593,7 +595,8 @@ namespace detail { auto const root_wd = root_runtime->window; auto msgwnd = root_wd; - window_proc_guard wp_guard{ root_wd }; + + detail::bedrock::root_guard rw_guard{ brock, root_wd }; auto& context = *brock.get_thread_context(msgwnd->thread_id); @@ -1215,14 +1218,8 @@ namespace detail } } - if (wd_manager.available(root_wd) && root_wd->other.attribute.root->update_requesters.size()) - { - for (auto wd : root_wd->other.attribute.root->update_requesters) - { - window_layout::paint(wd, window_layout::paint_operation::have_refreshed, false); - wd_manager.map(wd, true); - } - } + + wd_manager.update_requesters(root_wd); root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index 2747e65f..d549bedc 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -740,27 +740,6 @@ namespace detail return static_cast(vkey); } - class window_proc_guard - { - public: - window_proc_guard(detail::basic_window* wd) : - root_wd_(wd) - { - root_wd_->other.attribute.root->lazy_update = true; - } - - ~window_proc_guard() - { - if (!bedrock::instance().wd_manager().available(root_wd_)) - return; - - root_wd_->other.attribute.root->lazy_update = false; - root_wd_->other.attribute.root->update_requesters.clear(); - } - private: - detail::basic_window* const root_wd_; - }; - LRESULT CALLBACK Bedrock_WIN32_WindowProc(HWND root_window, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT window_proc_value = 0; @@ -793,7 +772,7 @@ namespace detail auto const root_wd = root_runtime->window; auto msgwnd = root_wd; - window_proc_guard wp_guard{ root_wd }; + detail::bedrock::root_guard rw_guard{ brock, root_wd }; switch (message) { @@ -1577,14 +1556,7 @@ namespace detail def_window_proc = true; } - if (wd_manager.available(root_wd) && root_wd->other.attribute.root->update_requesters.size()) - { - for (auto wd : root_wd->other.attribute.root->update_requesters) - { - window_layout::paint(wd, window_layout::paint_operation::have_refreshed, false); - wd_manager.map(wd, true); - } - } + wd_manager.update_requesters(root_wd); root_runtime = wd_manager.root_runtime(native_window); if(root_runtime) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index b5842be8..9f854ee4 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -1051,6 +1051,29 @@ namespace detail return true; } + void window_manager::update_requesters(core_window_t* root_wd) + { + //Thread-Safe Required! + std::lock_guard lock(mutex_); + + if (this->available(root_wd) && root_wd->other.attribute.root->update_requesters.size()) + { + for (auto wd : root_wd->other.attribute.root->update_requesters) + { + using paint_operation = window_layer::paint_operation; + if (!this->available(wd)) + continue; + + //#431 + //Redraws the widget when it has beground effect. + //Because the widget just redraw if it didn't have bground effect when it was inserted to the update_requesters queue + window_layer::paint(wd, (wd->effect.bground ? paint_operation::try_refresh : paint_operation::have_refreshed), false); + this->map(wd, true); + } + } + + } + void window_manager::refresh_tree(core_window_t* wd) { //Thread-Safe Required!