ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
60.66k stars 10.24k forks source link

ImGui Docking causes window to fill whole screen and Viewport causes new window to dull color #6779

Open yockey88 opened 1 year ago

yockey88 commented 1 year ago

Version/Branch of Dear ImGui:

Version: 1.89.9 Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp Compiler: MSVC (cl) Operating System: Win32 (Windows 11)

My Issue/Question:

Attempting to dock an imgui on the main viewport causes it to fill the whole screen and not the side I attempted to dock it to and was highlighted initially. As well it seems to fill a space larger than the the actual viewport hanging off the bottom of the window. Also whenever I drag an imgui window outside of the main window, it becomes a dull gray and loses color.

I've tested using a few flags and giving the bottom layer imgui window thats clear and immovable different flags and different sizes but nothing seems to work.

Screenshots/Video

https://github.com/ocornut/imgui/assets/64506168/ec9a21fa-5d37-4842-a2a1-25fef7bb8b3a

Minimal Reproducible Example

#include <Windows.h>

#include <glad/glad.h>
#include <SDL.h>
#undef main
#include <imgui.h>
#include <backends/imgui_impl_sdl2.h>
#include <backends/imgui_impl_opengl3.h>
#include <glm/glm.hpp>

int run(int argc , char* argv[]) {

    glm::ivec2 window_size = glm::ivec2(1782 , 1008);

    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        std::cout << "SDL2 failed to initialize: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window* window = SDL_CreateWindow(
        "Window" ,
        SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,
        window_size.x , window_size.y ,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
    );

    if (window == nullptr) {
        std::cout << "SDL2 failed to create window: " << SDL_GetError() << std::endl;

        SDL_Quit();
        return 1;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER , 1);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE , 8);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS , 1);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES , 24);
    SDL_SetWindowMinimumSize(window , 200 , 200);
    SDL_GL_SetSwapInterval(1);

    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    if (gl_context == nullptr) {
        std::cout << "SDL2 failed to create OpenGL context: " << SDL_GetError() << std::endl;

        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }

    if (gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress) == 0) {
        std::cout << "GLAD failed to initialize" << std::endl;

        SDL_GL_DeleteContext(gl_context);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }

    glEnable(GL_DEPTH_TEST);

    glViewport(0 , 0 , window_size.x , window_size.y);
    glClearColor(0.2f , 0.3f , 0.3f , 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    ImGui::StyleColorsDark((ImGuiStyle*)0);

    io.ConfigWindowsResizeFromEdges = true;
    io.ConfigWindowsMoveFromTitleBarOnly = true;
    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_ViewportsEnable | 
                        ImGuiConfigFlags_NavEnableKeyboard;

    ImGui_ImplSDL2_InitForOpenGL(window , gl_context);
    ImGui_ImplOpenGL3_Init("#version 460");

    bool running = true;
    while (running) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch(event.type) {
                case SDL_QUIT:
                    running = false;
                break;
                case SDL_WINDOWEVENT:
                    switch(event.window.event) {
                        case SDL_WINDOWEVENT_CLOSE: running = false; break;
                        case SDL_WINDOWEVENT_RESIZED:
                            glViewport(0 , 0 , event.window.data1 , event.window.data2);
                            window_size = glm::ivec2(event.window.data1 , event.window.data2);
                        break;
                        default: break;
                    }
                break;
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym) {
                        case SDLK_ESCAPE: running = false; break;
                        default: break;
                    }
                break;
                default: break;
            }
            ImGui_ImplSDL2_ProcessEvent(&event);
        }      

        glClearColor(0.2f , 0.3f , 0.3f , 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplSDL2_NewFrame(window);
        ImGui::NewFrame();

        ImGui::ShowDemoWindow();

        if (ImGui::BeginMainMenuBar()) {
            if (ImGui::BeginMenu("Menu")) {
                if (ImGui::MenuItem("Close"))
                    running = false;
                ImGui::EndMenu();
            }
            ImGui::EndMainMenuBar();
        }

        ImGuiViewport* viewport = ImGui::GetMainViewport();
        ImGui::SetNextWindowPos(viewport->Pos);
        ImGui::SetNextWindowSize(viewport->Size);
        ImGui::SetNextWindowViewport(viewport->ID);
        if (ImGui::Begin("YE2" , nullptr , ImGuiWindowFlags_MenuBar      | ImGuiWindowFlags_NoMove |
                                           ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoBringToFrontOnFocus | 
                                           ImGuiWindowFlags_NoResize)) {
            ImGui::Text("Text");
        }
        ImGui::End();

        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        ImGuiIO& io = ImGui::GetIO();
        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
            ImGui::UpdatePlatformWindows();
            ImGui::RenderPlatformWindowsDefault();
            SDL_GL_MakeCurrent(window , gl_context);
        }

        SDL_GL_SwapWindow(window);
    }   

    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;
}

HINSTANCE hinstance = nullptr;

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow) {     
    hinstance = hInstance;                                                        
    return run(__argc , __argv);

}
GamingMinds-DanielC commented 1 year ago

You don't set up a dockspace in your code, you must do so by either calling ImGui::DockSpace() or ImGui::DockSpaceOverViewport(), see demo code for reference.

Also, calling ImGui::SetNextWindowPos/Size/Viewport() every frame could mess with things further. Maybe set ImGuiCond_FirstUseEver to restrict it to the first use, then let ImGui handle the docking.

ocornut commented 1 year ago

There are multiple things here:

Indeed you didn't setup a dockspace but a regular window: technically that will allow docking into but that's not what you want (for reasons I won't detail here). But your main problem is you are calling SetNextWindowPos() every frame on it effectively UNDOCK that "ye2" window, so in turns the Demo Window become the sole window and take the full space. If you open Tools->Debug Log->Docking you'll see notification of "ye2" being undocked. Using DockSpaceOverViewport() is going to be simpler and more correct anyway so use that.

About the "dull grey and lose color" thing, This seem to be an issue with your multi-viewport .

yockey88 commented 1 year ago

Hi sorry I forgot to check this so I'm just seeing these, I'll fix the Dockspace stuff, but the greying out of the viewport happens both in this mini example and the unmodified app, I attached a video of the actual application where this happens. And for version number, 1.89.9 is what appears on my Imgui Demo Window I'm using for reference. I attached an image of that as well. So that is what I put, I'll try out the dockspace stuff and see effect that has

https://github.com/ocornut/imgui/assets/64506168/89badc86-d511-4664-a79d-2bdb5725a7c4

Screenshot 2023-09-07 172452

Edit: I went and used the example code for DockSpaceOverViewport(GetMainViewPort()) and unfortunately that just turned my entire window gray, and while that fixes the docking issue it just turns my entire window gray. I'm trying to make the bottom layer window see through so I can display 'floating' text and stuff on the scene. Setting the ImGuiWindowFlags_NoBackground doesn't seem to have any effect, simply making my window one giant grey square. Is there a way I can make a see through dockspace that is the same size as the platform window? There seems to be a lot of discussion about the subject but none of the solutions here have worked for me.

Edit 2: I Fixed the docking issue with your suggestions thank you for the tips on how to use dockspace, however using both of the DockSpace functions seems to turn off the NoBackground window flag, and the viewport issue also remains. I attached a video of the update with the dockspace calls.

https://github.com/ocornut/imgui/assets/64506168/c655d6f7-0591-4737-8947-e199f3e90bca