fix bug that window_position returns the pos of WM reparenting frame
This commit is contained in:
parent
df5fda9096
commit
1339658c4c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Platform Specification Implementation
|
* Platform Specification Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
|||||||
@ -588,16 +588,59 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
//There are three members make_owner(), get_owner() and remove(),
|
//There are three members make_owner(), get_owner() and remove(),
|
||||||
//they are maintain a table to discribe the owner of windows because the feature in X11, the
|
//they are maintain a table to discribe the owner of windows because of the feature in X11, the
|
||||||
//owner of top level window must be RootWindow.
|
//owner of top level window must be RootWindow.
|
||||||
void platform_spec::make_owner(native_window_type owner, native_window_type wd)
|
void platform_spec::make_owner(native_window_type owner, native_window_type wd)
|
||||||
{
|
{
|
||||||
platform_scope_guard psg;
|
platform_scope_guard lock;
|
||||||
wincontext_[wd].owner = owner;
|
wincontext_[wd].owner = owner;
|
||||||
window_context_t & context = wincontext_[owner];
|
|
||||||
if(context.owned == 0)
|
auto& owner_ctx = wincontext_[owner];
|
||||||
context.owned = new std::vector<native_window_type>;
|
if(!owner_ctx.owned)
|
||||||
context.owned->push_back(wd);
|
owner_ctx.owned = new std::vector<native_window_type>;
|
||||||
|
owner_ctx.owned->push_back(wd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool platform_spec::umake_owner(native_window_type child)
|
||||||
|
{
|
||||||
|
platform_scope_guard lock;
|
||||||
|
|
||||||
|
auto i = wincontext_.find(child);
|
||||||
|
if(i == wincontext_.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(i->second.owner)
|
||||||
|
{
|
||||||
|
auto u = wincontext_.find(i->second.owner);
|
||||||
|
if(u != wincontext_.end())
|
||||||
|
{
|
||||||
|
auto * owned = u->second.owned;
|
||||||
|
if(owned)
|
||||||
|
{
|
||||||
|
auto j = std::find(owned->begin(), owned->end(), child);
|
||||||
|
if(j != owned->end())
|
||||||
|
owned->erase(j);
|
||||||
|
|
||||||
|
if(owned->empty())
|
||||||
|
{
|
||||||
|
delete owned;
|
||||||
|
u->second.owned = nullptr;
|
||||||
|
//The owner owns no child. If it is not a child of other owners,
|
||||||
|
//remove it.
|
||||||
|
if(nullptr == u->second.owner)
|
||||||
|
wincontext_.erase(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i->second.owner = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Don't remove the ownerships which the child is a owner window.
|
||||||
|
if(nullptr == i->second.owned)
|
||||||
|
wincontext_.erase(i);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
native_window_type platform_spec::get_owner(native_window_type wd) const
|
native_window_type platform_spec::get_owner(native_window_type wd) const
|
||||||
@ -610,7 +653,9 @@ namespace detail
|
|||||||
void platform_spec::remove(native_window_type wd)
|
void platform_spec::remove(native_window_type wd)
|
||||||
{
|
{
|
||||||
msg_dispatcher_->erase(reinterpret_cast<Window>(wd));
|
msg_dispatcher_->erase(reinterpret_cast<Window>(wd));
|
||||||
platform_scope_guard psg;
|
|
||||||
|
platform_scope_guard lock;
|
||||||
|
#if 0
|
||||||
auto i = wincontext_.find(wd);
|
auto i = wincontext_.find(wd);
|
||||||
if(i == wincontext_.end()) return;
|
if(i == wincontext_.end()) return;
|
||||||
|
|
||||||
@ -641,6 +686,28 @@ namespace detail
|
|||||||
}
|
}
|
||||||
delete vec;
|
delete vec;
|
||||||
wincontext_.erase(i);
|
wincontext_.erase(i);
|
||||||
|
#else
|
||||||
|
if(umake_owner(wd))
|
||||||
|
{
|
||||||
|
auto i = wincontext_.find(wd);
|
||||||
|
if(i != wincontext_.end())
|
||||||
|
{
|
||||||
|
if(i->second.owned)
|
||||||
|
{
|
||||||
|
set_error_handler();
|
||||||
|
auto & wd_manager = detail::bedrock::instance().wd_manager();
|
||||||
|
for(auto u = i->second.owned->rbegin(); u != i->second.owned->rend(); ++u)
|
||||||
|
wd_manager.close(wd_manager.root(*u));
|
||||||
|
|
||||||
|
rev_error_handler();
|
||||||
|
|
||||||
|
delete i->second.owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
wincontext_.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
iconbase_.erase(wd);
|
iconbase_.erase(wd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Platform Specification Implementation
|
* Platform Specification Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Platform Specification Implementation
|
* Platform Specification Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -213,6 +213,9 @@ namespace detail
|
|||||||
const atombase_tag & atombase() const;
|
const atombase_tag & atombase() const;
|
||||||
|
|
||||||
void make_owner(native_window_type owner, native_window_type wd);
|
void make_owner(native_window_type owner, native_window_type wd);
|
||||||
|
|
||||||
|
// Cancel the ownership
|
||||||
|
bool umake_owner(native_window_type child);
|
||||||
native_window_type get_owner(native_window_type) const;
|
native_window_type get_owner(native_window_type) const;
|
||||||
void remove(native_window_type);
|
void remove(native_window_type);
|
||||||
|
|
||||||
|
|||||||
@ -296,6 +296,8 @@ namespace nana{
|
|||||||
win_attr.save_under = True;
|
win_attr.save_under = True;
|
||||||
attr_mask |= CWSaveUnder;
|
attr_mask |= CWSaveUnder;
|
||||||
|
|
||||||
|
///The parameter of XCreateWindow to create a top level window must be root.
|
||||||
|
///But after creation, the real parent is the reparenting frame window.
|
||||||
parent = restrict::spec.root_window();
|
parent = restrict::spec.root_window();
|
||||||
calc_screen_point(owner, pos);
|
calc_screen_point(owner, pos);
|
||||||
}
|
}
|
||||||
@ -309,9 +311,10 @@ namespace nana{
|
|||||||
if(handle)
|
if(handle)
|
||||||
{
|
{
|
||||||
//make owner if it is a popup window
|
//make owner if it is a popup window
|
||||||
if((!nested) && owner)
|
if(!nested)
|
||||||
{
|
{
|
||||||
restrict::spec.make_owner(owner, reinterpret_cast<native_window_type>(handle));
|
auto origin_owner = (owner ? owner : reinterpret_cast<native_window_type>(restrict::spec.root_window()));
|
||||||
|
restrict::spec.make_owner(origin_owner, reinterpret_cast<native_window_type>(handle));
|
||||||
exposed_positions[handle] = pos;
|
exposed_positions[handle] = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,7 +1225,7 @@ namespace nana{
|
|||||||
Window drop_wd;
|
Window drop_wd;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
nana::detail::platform_scope_guard psg;
|
nana::detail::platform_scope_guard lock;
|
||||||
::XQueryPointer(restrict::spec.open_display(), restrict::spec.root_window(), &drop_wd, &drop_wd, &pos.x, &pos.y, &x, &y, &mask);
|
::XQueryPointer(restrict::spec.open_display(), restrict::spec.root_window(), &drop_wd, &drop_wd, &pos.x, &pos.y, &x, &y, &mask);
|
||||||
return pos;
|
return pos;
|
||||||
#endif
|
#endif
|
||||||
@ -1278,9 +1281,19 @@ namespace nana{
|
|||||||
if(returns_previous)
|
if(returns_previous)
|
||||||
prev = parent_window(child);
|
prev = parent_window(child);
|
||||||
|
|
||||||
|
if(native_window_type{} == new_parent)
|
||||||
|
new_parent = reinterpret_cast<native_window_type>(restrict::spec.root_window());
|
||||||
|
|
||||||
::XReparentWindow(restrict::spec.open_display(),
|
::XReparentWindow(restrict::spec.open_display(),
|
||||||
reinterpret_cast<Window>(child), reinterpret_cast<Window>(new_parent),
|
reinterpret_cast<Window>(child), reinterpret_cast<Window>(new_parent),
|
||||||
0, 0);
|
0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
// If umake_owner returns true, it indicates the child windows is a popup window.
|
||||||
|
// So make the ownership of new_parent and child.
|
||||||
|
if(restrict::spec.umake_owner(child))
|
||||||
|
restrict::spec.make_owner(new_parent, child);
|
||||||
|
|
||||||
return prev;
|
return prev;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,7 +99,7 @@ namespace nana
|
|||||||
|
|
||||||
//Check scroll_area to avoiding division by zero.
|
//Check scroll_area to avoiding division by zero.
|
||||||
if (scroll_area)
|
if (scroll_area)
|
||||||
metrics_.value = pos * (static_cast<double>(value_max) / scroll_area); //converting to double to avoid overflow.
|
metrics_.value = static_cast<std::size_t>(pos * (static_cast<double>(value_max) / scroll_area)); //converting to double to avoid overflow.
|
||||||
|
|
||||||
if (metrics_.value < value_max)
|
if (metrics_.value < value_max)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1853,7 +1853,6 @@ namespace nana
|
|||||||
item_locator nl(impl_, xpos, arg.pos.x, arg.pos.y);
|
item_locator nl(impl_, xpos, arg.pos.x, arg.pos.y);
|
||||||
impl_->attr.tree_cont.for_each<item_locator&>(shape.first, nl);
|
impl_->attr.tree_cont.for_each<item_locator&>(shape.first, nl);
|
||||||
|
|
||||||
|
|
||||||
auto & node_state = impl_->node_state;
|
auto & node_state = impl_->node_state;
|
||||||
node_state.pressed_node = nl.node();
|
node_state.pressed_node = nl.node();
|
||||||
|
|
||||||
@ -1869,7 +1868,6 @@ namespace nana
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
impl_->draw(true);
|
impl_->draw(true);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user