Rounded window edges for viewports
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?
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;
}
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.
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.
This is the situation with ImGui::GetIO().ConfigViewportsNoDecoration = false;
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.
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.
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.
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.