Skip to content

Flooring of clip rectangle on negative monitor coordinates cuts off content #6861

Closed
@alektron

Description

@alektron

Version/Branch of Dear ImGui:

Version: 1.90 WIP (18992)
Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: (tested with) example_win32_directx11, example_win32_opengl3, custom backend
Operating System: Windows 10

Issue:
On a setup with multiple monitors, content inside an imgui child window gets clipped on the left side of the clipping rectangle if the viewport/platform window is positioned on a monitor with negative X coordinates.

On Windows, when using multiple monitors, one monitor is always set as the 'main monitor'. Other monitors can then be positioned left, right, above or below. All monitors together use one big coordinate system with the origin being in the top left corner of the main monitor (at least on all my systems/setups). On a setup where there is a monitor left to the main monitor, most coordinates used by Windows will become negative on the x axis. This includes e.g. mouse position or window position.

If we move our window to such a monitor with negative x coordinates, imgui items that are very close to the clipping rectangle border can be cut off as seen here:

image

The effect is most notable with frame borders enabled (and a high contrast) but to a sharp eye it is also visible on widgets with rounded frames. The text is also affected.

  ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
  ImGui::Begin("Hello, world!"); 
  ImGui::BeginChild("Child", ImVec2(0, 0), false);
  int v;
  ImGui::InputInt("TestInput", &v);
  ImGui::Text("Window pos X: %f", ImGui::GetWindowPos().x);
  ImGui::EndChild();
  ImGui::End();
  ImGui::PopStyleVar();

A possible monitor setup is the one below as seen in the Windows 10 desktop settings.
The platform window of the imgui application would have to be on screen one with this setup.
image

My best guess is that internally the clipping rectangle coordinates get floored which in the worst case usually shifts the left clipping rectangle border <1px to the left. However for negative floats this will shift the left border <1px to the right.

The culprit seems to be the code below (imgui.cpp ImGui::Begin(), Line: 7157) where the clipping rectangle gets floored.
There is probably a smarter way to solve this than adding a check for negative coordinates but I'm not sure.

float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize);
window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + top_border_size);
window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize);
window->InnerClipRect.ClipWithFull(host_rect);

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions