fix a crash that caused by double-delete of a event handler
This commit is contained in:
parent
f943673d3d
commit
a64354900c
@ -176,7 +176,6 @@ namespace detail
|
|||||||
{
|
{
|
||||||
caret_descriptor* caret;
|
caret_descriptor* caret;
|
||||||
std::shared_ptr<general_events> events_ptr;
|
std::shared_ptr<general_events> events_ptr;
|
||||||
general_events* attached_events;
|
|
||||||
}together;
|
}together;
|
||||||
|
|
||||||
widget_colors* scheme{ nullptr };
|
widget_colors* scheme{ nullptr };
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -63,14 +62,14 @@ namespace nana
|
|||||||
class basic_event : public detail::event_interface
|
class basic_event : public detail::event_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef const typename std::remove_reference<Arg>::type & arg_reference;
|
using arg_reference = const typename std::remove_reference<Arg>::type &;
|
||||||
private:
|
private:
|
||||||
struct docker
|
struct docker
|
||||||
: public detail::docker_interface
|
: public detail::docker_interface
|
||||||
{
|
{
|
||||||
basic_event * const event_ptr;
|
basic_event * const event_ptr;
|
||||||
std::function<void(arg_reference)> invoke;
|
std::function<void(arg_reference)> invoke;
|
||||||
bool flag_entered{ false };
|
|
||||||
bool flag_deleted{ false };
|
bool flag_deleted{ false };
|
||||||
bool unignorable{false};
|
bool unignorable{false};
|
||||||
|
|
||||||
@ -92,6 +91,36 @@ namespace nana
|
|||||||
return event_ptr;
|
return event_ptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//class emit_counter is a RAII helper for emitting count
|
||||||
|
//It is used for avoiding a try{}catch block which is required for some finial works when
|
||||||
|
//event handlers throw exceptions.
|
||||||
|
class emit_counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
emit_counter(basic_event* evt)
|
||||||
|
: evt_{evt}
|
||||||
|
{
|
||||||
|
++evt->emitting_count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~emit_counter()
|
||||||
|
{
|
||||||
|
if ((0 == --evt_->emitting_count_) && evt_->deleted_flags_)
|
||||||
|
{
|
||||||
|
evt_->deleted_flags_ = false;
|
||||||
|
for (auto i = evt_->dockers_->begin(); i != evt_->dockers_->end();)
|
||||||
|
{
|
||||||
|
if (i->get()->flag_deleted)
|
||||||
|
i = evt_->dockers_->erase(i);
|
||||||
|
else
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
basic_event * const evt_;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
/// It will get called firstly, because it is set at the beginning of the chain.
|
/// It will get called firstly, because it is set at the beginning of the chain.
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
@ -164,54 +193,37 @@ namespace nana
|
|||||||
return (nullptr == dockers_ ? 0 : dockers_->size());
|
return (nullptr == dockers_ ? 0 : dockers_->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit(arg_reference& arg) const
|
void emit(arg_reference& arg)
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
if (nullptr == dockers_)
|
if (nullptr == dockers_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Make a copy to allow create/destroy a new event handler when the call of emit in an event.
|
emit_counter ec(this);
|
||||||
const std::size_t fixed_size = 10;
|
|
||||||
docker* fixed_buffer[fixed_size];
|
|
||||||
docker** transitory = fixed_buffer;
|
|
||||||
|
|
||||||
std::unique_ptr<docker*[]> variable_buffer;
|
|
||||||
auto& dockers = *dockers_;
|
auto& dockers = *dockers_;
|
||||||
if (dockers.size() > fixed_size)
|
const auto dockers_len = dockers.size();
|
||||||
{
|
|
||||||
variable_buffer.reset(new docker*[dockers.size()]);
|
|
||||||
transitory = variable_buffer.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto output = transitory;
|
//The dockers may resize when a new event handler is created by a calling handler.
|
||||||
for (auto & dck : dockers)
|
//Traverses with position can avaid crash error which caused by a iterator which becomes invalid.
|
||||||
|
for (std::size_t pos = 0; pos < dockers_len; ++pos)
|
||||||
{
|
{
|
||||||
(*output++) = dck.get();
|
auto docker_ptr = dockers[pos].get();
|
||||||
}
|
if (docker_ptr->flag_deleted)
|
||||||
|
|
||||||
bool stop_propagation = false;
|
|
||||||
for (; transitory != output; ++transitory)
|
|
||||||
{
|
|
||||||
auto docker_ptr = *transitory;
|
|
||||||
if (stop_propagation && !docker_ptr->unignorable)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto i = std::find_if(dockers.begin(), dockers.end(), [docker_ptr](std::unique_ptr<docker>& p){
|
docker_ptr->invoke(arg);
|
||||||
return (docker_ptr == p.get());
|
if (arg.propagation_stopped())
|
||||||
});
|
|
||||||
|
|
||||||
if (i != dockers.end())
|
|
||||||
{
|
{
|
||||||
docker_ptr->flag_entered = true;
|
for (++pos; pos < dockers_len; ++pos)
|
||||||
docker_ptr->invoke(arg);
|
{
|
||||||
|
auto docker_ptr = dockers[pos].get();
|
||||||
|
if (!docker_ptr->unignorable || docker_ptr->flag_deleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (arg.propagation_stopped())
|
docker_ptr->invoke(arg);
|
||||||
stop_propagation = true;
|
}
|
||||||
|
break;
|
||||||
docker_ptr->flag_entered = false;
|
|
||||||
|
|
||||||
if (docker_ptr->flag_deleted)
|
|
||||||
dockers.erase(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,17 +240,20 @@ namespace nana
|
|||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
if (dockers_)
|
if (dockers_)
|
||||||
{
|
{
|
||||||
auto i = std::find_if(dockers_->begin(), dockers_->end(), [evt](const std::unique_ptr<docker>& sp)
|
for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i)
|
||||||
{
|
{
|
||||||
return (reinterpret_cast<detail::docker_interface*>(evt) == sp.get());
|
if (reinterpret_cast<detail::docker_interface*>(evt) == i->get())
|
||||||
});
|
{
|
||||||
|
//Checks whether this event is working now.
|
||||||
if (i != dockers_->end())
|
if (emitting_count_ > 1)
|
||||||
{
|
{
|
||||||
if (i->get()->flag_entered)
|
i->get()->flag_deleted = true;
|
||||||
i->get()->flag_deleted = true;
|
deleted_flags_ = true;
|
||||||
else
|
}
|
||||||
dockers_->erase(i);
|
else
|
||||||
|
dockers_->erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,6 +414,8 @@ namespace nana
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
|
unsigned emitting_count_{ 0 };
|
||||||
|
bool deleted_flags_{ false };
|
||||||
std::unique_ptr<std::vector<std::unique_ptr<docker>>> dockers_;
|
std::unique_ptr<std::vector<std::unique_ptr<docker>>> dockers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -260,9 +259,14 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if(cond_type::is_queue(handle))
|
if(cond_type::is_queue(handle))
|
||||||
{
|
{
|
||||||
auto i = std::find(queue.begin(), queue.end(), handle);
|
for (auto i = queue.begin(); i != queue.end(); ++i)
|
||||||
if(i != queue.end())
|
{
|
||||||
queue.erase(i);
|
if (handle == *i)
|
||||||
|
{
|
||||||
|
queue.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -356,7 +356,6 @@ namespace nana
|
|||||||
effect.bground_fade_rate = 0;
|
effect.bground_fade_rate = 0;
|
||||||
|
|
||||||
together.caret = nullptr;
|
together.caret = nullptr;
|
||||||
together.attached_events = nullptr;
|
|
||||||
|
|
||||||
extra_width = extra_height = 0;
|
extra_width = extra_height = 0;
|
||||||
|
|
||||||
@ -369,16 +368,15 @@ namespace nana
|
|||||||
|
|
||||||
bool basic_window::set_events(const std::shared_ptr<general_events>& p)
|
bool basic_window::set_events(const std::shared_ptr<general_events>& p)
|
||||||
{
|
{
|
||||||
if (together.attached_events)
|
if (together.events_ptr)
|
||||||
return false;
|
return false;
|
||||||
together.events_ptr = p;
|
together.events_ptr = p;
|
||||||
together.attached_events = p.get();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
general_events * basic_window::get_events() const
|
general_events * basic_window::get_events() const
|
||||||
{
|
{
|
||||||
return together.attached_events;
|
return together.events_ptr.get();
|
||||||
}
|
}
|
||||||
//end struct basic_window
|
//end struct basic_window
|
||||||
}//end namespace detail
|
}//end namespace detail
|
||||||
|
@ -146,6 +146,9 @@ namespace nana
|
|||||||
|
|
||||||
void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg)
|
void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg)
|
||||||
{
|
{
|
||||||
|
auto retain = wd->together.events_ptr;
|
||||||
|
auto evts_ptr = retain.get();
|
||||||
|
|
||||||
switch (evt_code)
|
switch (evt_code)
|
||||||
{
|
{
|
||||||
case event_code::click:
|
case event_code::click:
|
||||||
@ -162,35 +165,36 @@ namespace nana
|
|||||||
|
|
||||||
void(::nana::detail::drawer::*drawer_event_fn)(const arg_mouse&);
|
void(::nana::detail::drawer::*drawer_event_fn)(const arg_mouse&);
|
||||||
::nana::basic_event<arg_mouse>* evt_addr;
|
::nana::basic_event<arg_mouse>* evt_addr;
|
||||||
|
|
||||||
switch (evt_code)
|
switch (evt_code)
|
||||||
{
|
{
|
||||||
case event_code::click:
|
case event_code::click:
|
||||||
drawer_event_fn = &drawer::click;
|
drawer_event_fn = &drawer::click;
|
||||||
evt_addr = &wd->together.attached_events->click;
|
evt_addr = &evts_ptr->click;
|
||||||
break;
|
break;
|
||||||
case event_code::dbl_click:
|
case event_code::dbl_click:
|
||||||
drawer_event_fn = &drawer::dbl_click;
|
drawer_event_fn = &drawer::dbl_click;
|
||||||
evt_addr = &wd->together.attached_events->dbl_click;
|
evt_addr = &evts_ptr->dbl_click;
|
||||||
break;
|
break;
|
||||||
case event_code::mouse_enter:
|
case event_code::mouse_enter:
|
||||||
drawer_event_fn = &drawer::mouse_enter;
|
drawer_event_fn = &drawer::mouse_enter;
|
||||||
evt_addr = &wd->together.attached_events->mouse_enter;
|
evt_addr = &evts_ptr->mouse_enter;
|
||||||
break;
|
break;
|
||||||
case event_code::mouse_move:
|
case event_code::mouse_move:
|
||||||
drawer_event_fn = &drawer::mouse_move;
|
drawer_event_fn = &drawer::mouse_move;
|
||||||
evt_addr = &wd->together.attached_events->mouse_move;
|
evt_addr = &evts_ptr->mouse_move;
|
||||||
break;
|
break;
|
||||||
case event_code::mouse_leave:
|
case event_code::mouse_leave:
|
||||||
drawer_event_fn = &drawer::mouse_leave;
|
drawer_event_fn = &drawer::mouse_leave;
|
||||||
evt_addr = &wd->together.attached_events->mouse_leave;
|
evt_addr = &evts_ptr->mouse_leave;
|
||||||
break;
|
break;
|
||||||
case event_code::mouse_down:
|
case event_code::mouse_down:
|
||||||
drawer_event_fn = &drawer::mouse_down;
|
drawer_event_fn = &drawer::mouse_down;
|
||||||
evt_addr = &wd->together.attached_events->mouse_down;
|
evt_addr = &evts_ptr->mouse_down;
|
||||||
break;
|
break;
|
||||||
case event_code::mouse_up:
|
case event_code::mouse_up:
|
||||||
drawer_event_fn = &drawer::mouse_up;
|
drawer_event_fn = &drawer::mouse_up;
|
||||||
evt_addr = &wd->together.attached_events->mouse_up;
|
evt_addr = &evts_ptr->mouse_up;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid mouse event code");
|
throw std::runtime_error("Invalid mouse event code");
|
||||||
@ -209,7 +213,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
wd->drawer.mouse_wheel(*arg);
|
wd->drawer.mouse_wheel(*arg);
|
||||||
if (!draw_only)
|
if (!draw_only)
|
||||||
wd->together.attached_events->mouse_wheel.emit(*arg);
|
evts_ptr->mouse_wheel.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -229,19 +233,19 @@ namespace nana
|
|||||||
{
|
{
|
||||||
case event_code::key_press:
|
case event_code::key_press:
|
||||||
drawer_event_fn = &drawer::key_press;
|
drawer_event_fn = &drawer::key_press;
|
||||||
evt_addr = &wd->together.attached_events->key_press;
|
evt_addr = &evts_ptr->key_press;
|
||||||
break;
|
break;
|
||||||
case event_code::key_char:
|
case event_code::key_char:
|
||||||
drawer_event_fn = &drawer::key_char;
|
drawer_event_fn = &drawer::key_char;
|
||||||
evt_addr = &wd->together.attached_events->key_char;
|
evt_addr = &evts_ptr->key_char;
|
||||||
break;
|
break;
|
||||||
case event_code::key_release:
|
case event_code::key_release:
|
||||||
drawer_event_fn = &drawer::key_release;
|
drawer_event_fn = &drawer::key_release;
|
||||||
evt_addr = &wd->together.attached_events->key_release;
|
evt_addr = &evts_ptr->key_release;
|
||||||
break;
|
break;
|
||||||
case event_code::shortkey:
|
case event_code::shortkey:
|
||||||
drawer_event_fn = &drawer::shortkey;
|
drawer_event_fn = &drawer::shortkey;
|
||||||
evt_addr = &wd->together.attached_events->shortkey;
|
evt_addr = &evts_ptr->shortkey;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid keyboard event code");
|
throw std::runtime_error("Invalid keyboard event code");
|
||||||
@ -256,7 +260,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto arg = dynamic_cast<const arg_expose*>(&event_arg);
|
auto arg = dynamic_cast<const arg_expose*>(&event_arg);
|
||||||
if (arg)
|
if (arg)
|
||||||
wd->together.attached_events->expose.emit(*arg);
|
evts_ptr->expose.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case event_code::focus:
|
case event_code::focus:
|
||||||
@ -266,7 +270,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
wd->drawer.focus(*arg);
|
wd->drawer.focus(*arg);
|
||||||
if (!draw_only)
|
if (!draw_only)
|
||||||
wd->together.attached_events->focus.emit(*arg);
|
evts_ptr->focus.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -277,7 +281,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
wd->drawer.move(*arg);
|
wd->drawer.move(*arg);
|
||||||
if (!draw_only)
|
if (!draw_only)
|
||||||
wd->together.attached_events->move.emit(*arg);
|
evts_ptr->move.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -288,7 +292,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
wd->drawer.resizing(*arg);
|
wd->drawer.resizing(*arg);
|
||||||
if (!draw_only)
|
if (!draw_only)
|
||||||
wd->together.attached_events->resizing.emit(*arg);
|
evts_ptr->resizing.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -299,7 +303,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
wd->drawer.resized(*arg);
|
wd->drawer.resized(*arg);
|
||||||
if (!draw_only)
|
if (!draw_only)
|
||||||
wd->together.attached_events->resized.emit(*arg);
|
evts_ptr->resized.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -309,9 +313,9 @@ namespace nana
|
|||||||
auto arg = dynamic_cast<const arg_unload*>(&event_arg);
|
auto arg = dynamic_cast<const arg_unload*>(&event_arg);
|
||||||
if (arg && (wd->other.category == category::flags::root))
|
if (arg && (wd->other.category == category::flags::root))
|
||||||
{
|
{
|
||||||
auto evt_ptr = dynamic_cast<events_root_extension*>(wd->together.attached_events);
|
auto evt_root = dynamic_cast<events_root_extension*>(evts_ptr);
|
||||||
if (evt_ptr)
|
if (evt_root)
|
||||||
evt_ptr->unload.emit(*arg);
|
evt_root->unload.emit(*arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -320,7 +324,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto arg = dynamic_cast<const arg_destroy*>(&event_arg);
|
auto arg = dynamic_cast<const arg_destroy*>(&event_arg);
|
||||||
if (arg)
|
if (arg)
|
||||||
wd->together.attached_events->destroy.emit(*arg);
|
evts_ptr->destroy.emit(*arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -583,7 +583,7 @@ namespace detail
|
|||||||
delete msg.u.mouse_drop.files;
|
delete msg.u.mouse_drop.files;
|
||||||
arg.pos.x = msg.u.mouse_drop.x - msgwd->pos_root.x;
|
arg.pos.x = msg.u.mouse_drop.x - msgwd->pos_root.x;
|
||||||
arg.pos.y = msg.u.mouse_drop.y - msgwd->pos_root.y;
|
arg.pos.y = msg.u.mouse_drop.y - msgwd->pos_root.y;
|
||||||
msgwd->together.attached_events->mouse_dropfiles.emit(arg);
|
msgwd->together.events_ptr->mouse_dropfiles.emit(arg);
|
||||||
brock.wd_manager.do_lazy_refresh(msgwd, false);
|
brock.wd_manager.do_lazy_refresh(msgwd, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -766,7 +766,7 @@ namespace detail
|
|||||||
nana::point mspos{xevent.xbutton.x, xevent.xbutton.y};
|
nana::point mspos{xevent.xbutton.x, xevent.xbutton.y};
|
||||||
while(msgwnd)
|
while(msgwnd)
|
||||||
{
|
{
|
||||||
if(msgwnd->together.attached_events->mouse_wheel.length() != 0)
|
if(msgwnd->together.events_ptr->mouse_wheel.length() != 0)
|
||||||
{
|
{
|
||||||
mspos -= msgwnd->pos_root;
|
mspos -= msgwnd->pos_root;
|
||||||
arg_wheel arg;
|
arg_wheel arg;
|
||||||
@ -810,27 +810,29 @@ namespace detail
|
|||||||
{
|
{
|
||||||
if(hit)
|
if(hit)
|
||||||
msgwnd->flags.action = mouse_action::over;
|
msgwnd->flags.action = mouse_action::over;
|
||||||
|
|
||||||
|
auto retain = msgwnd->together.events_ptr;
|
||||||
|
auto evt_ptr = retain.get();
|
||||||
|
|
||||||
auto events_ptr = msgwnd->together.events_ptr;
|
|
||||||
arg.evt_code = event_code::mouse_up;
|
arg.evt_code = event_code::mouse_up;
|
||||||
emit_drawer(&drawer::mouse_up, msgwnd, arg, &context);
|
emit_drawer(&drawer::mouse_up, msgwnd, arg, &context);
|
||||||
|
|
||||||
if(fire_click)
|
if(fire_click)
|
||||||
{
|
{
|
||||||
arg.evt_code = event_code::click;
|
arg.evt_code = event_code::click;
|
||||||
msgwnd->together.attached_events->click.emit(arg);
|
evt_ptr->click.emit(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brock.wd_manager.available(msgwnd))
|
if (brock.wd_manager.available(msgwnd))
|
||||||
{
|
{
|
||||||
arg.evt_code = event_code::mouse_up;
|
arg.evt_code = event_code::mouse_up;
|
||||||
msgwnd->together.attached_events->mouse_up.emit(arg);
|
evt_ptr->mouse_up.emit(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(fire_click)
|
else if(fire_click)
|
||||||
{
|
{
|
||||||
arg.evt_code = event_code::click;
|
arg.evt_code = event_code::click;
|
||||||
msgwnd->together.attached_events->click.emit(arg);
|
msgwnd->together.events_ptr->click.emit(arg);
|
||||||
}
|
}
|
||||||
brock.wd_manager.do_lazy_refresh(msgwnd, false);
|
brock.wd_manager.do_lazy_refresh(msgwnd, false);
|
||||||
}
|
}
|
||||||
@ -1103,7 +1105,7 @@ namespace detail
|
|||||||
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
brock.get_key_state(arg);
|
brock.get_key_state(arg);
|
||||||
|
|
||||||
msgwnd->together.attached_events->key_char.emit(arg);
|
msgwnd->together.events_ptr->key_char.emit(arg);
|
||||||
if(arg.ignore == false && brock.wd_manager.available(msgwnd))
|
if(arg.ignore == false && brock.wd_manager.available(msgwnd))
|
||||||
brock.emit_drawer(event_code::key_char, msgwnd, arg, &context);
|
brock.emit_drawer(event_code::key_char, msgwnd, arg, &context);
|
||||||
}
|
}
|
||||||
|
@ -663,6 +663,7 @@ namespace detail
|
|||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
|
case WM_SYSCOMMAND:
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
case WM_MOUSEACTIVATE:
|
case WM_MOUSEACTIVATE:
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
@ -851,7 +852,7 @@ namespace detail
|
|||||||
case WM_WINDOWPOSCHANGED:
|
case WM_WINDOWPOSCHANGED:
|
||||||
if ((reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW) && (!msgwnd->visible))
|
if ((reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW) && (!msgwnd->visible))
|
||||||
brock.event_expose(msgwnd, true);
|
brock.event_expose(msgwnd, true);
|
||||||
else if((reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_HIDEWINDOW) && msgwnd->visible)
|
else if ((reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_HIDEWINDOW) && msgwnd->visible)
|
||||||
brock.event_expose(msgwnd, false);
|
brock.event_expose(msgwnd, false);
|
||||||
|
|
||||||
def_window_proc = true;
|
def_window_proc = true;
|
||||||
@ -871,6 +872,7 @@ namespace detail
|
|||||||
if (!brock.emit(event_code::focus, focus, arg, true, &context))
|
if (!brock.emit(event_code::focus, focus, arg, true, &context))
|
||||||
brock.wd_manager.set_focus(msgwnd, true);
|
brock.wd_manager.set_focus(msgwnd, true);
|
||||||
}
|
}
|
||||||
|
def_window_proc = true;
|
||||||
break;
|
break;
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
if(msgwnd->other.attribute.root->focus)
|
if(msgwnd->other.attribute.root->focus)
|
||||||
@ -891,10 +893,14 @@ namespace detail
|
|||||||
//focus_changed means that during an event procedure if the focus is changed
|
//focus_changed means that during an event procedure if the focus is changed
|
||||||
if(brock.wd_manager.available(msgwnd))
|
if(brock.wd_manager.available(msgwnd))
|
||||||
msgwnd->root_widget->other.attribute.root->context.focus_changed = true;
|
msgwnd->root_widget->other.attribute.root->context.focus_changed = true;
|
||||||
|
|
||||||
|
def_window_proc = true;
|
||||||
break;
|
break;
|
||||||
case WM_MOUSEACTIVATE:
|
case WM_MOUSEACTIVATE:
|
||||||
if(msgwnd->flags.take_active == false)
|
if(msgwnd->flags.take_active == false)
|
||||||
return MA_NOACTIVATE;
|
return MA_NOACTIVATE;
|
||||||
|
|
||||||
|
def_window_proc = true;
|
||||||
break;
|
break;
|
||||||
case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
|
case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
|
||||||
pressed_wd = nullptr;
|
pressed_wd = nullptr;
|
||||||
@ -1011,19 +1017,19 @@ namespace detail
|
|||||||
if (fire_click)
|
if (fire_click)
|
||||||
{
|
{
|
||||||
arg.evt_code = event_code::click;
|
arg.evt_code = event_code::click;
|
||||||
msgwnd->together.attached_events->click.emit(arg);
|
retain->click.emit(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brock.wd_manager.available(msgwnd))
|
if (brock.wd_manager.available(msgwnd))
|
||||||
{
|
{
|
||||||
arg.evt_code = event_code::mouse_up;
|
arg.evt_code = event_code::mouse_up;
|
||||||
msgwnd->together.attached_events->mouse_up.emit(arg);
|
retain->mouse_up.emit(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fire_click)
|
else if (fire_click)
|
||||||
{
|
{
|
||||||
arg.evt_code = event_code::click;
|
arg.evt_code = event_code::click;
|
||||||
msgwnd->together.attached_events->click.emit(arg);
|
retain->click.emit(arg);
|
||||||
}
|
}
|
||||||
brock.wd_manager.do_lazy_refresh(msgwnd, false);
|
brock.wd_manager.do_lazy_refresh(msgwnd, false);
|
||||||
}
|
}
|
||||||
@ -1114,7 +1120,7 @@ namespace detail
|
|||||||
auto evt_wd = scrolled_wd;
|
auto evt_wd = scrolled_wd;
|
||||||
while (evt_wd)
|
while (evt_wd)
|
||||||
{
|
{
|
||||||
if (evt_wd->together.attached_events->mouse_wheel.length() != 0)
|
if (evt_wd->together.events_ptr->mouse_wheel.length() != 0)
|
||||||
{
|
{
|
||||||
def_window_proc = false;
|
def_window_proc = false;
|
||||||
nana::point mspos{ scr_pos.x, scr_pos.y };
|
nana::point mspos{ scr_pos.x, scr_pos.y };
|
||||||
@ -1189,7 +1195,7 @@ namespace detail
|
|||||||
brock.wd_manager.calc_window_point(msgwnd, dropfiles.pos);
|
brock.wd_manager.calc_window_point(msgwnd, dropfiles.pos);
|
||||||
dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
|
dropfiles.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
|
|
||||||
msgwnd->together.attached_events->mouse_dropfiles.emit(dropfiles);
|
msgwnd->together.events_ptr->mouse_dropfiles.emit(dropfiles);
|
||||||
brock.wd_manager.do_lazy_refresh(msgwnd, false);
|
brock.wd_manager.do_lazy_refresh(msgwnd, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1419,7 +1425,7 @@ namespace detail
|
|||||||
brock.get_key_state(arg);
|
brock.get_key_state(arg);
|
||||||
arg.ignore = false;
|
arg.ignore = false;
|
||||||
|
|
||||||
msgwnd->together.attached_events->key_char.emit(arg);
|
msgwnd->together.events_ptr->key_char.emit(arg);
|
||||||
if ((false == arg.ignore) && brock.wd_manager.available(msgwnd))
|
if ((false == arg.ignore) && brock.wd_manager.available(msgwnd))
|
||||||
brock.emit_drawer(event_code::key_char, msgwnd, arg, &context);
|
brock.emit_drawer(event_code::key_char, msgwnd, arg, &context);
|
||||||
|
|
||||||
@ -1449,6 +1455,14 @@ namespace detail
|
|||||||
|
|
||||||
brock.delay_restore(2); //Restores while key release
|
brock.delay_restore(2); //Restores while key release
|
||||||
break;
|
break;
|
||||||
|
case WM_SYSCOMMAND:
|
||||||
|
if (SC_TASKLIST == wParam)
|
||||||
|
{
|
||||||
|
int debug = 0;
|
||||||
|
//brock.close_menu_if_focus_other_window()
|
||||||
|
}
|
||||||
|
def_window_proc = true;
|
||||||
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
{
|
{
|
||||||
arg_unload arg;
|
arg_unload arg;
|
||||||
@ -1537,7 +1551,8 @@ namespace detail
|
|||||||
impl_->menu.taken_window = wd;
|
impl_->menu.taken_window = wd;
|
||||||
|
|
||||||
//assigning of a nullptr taken window is to restore the focus of pre taken
|
//assigning of a nullptr taken window is to restore the focus of pre taken
|
||||||
if ((!wd) && pre)
|
//don't restore the focus if pre is a menu.
|
||||||
|
if ((!wd) && pre && (pre->root != get_menu()))
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
wd_manager.set_focus(pre, false);
|
wd_manager.set_focus(pre, false);
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/gui/detail/effects_renderer.hpp>
|
#include <nana/gui/detail/effects_renderer.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -192,7 +191,7 @@ namespace detail
|
|||||||
switch(evtid)
|
switch(evtid)
|
||||||
{
|
{
|
||||||
case event_code::mouse_drop:
|
case event_code::mouse_drop:
|
||||||
wd->flags.dropable = (is_make || (0 != wd->together.attached_events->mouse_dropfiles.length()));
|
wd->flags.dropable = (is_make || (0 != wd->together.events_ptr->mouse_dropfiles.length()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -985,11 +984,15 @@ namespace detail
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto i = std::find_if(attr_cap.begin(), attr_cap.end(),
|
for (auto i = attr_cap.begin(), end = attr_cap.end(); i != end; ++i)
|
||||||
[wd](const std::pair<core_window_t*, bool> & x){ return (x.first == wd);});
|
{
|
||||||
|
if (i->first == wd)
|
||||||
|
{
|
||||||
|
attr_cap.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(i != attr_cap.end())
|
|
||||||
attr_cap.erase(i);
|
|
||||||
return attr_.capture.window;
|
return attr_.capture.window;
|
||||||
}
|
}
|
||||||
return wd;
|
return wd;
|
||||||
|
@ -109,11 +109,11 @@ namespace nana
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
timer_core(timer_identifier tmid, const nana::basic_event<arg_elapse>& evt_elapse)
|
timer_core(timer_identifier tmid, basic_event<arg_elapse>& evt_elapse)
|
||||||
: timer_(tmid), evt_elapse_(evt_elapse)
|
: timer_(tmid), evt_elapse_(evt_elapse)
|
||||||
{}
|
{}
|
||||||
#else
|
#else
|
||||||
timer_core(const nana::basic_event<arg_elapse>& evt_elapse)
|
timer_core(basic_event<arg_elapse>& evt_elapse)
|
||||||
: timer_(this), evt_elapse_(evt_elapse)
|
: timer_(this), evt_elapse_(evt_elapse)
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
@ -138,7 +138,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
const timer_identifier timer_;
|
const timer_identifier timer_;
|
||||||
const nana::basic_event<arg_elapse> & evt_elapse_;
|
nana::basic_event<arg_elapse> & evt_elapse_;
|
||||||
}; //end class timer_core
|
}; //end class timer_core
|
||||||
|
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user