implement key_press support for menu in Linux

This commit is contained in:
Jinhao 2017-02-10 08:09:08 +08:00
parent 7a32fa2767
commit 4e42c18815
6 changed files with 42 additions and 35 deletions

View File

@ -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-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Nana Software License, Version 1.0. * Distributed under the Nana 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
@ -1163,8 +1163,16 @@ namespace detail
// 2 = msg_dispatcher should ignore the msg, because the XEvent is processed by _m_msg_filter // 2 = msg_dispatcher should ignore the msg, because the XEvent is processed by _m_msg_filter
int platform_spec::_m_msg_filter(XEvent& evt, msg_packet_tag& msg) int platform_spec::_m_msg_filter(XEvent& evt, msg_packet_tag& msg)
{ {
auto & bedrock = detail::bedrock::instance();
platform_spec & self = instance(); platform_spec & self = instance();
if(SelectionNotify == evt.type) if(KeyPress == evt.type || KeyRelease == evt.type)
{
auto menu_wd = bedrock.get_menu(reinterpret_cast<native_window_type>(evt.xkey.window), true);
if(menu_wd)
evt.xkey.window = reinterpret_cast<Window>(menu_wd);
}
else if(SelectionNotify == evt.type)
{ {
if(evt.xselection.property) if(evt.xselection.property)
{ {
@ -1197,7 +1205,6 @@ namespace detail
} }
} }
self.selection_.items.erase(self.selection_.items.begin()); self.selection_.items.erase(self.selection_.items.begin());
std::lock_guard<decltype(im->cond_mutex)> lock(im->cond_mutex); std::lock_guard<decltype(im->cond_mutex)> lock(im->cond_mutex);
@ -1373,9 +1380,8 @@ namespace detail
{ {
Window child; Window child;
::XTranslateCoordinates(self.display_, self.root_window(), evt.xclient.window, x, y, &self.xdnd_.pos.x, &self.xdnd_.pos.y, &child); ::XTranslateCoordinates(self.display_, self.root_window(), evt.xclient.window, x, y, &self.xdnd_.pos.x, &self.xdnd_.pos.y, &child);
typedef detail::bedrock bedrock;
auto wd = bedrock::instance().wd_manager().find_window(reinterpret_cast<native_window_type>(evt.xclient.window), self.xdnd_.pos.x, self.xdnd_.pos.y); auto wd = bedrock.wd_manager().find_window(reinterpret_cast<native_window_type>(evt.xclient.window), self.xdnd_.pos.x, self.xdnd_.pos.y);
if(wd && wd->flags.dropable) if(wd && wd->flags.dropable)
{ {
accepted = true; accepted = true;

View File

@ -1,6 +1,6 @@
/* /*
* Message Dispatcher Implementation * Message Dispatcher Implementation
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 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
@ -51,7 +51,7 @@ namespace detail
typedef std::list<msg_packet_tag> msg_queue_type; typedef std::list<msg_packet_tag> msg_queue_type;
msg_dispatcher(Display* disp) msg_dispatcher(Display* disp)
: display_(disp), is_work_(false) : display_(disp)
{ {
proc_.event_proc = 0; proc_.event_proc = 0;
proc_.timer_proc = 0; proc_.timer_proc = 0;
@ -338,7 +338,7 @@ namespace detail
private: private:
Display * display_; Display * display_;
volatile bool is_work_; volatile bool is_work_{ false };
std::unique_ptr<std::thread> thrd_; std::unique_ptr<std::thread> thrd_;
struct table_tag struct table_tag

View File

@ -1147,7 +1147,7 @@ namespace detail
} }
} }
void bedrock::pump_event(window modal_window, bool /*is_modal*/) void bedrock::pump_event(window condition_wd, bool is_modal)
{ {
thread_context * context = open_thread_context(); thread_context * context = open_thread_context();
if(0 == context->window_count) if(0 == context->window_count)
@ -1162,11 +1162,11 @@ namespace detail
auto & lock = wd_manager().internal_lock(); auto & lock = wd_manager().internal_lock();
lock.revert(); lock.revert();
native_window_type owner_native = 0; native_window_type owner_native{};
core_window_t * owner = 0; core_window_t * owner = 0;
if(modal_window) if(condition_wd && is_modal)
{ {
native_window_type modal = reinterpret_cast<core_window_t*>(modal_window)->root; native_window_type modal = reinterpret_cast<core_window_t*>(condition_wd)->root;
owner_native = native_interface::get_owner_window(modal); owner_native = native_interface::get_owner_window(modal);
if(owner_native) if(owner_native)
{ {
@ -1177,7 +1177,7 @@ namespace detail
} }
} }
nana::detail::platform_spec::instance().msg_dispatch(modal_window ? reinterpret_cast<core_window_t*>(modal_window)->root : 0); nana::detail::platform_spec::instance().msg_dispatch(condition_wd ? reinterpret_cast<core_window_t*>(condition_wd)->root : 0);
if(owner_native) if(owner_native)
{ {
@ -1190,7 +1190,7 @@ namespace detail
if(0 == --(context->event_pump_ref_count)) if(0 == --(context->event_pump_ref_count))
{ {
if(0 == modal_window || 0 == context->window_count) if(0 == condition_wd || 0 == context->window_count)
remove_thread_context(); remove_thread_context();
} }

View File

@ -345,7 +345,7 @@ namespace detail
} }
} }
void bedrock::pump_event(window modal_window, bool is_modal) void bedrock::pump_event(window condition_wd, bool is_modal)
{ {
const unsigned tid = ::GetCurrentThreadId(); const unsigned tid = ::GetCurrentThreadId();
auto context = this->open_thread_context(tid); auto context = this->open_thread_context(tid);
@ -365,9 +365,9 @@ namespace detail
try try
{ {
MSG msg; MSG msg;
if(modal_window) if (condition_wd)
{ {
HWND native_handle = reinterpret_cast<HWND>(reinterpret_cast<core_window_t*>(modal_window)->root); HWND native_handle = reinterpret_cast<HWND>(reinterpret_cast<core_window_t*>(condition_wd)->root);
if (is_modal) if (is_modal)
{ {
HWND owner = ::GetWindow(native_handle, GW_OWNER); HWND owner = ::GetWindow(native_handle, GW_OWNER);
@ -437,8 +437,8 @@ namespace detail
} }
catch(std::exception& e) catch(std::exception& e)
{ {
(msgbox(modal_window, "An uncaptured std::exception during message pumping: ").icon(msgbox::icon_information) (msgbox(condition_wd, "An uncaptured std::exception during message pumping: ").icon(msgbox::icon_information)
<<"\n in form: "<< API::window_caption(modal_window) << "\n in form: " << API::window_caption(condition_wd)
<<"\n exception : "<< e.what() <<"\n exception : "<< e.what()
).show(); ).show();
@ -448,16 +448,16 @@ namespace detail
intr_locker.forward(); intr_locker.forward();
if (0 == --(context->event_pump_ref_count)) if (0 == --(context->event_pump_ref_count))
{ {
if ((nullptr == modal_window) || (0 == context->window_count)) if ((nullptr == condition_wd) || (0 == context->window_count))
remove_thread_context(); remove_thread_context();
} }
throw; throw;
} }
catch(...) catch(...)
{ {
(msgbox(modal_window, "An exception during message pumping!").icon(msgbox::icon_information) (msgbox(condition_wd, "An exception during message pumping!").icon(msgbox::icon_information)
<<"An uncaptured non-std exception during message pumping!" <<"An uncaptured non-std exception during message pumping!"
<< "\n in form: " << API::window_caption(modal_window) << "\n in form: " << API::window_caption(condition_wd)
).show(); ).show();
internal_scope_guard lock; internal_scope_guard lock;
_m_except_handler(); _m_except_handler();
@ -465,7 +465,7 @@ namespace detail
intr_locker.forward(); intr_locker.forward();
if(0 == --(context->event_pump_ref_count)) if(0 == --(context->event_pump_ref_count))
{ {
if((nullptr == modal_window) || (0 == context->window_count)) if ((nullptr == condition_wd) || (0 == context->window_count))
remove_thread_context(); remove_thread_context();
} }
throw; throw;
@ -474,7 +474,7 @@ namespace detail
intr_locker.forward(); intr_locker.forward();
if(0 == --(context->event_pump_ref_count)) if(0 == --(context->event_pump_ref_count))
{ {
if((nullptr == modal_window) || (0 == context->window_count)) if ((nullptr == condition_wd) || (0 == context->window_count))
remove_thread_context(); remove_thread_context();
} }
}//end pump_event }//end pump_event

View File

@ -747,7 +747,7 @@ namespace nana
//add a is_wd_parent_menu to determine whether the menu wants the focus. //add a is_wd_parent_menu to determine whether the menu wants the focus.
//if a submenu gets the focus, the program may cause a crash error when the submenu is being destroyed //if a submenu gets the focus, the program may cause a crash error when the submenu is being destroyed
: base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald<appear::floating>()), : base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald<appear::floating>()),
want_focus_{ (!wd) || ((!is_wd_parent_menu) && (API::focus_window() != wd)) }, want_focus_{ (!wd) || ((!is_wd_parent_menu) && (API::root(API::focus_window()) != API::root(wd))) },
event_focus_{ nullptr } event_focus_{ nullptr }
{ {
caption("nana menu window"); caption("nana menu window");

View File

@ -116,6 +116,7 @@ namespace nana{ namespace system{
//#elif defined(NANA_X11) //#elif defined(NANA_X11)
#else #else
static_cast<void>(g); //eliminate unused parameter compiler warning. static_cast<void>(g); //eliminate unused parameter compiler warning.
static_cast<void>(owner);
throw "not implemented yet."; throw "not implemented yet.";
return false; return false;
#endif #endif