@@ -150,6 +150,56 @@ bool ImGuiEx::Canvas::Begin(ImGuiID id, const ImVec2& size)
150150
151151 m_InBeginEnd = true ;
152152
153+ auto beginWindowHook = ImGuiContextHook{};
154+ beginWindowHook.UserData = this ;
155+ beginWindowHook.Type = ImGuiContextHookType_BeginWindow;
156+ beginWindowHook.Callback = [](ImGuiContext* context, ImGuiContextHook* hook)
157+ {
158+ // ImGui::SetNextWindowViewport( ImGui::GetCurrentWindow()->Viewport->ID );
159+
160+ auto canvas = reinterpret_cast <Canvas*>(hook->UserData );
161+ if (canvas->m_SuspendCounter == 0 )
162+ {
163+ if ((context->NextWindowData .Flags & ImGuiNextWindowDataFlags_HasPos) != 0 )
164+ {
165+ auto pos = canvas->FromLocal (context->NextWindowData .PosVal );
166+ ImGui::SetNextWindowPos (pos, context->NextWindowData .PosCond , context->NextWindowData .PosPivotVal );
167+ }
168+
169+ if (context->BeginPopupStack .size ())
170+ {
171+ auto & popup = context->BeginPopupStack .back ();
172+ popup.OpenPopupPos = canvas->FromLocal (popup.OpenPopupPos );
173+ popup.OpenMousePos = canvas->FromLocal (popup.OpenMousePos );
174+ }
175+
176+ if (context->OpenPopupStack .size ())
177+ {
178+ auto & popup = context->OpenPopupStack .back ();
179+ popup.OpenPopupPos = canvas->FromLocal (popup.OpenPopupPos );
180+ popup.OpenMousePos = canvas->FromLocal (popup.OpenMousePos );
181+ }
182+
183+ }
184+ canvas->m_BeginWindowCursorBackup = ImGui::GetCursorScreenPos ();
185+ canvas->Suspend ();
186+ };
187+
188+ m_beginWindowHook = ImGui::AddContextHook (ImGui::GetCurrentContext (), &beginWindowHook);
189+
190+ auto endWindowHook = ImGuiContextHook{};
191+ endWindowHook.UserData = this ;
192+ endWindowHook.Type = ImGuiContextHookType_EndWindow;
193+ endWindowHook.Callback = [](ImGuiContext* ctx, ImGuiContextHook* hook)
194+ {
195+ auto canvas = reinterpret_cast <Canvas*>(hook->UserData );
196+ canvas->Resume ();
197+ ImGui::SetCursorScreenPos (canvas->m_BeginWindowCursorBackup );
198+ ImGui::GetCurrentWindow ()->DC .IsSetPos = false ;
199+ };
200+
201+ m_endWindowHook = ImGui::AddContextHook (ImGui::GetCurrentContext (), &endWindowHook);
202+
153203 return true ;
154204}
155205
@@ -185,6 +235,9 @@ void ImGuiEx::Canvas::End()
185235 // m_DrawList->AddRect(m_WidgetPosition - ImVec2(1.0f, 1.0f), m_WidgetPosition + m_WidgetSize + ImVec2(1.0f, 1.0f), IM_COL32(196, 0, 0, 255));
186236
187237 m_InBeginEnd = false ;
238+
239+ ImGui::RemoveContextHook (ImGui::GetCurrentContext (), m_beginWindowHook);
240+ ImGui::RemoveContextHook (ImGui::GetCurrentContext (), m_endWindowHook);
188241}
189242
190243void ImGuiEx::Canvas::SetView (const ImVec2& origin, float scale)
@@ -561,6 +614,23 @@ void ImGuiEx::Canvas::LeaveLocalSpace()
561614 m_DrawList->CmdBuffer .erase (m_DrawList->CmdBuffer .Data + m_DrawListCommadBufferSize);
562615 else if (m_DrawList->CmdBuffer .size () >= m_DrawListCommadBufferSize && m_DrawList->CmdBuffer [m_DrawListCommadBufferSize - 1 ].UserCallback == ImDrawCallback_ImCanvas)
563616 m_DrawList->CmdBuffer .erase (m_DrawList->CmdBuffer .Data + m_DrawListCommadBufferSize - 1 );
617+
618+ // Proposed solution from (https://github.com/thedmd/imgui-node-editor/pull/285):
619+ // test all commands from index >= m_DrawListFirstCommandIndex
620+ // and remove the one with UserCallback == ImDrawCallback_ImCanvas
621+ // (based on the original code, it seems there can be only one)
622+ int idxCommand_ImDrawCallback_ImCanvas = -1 ;
623+ for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer .size (); ++i)
624+ {
625+ auto & command = m_DrawList->CmdBuffer [i];
626+ if (command.UserCallback == ImDrawCallback_ImCanvas)
627+ {
628+ idxCommand_ImDrawCallback_ImCanvas = i;
629+ break ;
630+ }
631+ }
632+ if (idxCommand_ImDrawCallback_ImCanvas >= 0 )
633+ m_DrawList->CmdBuffer .erase (m_DrawList->CmdBuffer .Data + idxCommand_ImDrawCallback_ImCanvas);
564634 }
565635
566636 auto & fringeScale = ImFringeScaleRef (m_DrawList);
0 commit comments