diff --git a/.travis.yml b/.travis.yml index 0629aeb6..09209bba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,7 @@ matrix: before_install: - cd .. - - git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git nana-demo + - git clone --depth=1 --branch=master https://github.com/qPCR4vir/nana-demo.git nana-demo - export PATH="$HOME/bin:$PATH" - wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.12/cmake-3.12.0-rc3-Linux-x86_64.sh || true - chmod -R +x /tmp/tools diff --git a/build/cmake/compilers.cmake b/build/cmake/compilers.cmake index c8db4976..07729e3c 100644 --- a/build/cmake/compilers.cmake +++ b/build/cmake/compilers.cmake @@ -38,13 +38,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AN endif() -if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # APPLE Clang - target_compile_options(nana PUBLIC -stdlib=libstdc++) -endif () - - if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") target_compile_options(nana PRIVATE -fmax-errors=3) endif() - diff --git a/include/nana/c++defines.hpp b/include/nana/c++defines.hpp index 4f00e5f9..4dc62a65 100644 --- a/include/nana/c++defines.hpp +++ b/include/nana/c++defines.hpp @@ -89,7 +89,7 @@ #define NANA_MINGW #endif // MINGW -#elif defined(APPLE) //Mac OS X +#elif defined(__APPLE__) || defined(APPLE) //Mac OS X //Symbols for MACOS #define NANA_MACOS #define NANA_POSIX @@ -252,7 +252,7 @@ # if __has_include() # undef STD_FILESYSTEM_NOT_SUPPORTED # endif -# if __has_include() +# if __has_include() # if !(defined(NANA_MINGW) && !defined(_GLIBCXX_HAS_GTHREADS)) //See the comment above regarding MinGW's threading support # undef STD_THREAD_NOT_SUPPORTED diff --git a/include/nana/filesystem/filesystem.hpp b/include/nana/filesystem/filesystem.hpp index 36f8776d..8aab0cea 100644 --- a/include/nana/filesystem/filesystem.hpp +++ b/include/nana/filesystem/filesystem.hpp @@ -560,7 +560,7 @@ namespace std { #endif } } // std -#else +#else //#if NANA_USING_NANA_FILESYSTEM //Implements the missing functions for various version of experimental/filesystem namespace std { @@ -568,7 +568,7 @@ namespace std { { //Visual Studio 2017 #if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \ - (!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603)) + (!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603 || (__GNUC__* 100 + __GNUC_MINOR__ < 801))) path weakly_canonical(const path& p); path weakly_canonical(const path& p, std::error_code& err); #endif diff --git a/include/nana/gui/timer.hpp b/include/nana/gui/timer.hpp index c360884b..0f28116e 100644 --- a/include/nana/gui/timer.hpp +++ b/include/nana/gui/timer.hpp @@ -48,7 +48,7 @@ namespace nana template void elapse(Function && fn) { - elapse_.connect(std::forward(fn)); + elapse_->connect(std::forward(fn)); } void reset(); @@ -66,7 +66,7 @@ namespace nana private: unsigned _m_interval() const; private: - nana::basic_event elapse_; + std::shared_ptr> elapse_; implement * const impl_; }; }//end namespace nana diff --git a/source/charset.cpp b/source/charset.cpp index 91d7855f..d9a0b0e0 100644 --- a/source/charset.cpp +++ b/source/charset.cpp @@ -1,7 +1,7 @@ /** * A Character Encoding Set Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -245,8 +245,12 @@ namespace nana int bytes = ::WideCharToMultiByte(CP_ACP, 0, s, -1, 0, 0, 0, 0); if(bytes > 1) { - mbstr.resize(bytes - 1); - ::WideCharToMultiByte(CP_ACP, 0, s, -1, &(mbstr[0]), bytes - 1, 0, 0); + // the bytes is the length of the string with null character. + mbstr.resize(bytes); + ::WideCharToMultiByte(CP_ACP, 0, s, -1, &(mbstr[0]), bytes, 0, 0); + + //Remove the null character written by WideCharToMultiByte + mbstr.pop_back(); } return true; #else @@ -279,8 +283,12 @@ namespace nana int chars = ::MultiByteToWideChar(CP_ACP, 0, s, -1, 0, 0); if(chars > 1) { - wcstr.resize(chars - 1); - ::MultiByteToWideChar(CP_ACP, 0, s, -1, &wcstr[0], chars - 1); + // the length of the string with null character. + wcstr.resize(chars); + ::MultiByteToWideChar(CP_ACP, 0, s, -1, &wcstr[0], chars); + + // remove the null character written by MultiByteToWideChar + wcstr.pop_back(); } #else locale_initializer::init(); diff --git a/source/filesystem/filesystem.cpp b/source/filesystem/filesystem.cpp index ae812104..bcd5957c 100644 --- a/source/filesystem/filesystem.cpp +++ b/source/filesystem/filesystem.cpp @@ -1407,7 +1407,7 @@ namespace std namespace filesystem { #if (defined(NANA_USING_STD_EXPERIMENTAL_FILESYSTEM) && defined(_MSC_VER) && (_MSC_VER > 1912)) || \ - (!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603)) + (!defined(__clang__) && defined(__GNUC__) && (__cplusplus < 201603 || (__GNUC__* 100 + __GNUC_MINOR__ < 801))) namespace detail { diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index b3ed3fb4..23f55fa8 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -622,6 +622,7 @@ namespace detail } break; case ConfigureNotify: + ++(root_runtime->x11msg.config); if(msgwnd->dimension.width != static_cast(xevent.xconfigure.width) || msgwnd->dimension.height != static_cast(xevent.xconfigure.height)) { auto & cf = xevent.xconfigure; @@ -890,7 +891,12 @@ namespace detail case MapNotify: case UnmapNotify: if(xevent.type == MapNotify) + { + ++(root_runtime->x11msg.map); x11_apply_exposed_position(native_window); + } + else + ++(root_runtime->x11msg.unmap); brock.event_expose(msgwnd, (xevent.type == MapNotify)); context.platform.motion_window = nullptr; diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index d05a6119..58044bb9 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -173,15 +173,22 @@ namespace detail static LRESULT WINAPI Bedrock_WIN32_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + HINSTANCE windows_module_handle() + { + MEMORY_BASIC_INFORMATION mbi; + static int dummy; + VirtualQuery(&dummy, &mbi, sizeof(mbi)); + return reinterpret_cast(mbi.AllocationBase); + } + bedrock::bedrock() : pi_data_(new pi_data), impl_(new private_impl) { nana::detail::platform_spec::instance(); //to guaranty the platform_spec object is initialized before using. - WNDCLASSEX wincl; - wincl.hInstance = ::GetModuleHandle(0); + wincl.hInstance = windows_module_handle(); wincl.lpszClassName = L"NanaWindowInternal"; wincl.lpfnWndProc = &Bedrock_WIN32_WindowProc; wincl.style = CS_DBLCLKS | CS_OWNDC; @@ -229,6 +236,8 @@ namespace detail delete impl_; delete pi_data_; + + ::UnregisterClass(L"NanaWindowInternal", windows_module_handle()); } diff --git a/source/gui/detail/inner_fwd_implement.hpp b/source/gui/detail/inner_fwd_implement.hpp index af246905..a46d51eb 100644 --- a/source/gui/detail/inner_fwd_implement.hpp +++ b/source/gui/detail/inner_fwd_implement.hpp @@ -21,6 +21,10 @@ #include +#ifdef NANA_X11 +# include +#endif + namespace nana{ namespace detail { @@ -75,6 +79,15 @@ namespace nana{ root_misc(root_misc&&); root_misc(basic_window * wd, unsigned width, unsigned height); ~root_misc(); + +#ifdef NANA_X11 + struct x11msg_confirm + { + std::atomic config{ 0 }; + std::atomic map{ 0 }; + std::atomic unmap{ 0 }; + }x11msg; +#endif private: root_misc(const root_misc&) = delete; root_misc& operator=(const root_misc&) = delete; diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index efe49d21..3804b7e6 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -17,14 +17,15 @@ #include #if defined(NANA_WINDOWS) - #if defined(STD_THREAD_NOT_SUPPORTED) - #include - #else - #include - #endif - #include +# if defined(STD_THREAD_NOT_SUPPORTED) +# include +# else +# include +# endif +# include #elif defined(NANA_X11) - #include +# include +# include "inner_fwd_implement.hpp" #endif #include "../../paint/image_accessor.hpp" @@ -34,6 +35,10 @@ namespace nana{ namespace detail{ #if defined(NANA_WINDOWS) + + //This function is defined in bedrock_windows.cpp + HINSTANCE windows_module_handle(); + class tray_manager { struct window_extra_t @@ -199,26 +204,87 @@ namespace nana{ namespace x11_wait { + struct param + { + Window handle; + root_misc * misc; + std::size_t comp_value; + }; + static Bool configure(Display *disp, XEvent *evt, char *arg) { - return disp && evt && arg && (evt->type == ConfigureNotify) && (evt->xconfigure.window == *reinterpret_cast(arg)); + auto p = reinterpret_cast(arg); + if(p) + { + if(p->misc->x11msg.config != p->comp_value) + return true; + + if(disp && evt && (evt->type == ConfigureNotify)) + { + if(evt->xconfigure.window == p->handle) + return true; + } + } + return false; } static Bool map(Display *disp, XEvent *evt, char *arg) - { - return disp && evt && arg && (evt->type == MapNotify) && (evt->xmap.window == *reinterpret_cast(arg)); + { + auto p = reinterpret_cast(arg); + if(p) + { + if(p->misc->x11msg.map != p->comp_value) + return true; + + if(disp && evt && (evt->type == MapNotify)) + { + if(evt->xmap.window == p->handle) + return true; + } + } + return false; } static Bool unmap(Display *disp, XEvent *evt, char *arg) - { - return disp && evt && arg && (evt->type == MapNotify) && (evt->xunmap.window == *reinterpret_cast(arg)); + { + auto p = reinterpret_cast(arg); + if(p) + { + if(p->misc->x11msg.unmap != p->comp_value) + return true; + + if(disp && evt && (evt->type == UnmapNotify)) + { + if(evt->xunmap.window == p->handle) + return true; + } + } + return false; } } - static void x11_wait_for(Window wd, Bool(*pred_fn)(Display*, XEvent*, char*)) + static void x11_wait_for(Window wd, Bool(*pred_fn)(Display*, XEvent*, char*), std::size_t comp_value) { + auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast(wd)); + x11_wait::param p; + p.handle = wd; + p.misc = misc; + + if(pred_fn == &x11_wait::configure) + p.comp_value = misc->x11msg.config; + else if(pred_fn == &x11_wait::map) + p.comp_value = misc->x11msg.map; + else if(pred_fn == &x11_wait::unmap) + p.comp_value = misc->x11msg.unmap; + + //Checks whether the msg is received. + if(p.comp_value != comp_value) + return; + + p.comp_value = comp_value; + XEvent dummy; - ::XPeekIfEvent(restrict::spec.open_display(), &dummy, pred_fn, reinterpret_cast(&wd)); + ::XPeekIfEvent(restrict::spec.open_display(), &dummy, pred_fn, reinterpret_cast(&p)); } #endif @@ -315,7 +381,7 @@ namespace nana{ HWND native_wd = ::CreateWindowEx(style_ex, L"NanaWindowInternal", L"Nana Window", style, pt.x, pt.y, 100, 100, - reinterpret_cast(owner), 0, ::GetModuleHandle(0), 0); + reinterpret_cast(owner), 0, windows_module_handle(), 0); //A window may have a border, this should be adjusted the client area fit for the specified size. ::RECT client; @@ -504,7 +570,7 @@ namespace nana{ WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, r.x, r.y, r.width, r.height, reinterpret_cast(parent), // The window is a child-window to desktop - 0, ::GetModuleHandle(0), 0); + 0, windows_module_handle(), 0); #elif defined(NANA_X11) nana::detail::platform_scope_guard psg; @@ -758,13 +824,17 @@ namespace nana{ if(show == is_window_visible(wd)) return; + auto misc = bedrock::instance().wd_manager().root_runtime(wd); + if(show) { + std::size_t cmp_value = misc->x11msg.map; + ::XMapWindow(disp, reinterpret_cast(wd)); //Wait for the mapping notify to update the local attribute of visibility so that //the followed window_visible() call can return the updated visibility value. - x11_wait_for(reinterpret_cast(wd), x11_wait::map); + x11_wait_for(reinterpret_cast(wd), x11_wait::map, cmp_value); Window grab = restrict::spec.grab(0); if(grab == reinterpret_cast(wd)) @@ -772,10 +842,12 @@ namespace nana{ } else { + std::size_t cmp_value = misc->x11msg.unmap; ::XUnmapWindow(disp, reinterpret_cast(wd)); + //Wait for the mapping notify to update the local attribute of visibility so that //the followed window_visible() call can return the updated visibility value. - x11_wait_for(reinterpret_cast(wd), x11_wait::unmap); + x11_wait_for(reinterpret_cast(wd), x11_wait::unmap, cmp_value); } } static_cast(active); //eliminate unused parameter compiler warning. @@ -1019,11 +1091,15 @@ namespace nana{ y += origin_y; } + auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast(wd)); + std::size_t cmp_value = misc->x11msg.config; + ::XMoveWindow(disp, reinterpret_cast(wd), x, y); //Wait for the configuration notify to update the local attribute of position so that //the followed window_position() call can return the updated position value. - x11_wait_for(reinterpret_cast(wd), x11_wait::configure); + + x11_wait_for(reinterpret_cast(wd), x11_wait::configure, cmp_value); #endif } @@ -1109,6 +1185,9 @@ namespace nana{ y += origin_y; } + auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast(wd)); + std::size_t cmp_value = misc->x11msg.config; + ::XMoveResizeWindow(disp, reinterpret_cast(wd), x, y, r.width, r.height); //Wait for the configuration notify to update the local attribute of position so that @@ -1116,7 +1195,7 @@ namespace nana{ //It seems that XMoveResizeWindow doesn't need x11_wait_for. But x11_wait_for is still called //to make sure the local attribute is updated. - x11_wait_for(reinterpret_cast(wd), x11_wait::configure); + x11_wait_for(reinterpret_cast(wd), x11_wait::configure, cmp_value); return true; #endif @@ -1283,11 +1362,15 @@ namespace nana{ hints.min_height = hints.max_height = sz.height; ::XSetWMNormalHints(disp, reinterpret_cast(wd), &hints); } + + auto misc = bedrock::instance().wd_manager().root_runtime(reinterpret_cast(wd)); + std::size_t cmp_value = misc->x11msg.config; + ::XResizeWindow(disp, reinterpret_cast(wd), sz.width, sz.height); //It seems that XResizeWindow doesn't need x11_wait_for. But x11_wait_for is still called //to make sure the local attribute is updated. - x11_wait_for(reinterpret_cast(wd), x11_wait::configure); + x11_wait_for(reinterpret_cast(wd), x11_wait::configure, cmp_value); return true; #endif } diff --git a/source/gui/filebox.cpp b/source/gui/filebox.cpp index 06dfed84..f2417087 100644 --- a/source/gui/filebox.cpp +++ b/source/gui/filebox.cpp @@ -1516,14 +1516,24 @@ namespace nana path_type parent_path{ str }; str += (len + 1); - - while(*str) + + // if only one file was selected, the ofn.lpstrFile + // is returning only that file, without any parent + if (!*str) { - len = ::wcslen(str); - targets.emplace_back(parent_path / path_type{str}); - str += (len + 1); + targets.emplace_back(parent_path); + impl_->path = parent_path.parent_path().u8string(); + } + else + { + while(*str) + { + len = ::wcslen(str); + targets.emplace_back(parent_path / path_type{str}); + str += (len + 1); + } + impl_->path = parent_path.u8string(); } - impl_->path = parent_path.u8string(); } else { diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 85ef8dfe..8570c6b0 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -146,7 +146,8 @@ namespace nana //draw caption auto text = to_wstring(API::window_caption(window_handle_)); - text_rd_->render({ 3, 1 }, text.data(), text.size(), graph.size().width - 20, paint::text_renderer::mode::truncate_with_ellipsis); + if((graph.size().width > 20) && (graph.size().width - 20 > 10)) + text_rd_->render({ 3, 1 }, text.data(), text.size(), graph.size().width - 20, paint::text_renderer::mode::truncate_with_ellipsis); //draw x button auto r = _m_button_area(); diff --git a/source/gui/timer.cpp b/source/gui/timer.cpp index 8374a5fb..5e0e75bb 100644 --- a/source/gui/timer.cpp +++ b/source/gui/timer.cpp @@ -111,13 +111,13 @@ namespace nana { public: #if defined(NANA_WINDOWS) - timer_core(timer* sender, timer_identifier tmid, basic_event& evt_elapse): + timer_core(timer* sender, timer_identifier tmid, std::shared_ptr> evt_elapse): sender_(sender), timer_(tmid), evt_elapse_(evt_elapse) {} #else - timer_core(timer* sender, basic_event& evt_elapse): + timer_core(timer* sender, std::shared_ptr> evt_elapse): sender_(sender), timer_(this), evt_elapse_(evt_elapse) @@ -142,12 +142,15 @@ namespace nana { arg_elapse arg; arg.sender = sender_; - evt_elapse_.emit(arg, nullptr); + + //retain the object to avoid it to be deleted during calling of emit + auto retain = evt_elapse_; + retain->emit(arg, nullptr); } private: timer * const sender_; const timer_identifier timer_; - nana::basic_event & evt_elapse_; + std::shared_ptr> evt_elapse_; }; //end class timer_core @@ -175,8 +178,9 @@ namespace nana }; //class timer - timer::timer() - : impl_(new implement) + timer::timer(): + elapse_(std::make_shared>()), + impl_(new implement) { } @@ -195,7 +199,7 @@ namespace nana void timer::reset() { stop(); - elapse_.clear(); + elapse_->clear(); } void timer::start() diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index ab2f3bba..bd3b4a14 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -2314,7 +2314,8 @@ namespace nana size_type count_of_exposed(bool with_rest) const { auto lister_s = this->content_view->view_area().height; - return (lister_s / item_height()) + (with_rest && (lister_s % item_height()) ? 1 : 0); + return (lister_s / item_height()) + (with_rest && + listbox_ptr->scroll_operation()->visible(true) && (lister_s % item_height()) ? 1 : 0); } void update(bool ignore_auto_draw = false) noexcept @@ -3338,16 +3339,27 @@ namespace nana return false; } + // init ir end to grab a header void grab(const nana::point& pos, bool is_grab) { - if(is_grab) + if(is_grab) // init grabbing the header { grabs_.start_pos = pos.x; - if(grabs_.splitter != npos) // resize header item, not move it - grabs_.item_width = essence_->header.at(grabs_.splitter).width_px; + if(grabs_.splitter == npos) // No splitter, no resize header, just moving + return; + + // splitter grabbed - resize the header: take initial width + grabs_.item_width = essence_->header.at(grabs_.splitter).width_px; } - else if((grab_terminal_.index != npos) && (grab_terminal_.index != essence_->pointer_where.second)) - essence_->header.move(essence_->pointer_where.second, grab_terminal_.index, grab_terminal_.place_front); + else // end to grab the header + if (grabs_.splitter != npos) // some Splitter grab, just resizing, no need to move + return; + else if( (grab_terminal_.index != npos) + && (grab_terminal_.index != essence_->pointer_where.second) ) + // move header to terminal position + essence_->header.move(essence_->pointer_where.second, // from + grab_terminal_.index, // to + grab_terminal_.place_front); } //grab_move @@ -4295,7 +4307,10 @@ namespace nana auto const good_list_r = essence_->rect_lister(list_r); auto & ptr_where = essence_->pointer_where; - if((ptr_where.first == parts::header) && (ptr_where.second != npos || (drawer_header_->splitter() != npos))) + + if( (ptr_where.first == parts::header) // click on header + && ( ptr_where.second != npos // in .. + || (drawer_header_->splitter() != npos))) // or splitter { essence_->ptr_state = item_state::pressed; if(good_head_r) @@ -4304,7 +4319,8 @@ namespace nana update = true; } } - else if(ptr_where.first == parts::list || ptr_where.first == parts::checker) + else if( ptr_where.first == parts::list // click on list + || ptr_where.first == parts::checker) // on a checker { index_pair item_pos = lister.advance(essence_->first_display(), static_cast(ptr_where.second)); @@ -4477,13 +4493,16 @@ namespace nana bool need_refresh = false; //Don't sort the column when the mouse is due to released for stopping resizing column. - if ((drawer_header_->splitter() == npos) && essence_->header.attrib().sortable && essence_->pointer_where.first == parts::header && prev_state == item_state::pressed) + if ( (drawer_header_->splitter() == npos) // no header splitter was selected + && essence_->header.attrib().sortable + && essence_->pointer_where.first == parts::header + && prev_state == item_state::pressed) { //Try to sort the column if(essence_->pointer_where.second < essence_->header.cont().size()) need_refresh = essence_->lister.sort_column(essence_->pointer_where.second, nullptr); } - else if (item_state::grabbed == prev_state) + else if (item_state::grabbed == prev_state) // selected splitter and grabbed { nana::point pos = arg.pos; essence_->widget_to_header(pos); @@ -6095,7 +6114,15 @@ namespace nana auto listbox::last_visible() const -> index_pair { - return _m_ess().lister.advance(_m_ess().first_display(), static_cast(_m_ess().count_of_exposed(true))); + if(!const_cast(this)->scroll_operation()->visible(true)) + { + auto last_cat = size_categ()-1; + index_pair ip(last_cat, at(last_cat).size()-1); + if(last_cat == 0 && ip.item == npos) // if the listbox is empty + ip.cat = npos; // return empty index_pair + return ip; + } + return _m_ess().lister.advance(_m_ess().first_display(), static_cast(_m_ess().count_of_exposed(true)-1)); } auto listbox::visibles() const -> index_pairs diff --git a/source/gui/widgets/toolbar.cpp b/source/gui/widgets/toolbar.cpp index f8db43c4..7d1d18f4 100644 --- a/source/gui/widgets/toolbar.cpp +++ b/source/gui/widgets/toolbar.cpp @@ -104,6 +104,7 @@ namespace nana delete ptr; cont_.clear(); + right_ = npos; } @@ -683,6 +684,7 @@ namespace nana if(m && (m->textout != show)) { m->textout = show; + m->pixels = 0; //force width calculation API::refresh_window(this->handle()); } }