imgui icon indicating copy to clipboard operation
imgui copied to clipboard

Rounded window edges for viewports

Open thewoz opened this issue 2 months ago • 6 comments

Version/Branch of Dear ImGui:

Version "master", Branch: docking

Back-ends:

ImGui_ImplGlfw ImGui_ImplOpenGL3

Compiler, OS:

macOS

Full config/build information:

No response

Details:

Hi everyone, I'm trying to make the style of these two windows look the same. I've changed a few style aspects, but what I just can't manage is to make the corners of the second window rounded. What am I doing wrong?

Image

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

#include <cstdio>
#include <cstdlib>
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui.hpp>

static void glfwErrorCallback(int error, const char * description) {
  fprintf(stderr, "GLFW error (%d): %s\n", error, description);
}

//****************************************************************************//
// main()
//****************************************************************************//
int main() {
  
  // Init finestra
  glfwSetErrorCallback(glfwErrorCallback);
  if(!glfwInit()) return 1;

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_SAMPLES, 4);
  glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
  
#ifdef __APPLE__
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

  GLFWwindow * gWindow = glfwCreateWindow(1280, 720, "Test", nullptr, nullptr);
  if(!gWindow) { glfwTerminate(); return 2; }

  glfwMakeContextCurrent(gWindow);
  glfwSwapInterval(1);

  if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cerr << "GLAD init failed\n"; return 3; }

  // ImGui
  IMGUI_CHECKVERSION();
  ImGui::CreateContext();
  
  ImGui::StyleColorsDark();
  
  ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
  ImGui::GetIO().ConfigViewportsNoDecoration = true;
  
  ImGui_ImplGlfw_InitForOpenGL(gWindow, true);
  ImGui_ImplOpenGL3_Init("#version 330");
  
  while(!glfwWindowShouldClose(gWindow)) {
        
    glfwPollEvents();
    
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    ImGuiWindowFlags mainWinFlags =
          ImGuiWindowFlags_NoDecoration
        | ImGuiWindowFlags_NoNavFocus
        | ImGuiWindowFlags_NoMove
        | ImGuiWindowFlags_NoBringToFrontOnFocus
        | ImGuiWindowFlags_NoScrollWithMouse;
    
    ImGuiViewport * viewport = ImGui::GetMainViewport();
    
    ImGui::SetNextWindowPos (viewport->WorkPos);
    ImGui::SetNextWindowSize(viewport->WorkSize);

    ImGui::Begin("MainWindow", NULL, mainWinFlags);
    
    ImGui::End();
    
    ImGuiWindowFlags secondWinFlags = ImGuiWindowFlags_NoCollapse;

    ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 20.0f);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowTitleAlign, ImVec2(0.5f, 0.5f));
    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 7.5f));

    ImGui::PushStyleColor(ImGuiCol_ResizeGrip,    ImVec4(0.f, 0.f, 0.f, 0.0f));
    ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(0.188f, 0.188f, 0.188f, 1.0f));
    ImGui::PushStyleColor(ImGuiCol_TitleBg,       ImVec4(0.145f, 0.145f, 0.145f, 1.0f));
    
    ImGui::Begin("SecondWindow", NULL, secondWinFlags);
    
    ImGui::End();
    
    ImGui::PopStyleColor(3);
    ImGui::PopStyleVar(3);
    
    ImGui::Render();

    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    
    GLFWwindow * backup_current_context = glfwGetCurrentContext();
    
    ImGui::UpdatePlatformWindows();
    ImGui::RenderPlatformWindowsDefault();
    
    glfwMakeContextCurrent(backup_current_context);
 
    glfwSwapBuffers(gWindow);
    
  }

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

  glfwDestroyWindow(gWindow);
  glfwTerminate();
  
  return 0;
  
}

thewoz avatar Nov 12 '25 17:11 thewoz

In general, same answer as #4180, #6298, #6599, #7813, #8309, #8626, #8791, #8981 : rounded secondary viewports are not reliably supported, sorry. In practice it depends on the OS and variety of settings.

You can research it but I would assume on Mac maybe the system display window with title/bar decorations as rounded? It's not particularly related to dear imgui. Try with ImGui::GetIO().ConfigViewportsNoDecoration = false; to confirm.

ocornut avatar Nov 12 '25 17:11 ocornut

https://github.com/glfw/glfw/blob/936307558ee25bf5d50d7ecf22972efd4c3abd4f/src/cocoa_window.m#L816

void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled)
{
    @autoreleasepool {

    NSUInteger styleMask = [window->ns.object styleMask];
    if (enabled)
    {
        styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
        styleMask &= ~NSWindowStyleMaskBorderless;
    }
    else
    {
        styleMask |= NSWindowStyleMaskBorderless;
        styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
    }

    [window->ns.object setStyleMask:styleMask];
    [window->ns.object makeFirstResponder:window->ns.view];

    } // autoreleasepool
}

Using NSWindowStyleMaskBorderless.

Then if I google for "NSWindowStyleMaskBorderless rounded": https://stackoverflow.com/questions/4003975/round-corners-on-a-borderless-nswindow

I would assume one may would need a transparent framebuffer which would be highly dependent, costly, and is not formally supported yet, see e.g. #5988, but they may be other ways, you'd have to investigate for this in macOS land.

ocornut avatar Nov 12 '25 17:11 ocornut

This is the situation with ImGui::GetIO().ConfigViewportsNoDecoration = false;

Image

In this way, the decorations are the same. The only downside is that you lose control over the decorative elements, such as the close and minimize buttons. Another possibility would be to open two windows with GLFW, but even in that case you still wouldn’t have control over those aspects.

Of course, with ImGuiWindowFlags_NoDecoration I can remove the second title.

thewoz avatar Nov 13 '25 10:11 thewoz

This is the situation with ImGui::GetIO().ConfigViewportsNoDecoration = false;

So mostly likely rounded on macOS is disabled by NSWindowStyleMaskBorderless, now maybe you can research if there's a way to reactivate it?

. The only downside is that you lose control over the decorative elements, such as the close and minimize buttons

Well technically you have the native Close and Minimize button (vs our Close and Collapse button).

I don't have a better answer now unfortunately. It would be nice to expose a way to promote native decoration and automatically hide ours but it probably raises many questions which we should tackle.

ocornut avatar Nov 13 '25 13:11 ocornut

So mostly likely rounded on macOS is disabled by NSWindowStyleMaskBorderless, now maybe you can research if there's a way to reactivate it?

It would be interesting to understand this. I’m not sure at which level I should look to fix it. NSWindowStyleMaskBorderless is a flag that has to be passed when a window is created. I don’t understand whether it needs to be handled in ImGui or in GLFW.

I don't have a better answer now unfortunately. It would be nice to expose a way to promote native decoration and automatically hide ours but it probably raises many questions which we should tackle.

I agree with you. At least for now, the situation seems clear to me.

thewoz avatar Nov 14 '25 10:11 thewoz

It would be interesting to understand this. I’m not sure at which level I should look to fix it. NSWindowStyleMaskBorderless is a flag that has to be passed when a window is created. I don’t understand whether it needs to be handled in ImGui or in GLFW.

The first step would be to understand if it's even possible in macOS to have a rounded window without native decoration. For that you might need to scour for native doc or experiment with native code. If if it is indeed possible we can later figure out a way to make that possible from GLFW or from a imgui_impl_glfw backend. Honestly it is a bit far fetched but if you'd like to investigate this further please let me know, otherwise I'd probably close this as not yet supported and not a research priority.

ocornut avatar Nov 18 '25 18:11 ocornut