diff --git a/include/nana/gui/detail/inner_fwd_implement.hpp b/include/nana/gui/detail/inner_fwd_implement.hpp index 5384aec4..833c7668 100644 --- a/include/nana/gui/detail/inner_fwd_implement.hpp +++ b/include/nana/gui/detail/inner_fwd_implement.hpp @@ -121,7 +121,6 @@ namespace nana{ { core_window_t* pressed{nullptr}; //The handle to a window which is being pressed core_window_t* hovered{nullptr}; //the latest window that mouse moved - bool tabstop_focus_changed{false}; //KeyDown may set it true, if it is true KeyChar will ignore the message }condition; root_misc(core_window_t * wd, unsigned width, unsigned height) diff --git a/source/detail/linux_X11/platform_spec.cpp b/source/detail/linux_X11/platform_spec.cpp index f53c046b..c8ccf682 100644 --- a/source/detail/linux_X11/platform_spec.cpp +++ b/source/detail/linux_X11/platform_spec.cpp @@ -44,7 +44,7 @@ namespace detail bool conf::open(const char* file) { ifs_.open(file); - return static_cast(ifs_ != 0); + return static_cast(ifs_); } std::string conf::value(const char* key) diff --git a/source/gui/detail/linux_X11/bedrock.cpp b/source/gui/detail/linux_X11/bedrock.cpp index 1a5a1ecc..d484cbb1 100644 --- a/source/gui/detail/linux_X11/bedrock.cpp +++ b/source/gui/detail/linux_X11/bedrock.cpp @@ -1032,7 +1032,6 @@ namespace detail { brock.wd_manager.set_focus(the_next, false); brock.wd_manager.do_lazy_refresh(the_next, true); - root_runtime->condition.tabstop_focus_changed = true; } } else if(keyboard::alt == keychar) @@ -1081,6 +1080,7 @@ namespace detail break; } case XLookupChars: + if (msgwnd->flags.enabled) { const ::nana::char_t* charbuf; #if defined(NANA_UNICODE) @@ -1097,6 +1097,10 @@ namespace detail arg.ignore = false; arg.key = charbuf[i]; + // When tab is pressed, only tab-eating mode is allowed + if ((keyboard::tab == arg.key) && !(msgwnd->flags.tab & tab_type::eating)) + continue; + if(context.is_alt_pressed) { arg.ctrl = arg.shift = false; diff --git a/source/gui/detail/win32/bedrock.cpp b/source/gui/detail/win32/bedrock.cpp index daeb369d..8cd5231c 100644 --- a/source/gui/detail/win32/bedrock.cpp +++ b/source/gui/detail/win32/bedrock.cpp @@ -1408,7 +1408,6 @@ namespace detail brock.wd_manager.set_focus(the_next, false); brock.wd_manager.do_lazy_refresh(msgwnd, false); brock.wd_manager.do_lazy_refresh(the_next, true); - root_runtime->condition.tabstop_focus_changed = true; } } else @@ -1437,9 +1436,10 @@ namespace detail break; case WM_CHAR: msgwnd = brock.focus(); - if(false == root_runtime->condition.tabstop_focus_changed) + if (msgwnd && msgwnd->flags.enabled) { - if(msgwnd && msgwnd->flags.enabled) + // When tab is pressed, only tab-eating mode is allowed + if ((9 != wParam) || (msgwnd->flags.tab & tab_type::eating)) { arg_keyboard arg; arg.evt_code = event_code::key_char; @@ -1455,8 +1455,6 @@ namespace detail brock.wd_manager.do_lazy_refresh(msgwnd, false); } } - else - root_runtime->condition.tabstop_focus_changed = false; return 0; case WM_KEYUP: if(wParam != 18) //MUST NOT BE AN ALT diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 44444659..30c497fa 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -493,9 +493,6 @@ namespace detail wd->pos_owner.y = y; _m_move_core(wd, delta); - if(wd->together.caret && wd->together.caret->visible()) - wd->together.caret->update(); - auto &brock = bedrock::instance(); arg_move arg; arg.window_handle = reinterpret_cast(wd); @@ -522,7 +519,7 @@ namespace detail auto & brock = bedrock::instance(); bool moved = false; const bool size_changed = (r.width != wd->dimension.width || r.height != wd->dimension.height); - if(wd->other.category != category::root_tag::value) + if(category::flags::root != wd->other.category) { //Move child widgets if(r.x != wd->pos_owner.x || r.y != wd->pos_owner.y) @@ -533,9 +530,6 @@ namespace detail _m_move_core(wd, delta); moved = true; - if(wd->together.caret && wd->together.caret->visible()) - wd->together.caret->update(); - arg_move arg; arg.window_handle = reinterpret_cast(wd); arg.x = r.x; @@ -1019,35 +1013,35 @@ namespace detail } } + + // preconditions of get_tabstop: tabstop is not empty and at least one window is visible window_manager::core_window_t* get_tabstop(window_manager::core_window_t* wd, bool forward) { auto & tabs = wd->root_widget->other.attribute.root->tabstop; - if (tabs.size()) + + if (forward) { - if (forward) // + if (detail::tab_type::none == wd->flags.tab) + return (tabs.front()); + else if (detail::tab_type::tabstop & wd->flags.tab) { - if (detail::tab_type::none == wd->flags.tab) - return (tabs.front()); - else if (detail::tab_type::tabstop & wd->flags.tab) + auto end = tabs.cend(); + auto i = std::find(tabs.cbegin(), end, wd); + if (i != end) { - auto end = tabs.cend(); - auto i = std::find(tabs.cbegin(), end, wd); - if (i != end) - { - ++i; - window_manager::core_window_t* ts = (i != end ? (*i) : tabs.front()); - return (ts != wd ? ts : 0); - } - else - return tabs.front(); + ++i; + window_manager::core_window_t* ts = (i != end ? (*i) : tabs.front()); + return (ts != wd ? ts : 0); } + else + return tabs.front(); } - else if (tabs.size() > 1) //at least 2 elments in tabs is required when moving perviously. - { - auto i = std::find(tabs.cbegin(), tabs.cend(), wd); - if (i != tabs.cend()) - return (tabs.cbegin() == i ? tabs.back() : *(i - 1)); - } + } + else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward. + { + auto i = std::find(tabs.cbegin(), tabs.cend(), wd); + if (i != tabs.cend()) + return (tabs.cbegin() == i ? tabs.back() : *(i - 1)); } return nullptr; } @@ -1059,17 +1053,31 @@ namespace detail if (!impl_->wd_register.available(wd)) return nullptr; - auto new_stop = get_tabstop(wd, forward); + auto & tabs = wd->root_widget->other.attribute.root->tabstop; + if (tabs.empty()) + return nullptr; - while (new_stop) + bool precondition = false; + for (auto & tab_wd : tabs) { - if (wd == new_stop) + if (tab_wd->visible) + { + precondition = true; break; + } + } - if (new_stop->flags.enabled && new_stop->visible) - return new_stop; + if (precondition) + { + auto new_stop = get_tabstop(wd, forward); - new_stop = get_tabstop(new_stop, forward); + while (new_stop && (wd != new_stop)) + { + if (new_stop->flags.enabled && new_stop->visible) + return new_stop; + + new_stop = get_tabstop(new_stop, forward); + } } return nullptr; @@ -1411,7 +1419,12 @@ namespace detail if(wd->other.category != category::root_tag::value) //A root widget always starts at (0, 0) and its childs are not to be changed { wd->pos_root += delta; - if(wd->other.category == category::frame_tag::value) + if (category::flags::frame != wd->other.category) + { + if (wd->together.caret && wd->together.caret->visible()) + wd->together.caret->update(); + } + else native_interface::move_window(wd->other.attribute.frame->container, wd->pos_root.x, wd->pos_root.y); for (auto child : wd->children) diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 1050affa..807d2b75 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -700,15 +700,18 @@ namespace nana class menu_window : public widget_object { - typedef menu_drawer drawer_type; - typedef widget_object base_type; + using drawer_type = menu_drawer; + using base_type = widget_object; public: - typedef menu_builder::item_type item_type; + using item_type = menu_builder::item_type; - menu_window(window wd, const point& pos, renderer_interface * rdptr) + + menu_window(window wd, bool is_wd_parent_menu, const point& pos, renderer_interface * rdptr) + //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 : base_type(wd, false, rectangle(pos, nana::size(2, 2)), appear::bald()), - want_focus_(nullptr == wd || (API::focus_window() != wd)), - event_focus_(nullptr) + want_focus_{ (!wd) || ((!is_wd_parent_menu) && (API::focus_window() != wd)) }, + event_focus_{ nullptr } { caption(STR("nana menu window")); get_drawer_trigger().close_menu_tree([this]{ this->_m_close_all(); }); @@ -1012,7 +1015,7 @@ namespace nana pos.x += sbm->gaps.x; pos.y += sbm->gaps.y; - menu_window & mwnd = form_loader()(handle(), pos, mdtrigger.renderer); + menu_window & mwnd = form_loader()(handle(), true, pos, mdtrigger.renderer); mwnd.state_.self_submenu = true; submenu_.child = & mwnd; submenu_.child->submenu_.parent = this; @@ -1294,7 +1297,7 @@ namespace nana { close(); - impl_->uiobj = &(form_loader()(wd, point(x, y), &(*impl_->mbuilder.renderer()))); + impl_->uiobj = &(form_loader()(wd, false, point(x, y), &(*impl_->mbuilder.renderer()))); impl_->uiobj->events().destroy.connect_unignorable([this]{ impl_->uiobj = nullptr; if (impl_->destroy_answer) diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 0a2f9261..69cf0b6a 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1482,6 +1482,8 @@ namespace nana{ namespace widgets behavior_->pre_calc_lines(width_pixels()); _m_scrollbar(); + + move_caret(points_.caret); return true; }