fix a refreshing issue
bad refreshing when a lite_widget is destroying if the lite_widget's parent is also a type of lite_widget
This commit is contained in:
parent
331f19e679
commit
e8ae11e208
@ -55,6 +55,13 @@ namespace detail
|
|||||||
unsigned ignore; //determinate that pos or size would be ignored.
|
unsigned ignore; //determinate that pos or size would be ignored.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct map_thread
|
||||||
|
{
|
||||||
|
rectangle update_area;
|
||||||
|
bool ignore_update_area;
|
||||||
|
bool forced;
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
tray = 0x501,
|
tray = 0x501,
|
||||||
|
|||||||
@ -42,7 +42,7 @@ namespace detail
|
|||||||
|
|
||||||
~bedrock();
|
~bedrock();
|
||||||
void pump_event(window, bool is_modal);
|
void pump_event(window, bool is_modal);
|
||||||
void map_thread_root_buffer(core_window_t*, bool forced);
|
void map_thread_root_buffer(core_window_t*, bool forced, const rectangle* update_area = nullptr);
|
||||||
static int inc_window(unsigned tid = 0);
|
static int inc_window(unsigned tid = 0);
|
||||||
thread_context* open_thread_context(unsigned tid = 0);
|
thread_context* open_thread_context(unsigned tid = 0);
|
||||||
thread_context* get_thread_context(unsigned tid = 0);
|
thread_context* get_thread_context(unsigned tid = 0);
|
||||||
|
|||||||
@ -110,7 +110,7 @@ namespace nana
|
|||||||
void key_char(const arg_keyboard&);
|
void key_char(const arg_keyboard&);
|
||||||
void key_release(const arg_keyboard&);
|
void key_release(const arg_keyboard&);
|
||||||
void shortkey(const arg_keyboard&);
|
void shortkey(const arg_keyboard&);
|
||||||
void map(window, bool forced); //Copy the root buffer to screen
|
void map(window, bool forced, const rectangle* update_area = nullptr); //Copy the root buffer to screen
|
||||||
void refresh();
|
void refresh();
|
||||||
drawer_trigger* realizer() const;
|
drawer_trigger* realizer() const;
|
||||||
void attached(widget&, drawer_trigger&);
|
void attached(widget&, drawer_trigger&);
|
||||||
|
|||||||
@ -13,9 +13,9 @@ namespace nana{
|
|||||||
{
|
{
|
||||||
edge_nimbus_renderer() = default;
|
edge_nimbus_renderer() = default;
|
||||||
public:
|
public:
|
||||||
typedef CoreWindow core_window_t;
|
using core_window_t = CoreWindow;
|
||||||
typedef window_layout window_layer;
|
using window_layer = window_layout;
|
||||||
typedef nana::paint::graphics & graph_reference;
|
using graph_reference = ::nana::paint::graphics&;
|
||||||
|
|
||||||
static edge_nimbus_renderer& instance()
|
static edge_nimbus_renderer& instance()
|
||||||
{
|
{
|
||||||
@ -28,7 +28,34 @@ namespace nana{
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool render(core_window_t * wd, bool forced)
|
void erase(core_window_t* wd)
|
||||||
|
{
|
||||||
|
if (effects::edge_nimbus::none == wd->effect.edge_nimbus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
core_window_t * root_wd = wd->root_widget;
|
||||||
|
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
|
||||||
|
|
||||||
|
for (auto i = nimbus.cbegin(); i != nimbus.cend(); ++i)
|
||||||
|
{
|
||||||
|
if (i->window == wd)
|
||||||
|
{
|
||||||
|
auto pixels = weight();
|
||||||
|
rectangle r{wd->pos_root, wd->dimension};
|
||||||
|
r.x -= static_cast<int>(pixels);
|
||||||
|
r.y -= static_cast<int>(pixels);
|
||||||
|
r.width += static_cast<unsigned>(pixels << 1);
|
||||||
|
r.height += static_cast<unsigned>(pixels << 1);
|
||||||
|
|
||||||
|
root_wd->root_graph->paste(root_wd->root, r, r.x, r.y);
|
||||||
|
|
||||||
|
nimbus.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool render(core_window_t * wd, bool forced, const rectangle* update_area = nullptr)
|
||||||
{
|
{
|
||||||
bool rendered = false;
|
bool rendered = false;
|
||||||
core_window_t * root_wd = wd->root_widget;
|
core_window_t * root_wd = wd->root_widget;
|
||||||
@ -49,8 +76,12 @@ namespace nana{
|
|||||||
{
|
{
|
||||||
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r))
|
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r))
|
||||||
{
|
{
|
||||||
if(action.window == wd)
|
if (action.window == wd)
|
||||||
|
{
|
||||||
|
if (update_area)
|
||||||
|
::nana::overlap(*update_area, rectangle(r), r);
|
||||||
rendered = true;
|
rendered = true;
|
||||||
|
}
|
||||||
|
|
||||||
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
|
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
|
||||||
if ((forced && (action.window == wd)) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
|
if ((forced && (action.window == wd)) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refresh))
|
||||||
|
|||||||
@ -150,9 +150,9 @@ namespace detail
|
|||||||
core_window_t* root(native_window_type) const;
|
core_window_t* root(native_window_type) const;
|
||||||
|
|
||||||
//Copy the root buffer that wnd specified into DeviceContext
|
//Copy the root buffer that wnd specified into DeviceContext
|
||||||
void map(core_window_t*, bool forced);
|
void map(core_window_t*, bool forced, const rectangle* update_area = nullptr);
|
||||||
|
|
||||||
bool update(core_window_t*, bool redraw, bool force);
|
bool update(core_window_t*, bool redraw, bool force, const rectangle* update_area = nullptr);
|
||||||
void refresh_tree(core_window_t*);
|
void refresh_tree(core_window_t*);
|
||||||
|
|
||||||
bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen);
|
bool do_lazy_refresh(core_window_t*, bool force_copy_to_screen);
|
||||||
|
|||||||
@ -240,7 +240,7 @@ namespace nana
|
|||||||
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
|
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::map(window wd, bool forced) //Copy the root buffer to screen
|
void drawer::map(window wd, bool forced, const rectangle* update_area) //Copy the root buffer to screen
|
||||||
{
|
{
|
||||||
if(wd)
|
if(wd)
|
||||||
{
|
{
|
||||||
@ -262,12 +262,16 @@ namespace nana
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false == edge_nimbus_renderer_t::instance().render(iwd, forced))
|
if (false == edge_nimbus_renderer_t::instance().render(iwd, forced, update_area))
|
||||||
{
|
{
|
||||||
nana::rectangle vr;
|
rectangle vr;
|
||||||
if(bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
|
if (bedrock_type::window_manager_t::wndlayout_type::read_visual_rectangle(iwd, vr))
|
||||||
|
{
|
||||||
|
if (update_area)
|
||||||
|
::nana::overlap(*update_area, rectangle(vr), vr);
|
||||||
iwd->root_graph->paste(iwd->root, vr, vr.x, vr.y);
|
iwd->root_graph->paste(iwd->root, vr, vr.x, vr.y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(owns_caret)
|
if(owns_caret)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -167,7 +167,7 @@ namespace detail
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bedrock::map_thread_root_buffer(core_window_t*, bool forced)
|
void bedrock::map_thread_root_buffer(core_window_t*, bool forced, const rectangle*)
|
||||||
{
|
{
|
||||||
//GUI in X11 is thread-independent, so no implementation.
|
//GUI in X11 is thread-independent, so no implementation.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -338,9 +338,14 @@ namespace detail
|
|||||||
return bedrock_object;
|
return bedrock_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced)
|
void bedrock::map_thread_root_buffer(core_window_t* wd, bool forced, const rectangle* update_area)
|
||||||
{
|
{
|
||||||
::PostMessage(reinterpret_cast<HWND>(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast<WPARAM>(wd), static_cast<LPARAM>(forced ? TRUE : FALSE));
|
auto stru = reinterpret_cast<detail::messages::map_thread*>(::HeapAlloc(::GetProcessHeap(), 0, sizeof(detail::messages::map_thread)));
|
||||||
|
if (stru)
|
||||||
|
{
|
||||||
|
if (FALSE == ::PostMessage(reinterpret_cast<HWND>(wd->root), nana::detail::messages::map_thread_root_buffer, reinterpret_cast<WPARAM>(wd), reinterpret_cast<LPARAM>(stru)))
|
||||||
|
::HeapFree(::GetProcessHeap(), 0, stru);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
|
void interior_helper_for_menu(MSG& msg, native_window_type menu_window)
|
||||||
@ -591,8 +596,12 @@ namespace detail
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case nana::detail::messages::map_thread_root_buffer:
|
case nana::detail::messages::map_thread_root_buffer:
|
||||||
bedrock.wd_manager.map(reinterpret_cast<bedrock::core_window_t*>(wParam), (TRUE == lParam));
|
{
|
||||||
|
auto stru = reinterpret_cast<detail::messages::map_thread*>(lParam);
|
||||||
|
bedrock.wd_manager.map(reinterpret_cast<bedrock::core_window_t*>(wParam), stru->forced, (stru->ignore_update_area ? nullptr : &stru->update_area));
|
||||||
::UpdateWindow(wd);
|
::UpdateWindow(wd);
|
||||||
|
::HeapFree(::GetProcessHeap(), 0, stru);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
case nana::detail::messages::remote_thread_move_window:
|
case nana::detail::messages::remote_thread_move_window:
|
||||||
{
|
{
|
||||||
|
|||||||
@ -371,22 +371,27 @@ namespace detail
|
|||||||
//destroy
|
//destroy
|
||||||
//@brief: Delete the window handle
|
//@brief: Delete the window handle
|
||||||
void window_manager::destroy(core_window_t* wd)
|
void window_manager::destroy(core_window_t* wd)
|
||||||
{
|
|
||||||
core_window_t* parent = nullptr;
|
|
||||||
{
|
{
|
||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
if (impl_->wd_register.available(wd) == false) return;
|
if (impl_->wd_register.available(wd) == false) return;
|
||||||
|
|
||||||
if (wd->parent)
|
rectangle update_area(wd->pos_owner, wd->dimension);
|
||||||
{
|
|
||||||
parent = wd->parent;
|
auto parent = wd->parent;
|
||||||
utl::erase(wd->parent->children, wd);
|
if (parent)
|
||||||
}
|
utl::erase(parent->children, wd);
|
||||||
|
|
||||||
_m_destroy(wd);
|
_m_destroy(wd);
|
||||||
|
|
||||||
|
while (parent && (parent->other.category == ::nana::category::flags::lite_widget))
|
||||||
|
{
|
||||||
|
update_area.x += parent->pos_owner.x;
|
||||||
|
update_area.y += parent->pos_owner.y;
|
||||||
|
parent = parent->parent;
|
||||||
}
|
}
|
||||||
update(parent, false, false);
|
|
||||||
|
update(parent, false, false, &update_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
//destroy_handle
|
//destroy_handle
|
||||||
@ -672,7 +677,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Copy the root buffer that wnd specified into DeviceContext
|
//Copy the root buffer that wnd specified into DeviceContext
|
||||||
void window_manager::map(core_window_t* wd, bool forced)
|
void window_manager::map(core_window_t* wd, bool forced, const rectangle* update_area)
|
||||||
{
|
{
|
||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
@ -680,12 +685,12 @@ namespace detail
|
|||||||
{
|
{
|
||||||
//Copy the root buffer that wd specified into DeviceContext
|
//Copy the root buffer that wd specified into DeviceContext
|
||||||
#if defined(NANA_LINUX)
|
#if defined(NANA_LINUX)
|
||||||
wd->drawer.map(reinterpret_cast<window>(wd), forced);
|
wd->drawer.map(reinterpret_cast<window>(wd), forced, update_area);
|
||||||
#elif defined(NANA_WINDOWS)
|
#elif defined(NANA_WINDOWS)
|
||||||
if(nana::system::this_thread_id() == wd->thread_id)
|
if(nana::system::this_thread_id() == wd->thread_id)
|
||||||
wd->drawer.map(reinterpret_cast<window>(wd), forced);
|
wd->drawer.map(reinterpret_cast<window>(wd), forced, update_area);
|
||||||
else
|
else
|
||||||
bedrock::instance().map_thread_root_buffer(wd, forced);
|
bedrock::instance().map_thread_root_buffer(wd, forced, update_area);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -694,7 +699,7 @@ namespace detail
|
|||||||
//@brief: update is used for displaying the screen-off buffer.
|
//@brief: update is used for displaying the screen-off buffer.
|
||||||
// Because of a good efficiency, if it is called in an event procedure and the event procedure window is the
|
// Because of a good efficiency, if it is called in an event procedure and the event procedure window is the
|
||||||
// same as update's, update would not map the screen-off buffer and just set the window for lazy refresh
|
// same as update's, update would not map the screen-off buffer and just set the window for lazy refresh
|
||||||
bool window_manager::update(core_window_t* wd, bool redraw, bool forced)
|
bool window_manager::update(core_window_t* wd, bool redraw, bool forced, const rectangle* update_area)
|
||||||
{
|
{
|
||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
@ -705,7 +710,7 @@ namespace detail
|
|||||||
if(forced || (false == wd->belong_to_lazy()))
|
if(forced || (false == wd->belong_to_lazy()))
|
||||||
{
|
{
|
||||||
wndlayout_type::paint(wd, redraw, false);
|
wndlayout_type::paint(wd, redraw, false);
|
||||||
this->map(wd, forced);
|
this->map(wd, forced, update_area);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1252,18 +1257,9 @@ namespace detail
|
|||||||
|
|
||||||
if (!established)
|
if (!established)
|
||||||
{
|
{
|
||||||
if (effects::edge_nimbus::none != wd->effect.edge_nimbus)
|
//remove the window from edge nimbus effect when it is destroying
|
||||||
{
|
using edge_nimbus = detail::edge_nimbus_renderer<core_window_t>;
|
||||||
auto & cont = root_attr->effects_edge_nimbus;
|
edge_nimbus::instance().erase(wd);
|
||||||
for (auto i = cont.begin(); i != cont.end(); ++i)
|
|
||||||
{
|
|
||||||
if (i->window == wd)
|
|
||||||
{
|
|
||||||
cont.erase(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (pa_root_attr != root_attr)
|
else if (pa_root_attr != root_attr)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user