Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ViewPort scaling messed up on secondary screen with different scaling #7689

Open
BraunSilas opened this issue Jun 13, 2024 · 4 comments
Open

Comments

@BraunSilas
Copy link

BraunSilas commented Jun 13, 2024

Version/Branch of Dear ImGui:

V1.90.8 Branch Docking

Back-ends:

glfw glad

Compiler, OS:

Windows 10 + CLion + Bundled MinGW

Full config/build information:

No response

Details:

I am using ImGui (Branch: Docking) and attempting to use it to dock and with multiple viewports.

I did not used the example project as guide but only took the parts that worked with by libs.

I was able to get it running pretty smoothly, but once I drag an ImGui Winodw on its own onto another screen, the scalling breaks, [image 1]
This does not happen with a Windows window or if the ImGui window is in a Windows window.

But I am still able to change the size of the ImGui window and once I do that all Widgets jump back to where they belong to. [image 2]

But once I drag the window back onto the MainScreen this happens. [image 3]
My mouse is not highlighting the widget when it is on top of them. in the image imagine the top red circle being my cursor and the bottom circle indicating the higlighted widget.

However if I now drop the imgui window (including black padding) into the Windows window it snaps back and the black padding disapears and my mouse highlights the correct widgets again.

I also think that the font size in the imgui window differs between the 2 screen.

In the Windows setting I see:
main screen: 150% scale and 3840 * 2160
secondary screen: 100% scale and 1080 * 1920

And I just tested setting the scaling of the secondary screen to 150%

and it fixed it. any Tips how I can adjust my window to the scale?

Thank you for your support

Screenshots/Video:

image 1
image 2
image 3

Minimal, Complete and Verifiable Example code:

#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"

#include "glad/glad.h" // this come form OpenGL Course free COde Camp min1 - glad.dav1d.de
#include <GLFW/glfw3.h>
#include "iostream"



int main(void)
{
    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//only modern functions


    GLFWwindow* window = glfwCreateWindow(800,800,"OpenGL", NULL, NULL);

    if(!window){
        std::cout << "Failed to create GLFW Window!" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);//enable Vsync
    gladLoadGL();


    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void) io;
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;         // Enable Docking
    io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;       // Enable Multi-Viewport / 

    ImGui::StyleColorsDark();

    ImGuiStyle& style = ImGui::GetStyle();
    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable){
        style.WindowRounding = 0.0f;
        style.Colors[ImGuiCol_WindowBg].w = 1.0f;
    }

    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");


    // Our state
    bool show_demo_window = true;
    bool show_another_window = false;
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);


    while(!glfwWindowShouldClose(window)){

        glfwPollEvents();

        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();


        ImGui::ShowDemoWindow();


        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, 800, 800);
        glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());


  
        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable){
            GLFWwindow* backup_current_context = glfwGetCurrentContext();
            ImGui::UpdatePlatformWindows();
            ImGui::RenderPlatformWindowsDefault();
            glfwMakeContextCurrent(backup_current_context);
        }

        glfwSwapBuffers(window);
    }


    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}
@BraunSilas BraunSilas changed the title ViewPort turns black on secondary screen ViewPort scaling messed up on secondary screen with different scaling Jun 13, 2024
@BraunSilas
Copy link
Author

I have seen #6444 but It don't see what I need to do?

@BraunSilas
Copy link
Author

@BraunSilas
Copy link
Author

What I understand is: for each view port I need to check the scale and then switch the fontsize.
But how can get the specific scale of a specific window/viewport? I would imagine that at every Begin() I can check the scale and then insert a function that assignes the correct font size regarding the scale. I just don't understand how I know which scal belongs to which Imgui Window

@the-loki
Copy link

Reason:

I discovered the root cause of this issue, as you mentioned, is due to different monitors' DPI scaling. When using GLFW with the docking version of ImGui and disabling the system window decoration, this issue arises. The reason is that in this setting, window movement uses glfwSetWindowPos (this is also the case when the number of viewports is greater than one). When the window crosses monitors with different DPI scaling, GLFW triggers a DPI change event and updates the window size. The new size triggers a GLFW resize event. The problem is that the resize event triggered by glfwSetWindowPos happens in the same frame, and the viewport's PlatformRequestResize is cleared without being used after being set, causing the issue.

However, when enabling the system window decoration, the window size is also updated, but the new size recommended by the system does not trigger a GLFW resize event, so the issue does not occur with system window decoration enabled.

Temporary workaround:
You can actively set the window size when the DPI changes to solve the issue, as long as it triggers a window size change.

Suggested fix:
Consider detecting the usage of the viewport's PlatformRequestResize parameter when enabling ImGuiConfigFlags_ViewportsEnable. If it is not used, retain it until the next frame instead of clearing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants