wxTreebook items flicker when switching pages, see video:
https://github.com/user-attachments/assets/498136dd-c739-4810-bc8d-df695d448d17
widgets sample—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Is this something you observer in KiCad too? The widgets sample has special code for creating pages on demand and this could be responsible for it, especially because I don't see any obvious flicker in the notebook sample (after switching to using wxTreebook).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Yes, KiCad also lazy-loads pages.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Do you do it in wxEVT_TREEBOOK_PAGE_CHANGED handler, as the sample does? I think flicker is unavoidable in this case because the page is shown before it's created.
It should be possible to create the page contents when its Show() is called (only once, of course), we probably didn't do it in the widgets sample to keep the code simpler or just because nobody thought of this...
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Looks like KiCad already resolves the pages on show: https://gitlab.com/kicad/code/kicad/-/blob/df8ecb877ad9b957ac10cd0769f4e397a1974599/common/widgets/wx_treebook.cpp#L63
Looks like it gets worse with each loaded lazy page:
https://github.com/user-attachments/assets/8791a1c4-12ab-4e90-9af8-de288dbfcf41
LAZY_PAGE::Show stack trace
> _eeschema.dll!LAZY_PAGE::Show(bool show=false) Line 62 C++
wxmsw330ud_core_vc_x64_custom.dll!wxBookCtrlBase::DoShowPage(wxWindow * page=0x00000231bf8f77b0, bool show=false) Line 291 C++
wxmsw330ud_core_vc_x64_custom.dll!wxBookCtrlBase::DoSetSelection(unsigned __int64 n=20, int flags=1) Line 524 C++
wxmsw330ud_core_vc_x64_custom.dll!wxTreebook::SetSelection(unsigned __int64 n=20) Line 130 C++
wxmsw330ud_core_vc_x64_custom.dll!wxTreebook::OnTreeSelectionChange(wxTreeEvent & event={...}) Line 603 C++
wxbase330ud_vc_x64_custom.dll!wxAppConsoleBase::HandleEvent(wxEvtHandler * handler=0x00000231bf316060, void(wxEvtHandler::*)(wxEvent &) func=0x00000231b10e9700, wxEvent & event={...}) Line 663 C++
wxbase330ud_vc_x64_custom.dll!wxAppConsoleBase::CallEventHandler(wxEvtHandler * handler=0x00000231bf316060, wxEventFunctor & functor={...}, wxEvent & event={...}) Line 675 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase & entry={...}, wxEvtHandler * handler=0x00000231bf316060, wxEvent & event={...}) Line 1467 C++
wxbase330ud_vc_x64_custom.dll!wxEventHashTable::HandleEvent(wxEvent & event={...}, wxEvtHandler * self=0x00000231bf316060) Line 1073 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::TryHereOnly(wxEvent & event={...}) Line 1654 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::TryBeforeAndHere(wxEvent & event={...}) Line 4072 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::ProcessEventLocally(wxEvent & event={...}) Line 1587 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::ProcessEvent(wxEvent & event={...}) Line 1560 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindowBase::TryAfter(wxEvent & event={...}) Line 3507 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::ProcessEvent(wxEvent & event={...}) Line 1573 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::SafelyProcessEvent::__l2::<lambda>() Line 1675 C++
wxbase330ud_vc_x64_custom.dll!wxSafeCall<bool,bool <lambda>(void),bool <lambda>(void)>(const wxEvtHandler::SafelyProcessEvent::__l2::bool <lambda>(void) & func=bool <lambda>(void){...}, const wxEvtHandler::SafelyProcessEvent::__l2::bool <lambda>(void) & handler=bool <lambda>(void){...}) Line 40 C++
wxbase330ud_vc_x64_custom.dll!wxEvtHandler::SafelyProcessEvent(wxEvent & event={...}) Line 1683 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindowBase::HandleWindowEvent(wxEvent & event={...}) Line 1511 C++
wxmsw330ud_core_vc_x64_custom.dll!wxTreeCtrl::HandleTreeEvent(wxTreeEvent & event={...}) Line 1156 C++
wxmsw330ud_core_vc_x64_custom.dll!wxTreeCtrl::MSWOnNotify(int idCtrl=-31576, __int64 lParam=2412447184640, __int64 * result=0x00000231b10ea338) Line 3788 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::HandleNotify(int idCtrl=-31576, __int64 lParam=2412447184640, __int64 * result=0x00000231b10ea338) Line 4184 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::MSWHandleMessage(__int64 * result=0x00000231b10eb148, unsigned int message=78, unsigned __int64 wParam=18446744073709520040, __int64 lParam=2412447184640) Line 3289 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::MSWWindowProc(unsigned int message=78, unsigned __int64 wParam=18446744073709520040, __int64 lParam=2412447184640) Line 3975 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWndProc(HWND__ * hWnd=0x0000000001181a3e, unsigned int message=78, unsigned __int64 wParam=18446744073709520040, __int64 lParam=2412447184640) Line 3020 C++
user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 (*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,void *,int) Unknown
user32.dll!DispatchClientMessage() Unknown
user32.dll!__fnDWORD() Unknown
ntdll.dll!KiUserCallbackDispatcherContinue() Unknown
win32u.dll!NtUserMessageCall() Unknown
user32.dll!SendMessageWorker() Unknown
user32.dll!SendMessageInternal(struct HWND__ *,unsigned int,unsigned __int64,__int64,int) Unknown
user32.dll!SendMessageW() Unknown
comctl32.dll!CCSendNotify() Unknown
comctl32.dll!TV_SendSelChange(struct _TREE *,int,struct _TREEITEM *,struct _TREEITEM *,unsigned int) Unknown
comctl32.dll!TV_SelectItem(struct _TREE *,unsigned __int64,struct _TREEITEM *,unsigned int,unsigned int) Unknown
comctl32.dll!TV_ButtonDown(struct _TREE *,unsigned int,unsigned int,int,int,unsigned int) Unknown
comctl32.dll!TV_WndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64) Unknown
user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 (*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,void *,int) Unknown
user32.dll!CallWindowProcW() Unknown
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::MSWDefWindowProc(unsigned int nMsg=513, unsigned __int64 wParam=1, __int64 lParam=24117305) Line 2570 C++
wxmsw330ud_core_vc_x64_custom.dll!wxTreeCtrl::MSWDefWindowProc(unsigned int nMsg=513, unsigned __int64 wParam=1, __int64 lParam=24117305) Line 3371 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::MSWWindowProc(unsigned int message=513, unsigned __int64 wParam=1, __int64 lParam=24117305) Line 3981 C++
wxmsw330ud_core_vc_x64_custom.dll!wxTreeCtrl::MSWWindowProc(unsigned int nMsg=513, unsigned __int64 wParam=1, __int64 lParam=24117305) Line 3333 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWndProc(HWND__ * hWnd=0x0000000000cc1fc6, unsigned int message=513, unsigned __int64 wParam=1, __int64 lParam=24117305) Line 3020 C++
user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 (*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,void *,int) Unknown
user32.dll!CallWindowProcW() Unknown
comctl32.dll!CallNextSubclassProc() Unknown
comctl32.dll!TTSubclassProc(struct HWND__ *,unsigned int,unsigned __int64,__int64,unsigned __int64,unsigned __int64) Unknown
comctl32.dll!CallNextSubclassProc() Unknown
comctl32.dll!MasterSubclassProc() Unknown
user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 (*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,void *,int) Unknown
user32.dll!DispatchMessageWorker() Unknown
user32.dll!IsDialogMessageW() Unknown
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::MSWSafeIsDialogMessage(tagMSG * msg=0x00000231b10ee4f8) Line 2885 C++
wxmsw330ud_core_vc_x64_custom.dll!wxWindow::MSWProcessMessage(tagMSG * pMsg=0x00000231b10ee4f8) Line 2777 C++
wxmsw330ud_core_vc_x64_custom.dll!wxGUIEventLoop::PreProcessMessage(tagMSG * msg=0x00000231b10ee4f8) Line 103 C++
wxmsw330ud_core_vc_x64_custom.dll!wxGUIEventLoop::ProcessMessage(tagMSG * msg=0x00000231b10ee4f8) Line 121 C++
wxmsw330ud_core_vc_x64_custom.dll!wxGUIEventLoop::Dispatch() Line 179 C++
wxbase330ud_vc_x64_custom.dll!wxEventLoopManual::ProcessEvents() Line 247 C++
wxbase330ud_vc_x64_custom.dll!wxEventLoopManual::DoRunLoop() Line 288 C++
wxbase330ud_vc_x64_custom.dll!wxEventLoopManual::DoRun::__l4::<lambda>() Line 369 C++
wxbase330ud_vc_x64_custom.dll!wxSafeCall<void,void <lambda>(void),void <lambda>(void)>(const wxEventLoopManual::DoRun::__l4::void <lambda>(void) & func=void <lambda>(void){...}, const wxEventLoopManual::DoRun::__l4::void <lambda>(void) & handler=void <lambda>(void){...}) Line 40 C++
wxbase330ud_vc_x64_custom.dll!wxEventLoopManual::DoRun() Line 364 C++
wxbase330ud_vc_x64_custom.dll!wxEventLoopBase::Run() Line 88 C++
wxmsw330ud_core_vc_x64_custom.dll!wxDialogModalData::RunLoop() Line 61 C++
wxmsw330ud_core_vc_x64_custom.dll!wxDialog::ShowModal() Line 254 C++
kicommon.dll!DIALOG_SHIM::ShowModal() Line 1219 C++
_eeschema.dll!EDA_BASE_FRAME::ShowPreferences(wxString aStartPage={...}, wxString aStartParentPage={...}) Line 1511 C++
_eeschema.dll!COMMON_CONTROL::OpenPreferences(const TOOL_EVENT & aEvent={...}) Line 75 C++
_eeschema.dll!std::invoke<int (__cdecl COMMON_CONTROL::*&)(TOOL_EVENT const &),COMMON_CONTROL * &,TOOL_EVENT const &>(int(COMMON_CONTROL::*)(const TOOL_EVENT &) & _Obj=0x00007ffeac1647d5, COMMON_CONTROL * & _Arg1=0x00000231bb8d5160, const TOOL_EVENT & <_Args2_0>={...}) Line 1726 C++
_eeschema.dll!std::_Invoker_ret<std::_Unforced>::_Call<int (__cdecl COMMON_CONTROL::*&)(TOOL_EVENT const &),COMMON_CONTROL * &,TOOL_EVENT const &>(int(COMMON_CONTROL::*)(const TOOL_EVENT &) & _Func=0x00007ffeac1647d5, COMMON_CONTROL * & <_Vals_0>=0x00000231bb8d5160, const TOOL_EVENT & <_Vals_1>={...}) Line 2112 C++
_eeschema.dll!std::_Call_binder<std::_Unforced,0,1,int (__cdecl COMMON_CONTROL::*)(TOOL_EVENT const &),std::tuple<COMMON_CONTROL *,std::_Ph<1>>,std::tuple<TOOL_EVENT const &>>(std::_Invoker_ret<std::_Unforced> __formal={...}, std::integer_sequence<unsigned __int64,0,1> __formal={...}, int(COMMON_CONTROL::*)(const TOOL_EVENT &) & _Obj=0x00007ffeac1647d5, std::tuple<COMMON_CONTROL *,std::_Ph<1>> & _Tpl={...}, std::tuple<TOOL_EVENT const &> && _Ut={...}) Line 2122 C++
_eeschema.dll!std::_Binder<std::_Unforced,int (__cdecl COMMON_CONTROL::*&)(TOOL_EVENT const &),COMMON_CONTROL *,std::_Ph<1> const &>::operator()<TOOL_EVENT const &>(const TOOL_EVENT & <_Unbargs_0>={...}) Line 2176 C++
_eeschema.dll!std::invoke<std::_Binder<std::_Unforced,int (__cdecl COMMON_CONTROL::*&)(TOOL_EVENT const &),COMMON_CONTROL *,std::_Ph<1> const &> &,TOOL_EVENT const &>(std::_Binder<std::_Unforced,int (__cdecl COMMON_CONTROL::*&)(TOOL_EVENT const &),COMMON_CONTROL *,std::_Ph<1> const &> & _Obj={...}, const TOOL_EVENT & _Arg1={...}) Line 1726 C++
_eeschema.dll!std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,int (__cdecl COMMON_CONTROL::*&)(TOOL_EVENT const &),COMMON_CONTROL *,std::_Ph<1> const &>,int,TOOL_EVENT const &>::_Do_call(const TOOL_EVENT & <_Args_0>={...}) Line 883 C++
_eeschema.dll!std::_Func_class<int,TOOL_EVENT const &>::operator()(const TOOL_EVENT & <_Args_0>={...}) Line 926 C++
_eeschema.dll!COROUTINE<int,TOOL_EVENT const &>::callerStub(__int64 aData=956442854920) Line 513 C++
_eeschema.dll!make_fcontext() Unknown
000000deb06fc608() Unknown
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Also I see no flicker when using arrow keys.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I see no possible explanation for why it would behave differently depending on whether you change the page using the keyboard or the mouse. I do see that we can have flicker even when creating page on demand when showing it because we hide the old page first, then create the one about to be shown (which can take time...) and only then show it.
In wxTreebook case, specifically, we do have the new page in the CHANGING event, so it could actually be better to create the new page there, then hiding/showing should happen without any delay.
I also wonder if there is some way to measure flicker objectively because I often have trouble determining if my changes make things better or worse or don't change anything at all, especially after looking at them many times in a row.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()