@@ -158,22 +158,50 @@ void WindowRectAllocator::setFreeNextWindowPos( const char* expectedWindowName,
158158
159159 if ( findLocation )
160160 {
161- // push into application window if it is out
162- const Vector2f appWindowSize = Vector2f ( getViewerInstance ().framebufferSize );
163- const Box2f appWindowBox = Box2f::fromMinAndSize ( ImGuiMV::GetMainViewportShift (), appWindowSize );
164161 auto windowBox = Box2f::fromMinAndSize ( defaultPos, window->Size );
165- defaultPos.x = std::clamp ( windowBox.min .x , appWindowBox.min .x , std::max ( 0 .0f , windowBox.min .x + appWindowBox.min .x - ( windowBox.max .x - appWindowBox.max .x ) ) );
166- defaultPos.y = std::clamp ( windowBox.min .y , appWindowBox.min .y , std::max ( 0 .0f , windowBox.min .y + appWindowBox.min .y - ( windowBox.max .y - appWindowBox.max .y ) ) );
162+ Box2f boundsFixed;
163+
164+ Box2f workBox;
165+
166+ if ( ImGui::GetIO ().ConfigFlags & ImGuiConfigFlags_ViewportsEnable )
167+ {
168+ const auto & monitors = ImGui::GetPlatformIO ().Monitors ;
169+ for ( const auto & m : monitors )
170+ {
171+ Box2f mBox = Box2f::fromMinAndSize ( m.WorkPos , m.WorkSize );
172+ if ( mBox .intersects ( windowBox ) ) // alternative way: calculate window area in current monitor
173+ {
174+ workBox = mBox ;
175+ break ;
176+ }
177+ }
178+ }
179+ else
180+ {
181+ const Vector2f appWindowSize = Vector2f ( getViewerInstance ().framebufferSize );
182+ workBox = Box2f::fromMinAndSize ( ImGuiMV::GetMainViewportShift (), appWindowSize );
183+ }
184+ defaultPos.x = std::clamp ( windowBox.min .x , workBox.min .x , std::max ( 0 .0f , workBox.max .x - windowBox.size ().x ) );
185+ defaultPos.y = std::clamp ( windowBox.min .y , workBox.min .y , std::max ( 0 .0f , workBox.max .y - windowBox.size ().y ) );
167186 windowBox = Box2f::fromMinAndSize ( defaultPos, window->Size );
168187
169- // convert viewport bounds from local to window space
170- Box2f viewportBounds = getViewerInstance ().getViewportsBounds ();
171- Box2f boundsFixed = viewportBounds;
172- boundsFixed.min .y = ImGui::GetIO ().DisplaySize .y - boundsFixed.max .y ;
173- boundsFixed.max .y = boundsFixed.min .y + viewportBounds.size ().y ;
174- // convert viewport bounds from window to screen space
175- boundsFixed.min = ImGuiMV::Window2ScreenSpaceVector2f ( boundsFixed.min );
176- boundsFixed.max = ImGuiMV::Window2ScreenSpaceVector2f ( boundsFixed.max );
188+
189+ if ( ImGui::GetIO ().ConfigFlags & ImGuiConfigFlags_ViewportsEnable )
190+ {
191+ boundsFixed = workBox;
192+ }
193+ else
194+ {
195+ // convert viewport bounds from local to window space
196+ Box2f viewportBounds = getViewerInstance ().getViewportsBounds ();
197+ boundsFixed = viewportBounds;
198+ boundsFixed.min .y = ImGui::GetIO ().DisplaySize .y - boundsFixed.max .y ;
199+ boundsFixed.max .y = boundsFixed.min .y + viewportBounds.size ().y ;
200+ // convert viewport bounds from window to screen space
201+ boundsFixed.min = ImGuiMV::Window2ScreenSpaceVector2f ( boundsFixed.min );
202+ boundsFixed.max = ImGuiMV::Window2ScreenSpaceVector2f ( boundsFixed.max );
203+ }
204+ // push into application window if it is out
177205
178206 auto result = findFreeRect ( windowBox, boundsFixed, [&]( Box2f rect, std::function<void ( const char *, Box2f )> func )
179207 {
0 commit comments