Backends: GLFW: improve multi-viewport behavior in tiling WMs (X11). Amends. (#8884, #8474, #8289)

This commit is contained in:
ocornut
2025-09-10 20:06:45 +02:00
parent 6b2cdf29bc
commit 37b18acdf5
5 changed files with 23 additions and 15 deletions

View File

@@ -32,6 +32,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2025-09-10: [Docking] Improve multi-viewport behavior in tiling WMs on X11 via the ImGui_ImplGlfw_SetWindowFloating() function. Note: using GLFW backend on Linux/BSD etc. requires linking with -lX11. (#8884, #8474, #8289)
// 2025-07-08: Made ImGui_ImplGlfw_GetContentScaleForWindow(), ImGui_ImplGlfw_GetContentScaleForMonitor() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733) // 2025-07-08: Made ImGui_ImplGlfw_GetContentScaleForWindow(), ImGui_ImplGlfw_GetContentScaleForMonitor() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733)
// 2025-06-18: Added support for multiple Dear ImGui contexts. (#8676, #8239, #8069) // 2025-06-18: Added support for multiple Dear ImGui contexts. (#8676, #8239, #8069)
// 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps. // 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps.
@@ -121,14 +122,13 @@
#define GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32
#endif #endif
#include <GLFW/glfw3native.h> // for glfwGetWin32Window() #include <GLFW/glfw3native.h> // for glfwGetWin32Window()
#endif #elif defined(__APPLE__)
#ifdef __APPLE__
#ifndef GLFW_EXPOSE_NATIVE_COCOA #ifndef GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_COCOA #define GLFW_EXPOSE_NATIVE_COCOA
#endif #endif
#include <GLFW/glfw3native.h> // for glfwGetCocoaWindow() #include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
#elif !defined(__EMSCRIPTEN__) #elif !defined(__EMSCRIPTEN__)
// Freedesktop(Linux, BSD, etc) // Freedesktop (Linux, BSD, etc)
#ifndef GLFW_EXPOSE_NATIVE_X11 #ifndef GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_X11 #define GLFW_EXPOSE_NATIVE_X11
#include <X11/Xatom.h> #include <X11/Xatom.h>
@@ -183,7 +183,7 @@
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError() #define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
#define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform() #define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform()
// Map GLFWWindow* to ImGuiContext*. // Map GLFWWindow* to ImGuiContext*.
// - Would be simpler if we could use glfwSetWindowUserPointer()/glfwGetWindowUserPointer(), but this is a single and shared resource. // - Would be simpler if we could use glfwSetWindowUserPointer()/glfwGetWindowUserPointer(), but this is a single and shared resource.
// - Would be simpler if we could use e.g. std::map<> as well. But we don't. // - Would be simpler if we could use e.g. std::map<> as well. But we don't.
// - This is not particularly optimized as we expect size to be small and queries to be rare. // - This is not particularly optimized as we expect size to be small and queries to be rare.
@@ -1200,7 +1200,8 @@ static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
} }
} }
#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && (GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4)) #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && GLFW_HAS_GETPLATFORM
#define IMGUI_GLFW_HAS_SETWINDOWFLOATING
static void ImGui_ImplGlfw_SetWindowFloating(GLFWwindow* window) static void ImGui_ImplGlfw_SetWindowFloating(GLFWwindow* window)
{ {
#ifdef GLFW_EXPOSE_NATIVE_X11 #ifdef GLFW_EXPOSE_NATIVE_X11
@@ -1208,21 +1209,20 @@ static void ImGui_ImplGlfw_SetWindowFloating(GLFWwindow* window)
{ {
Display* display = glfwGetX11Display(); Display* display = glfwGetX11Display();
Window xwindow = glfwGetX11Window(window); Window xwindow = glfwGetX11Window(window);
Atom wm_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); Atom wm_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
Atom wm_type_dialog = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); Atom wm_type_dialog = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
XChangeProperty(display, xwindow, wm_type, XA_ATOM, 32, XChangeProperty(display, xwindow, wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wm_type_dialog, 1);
PropModeReplace, (unsigned char*)&wm_type_dialog, 1);
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
attrs.override_redirect = False; attrs.override_redirect = False;
XChangeWindowAttributes(display, xwindow, CWOverrideRedirect, &attrs); XChangeWindowAttributes(display, xwindow, CWOverrideRedirect, &attrs);
XFlush(display); XFlush(display);
} }
#endif #endif // GLFW_EXPOSE_NATIVE_X11
#ifdef GLFW_EXPOSE_NATIVE_WAYLAND
// FIXME: Help needed, see #8884, #8474 for discussions about this.
#endif // GLFW_EXPOSE_NATIVE_X11
} }
#endif #endif // IMGUI_GLFW_HAS_SETWINDOWFLOATING
static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport) static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
{ {
@@ -1251,7 +1251,7 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
vd->WindowOwned = true; vd->WindowOwned = true;
ImGui_ImplGlfw_ContextMap_Add(vd->Window, bd->Context); ImGui_ImplGlfw_ContextMap_Add(vd->Window, bd->Context);
viewport->PlatformHandle = (void*)vd->Window; viewport->PlatformHandle = (void*)vd->Window;
#if !defined(__APPLE__) && !defined(_WIN31) && !defined(__EMSCRIPTEN__) && (GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4)) #ifdef IMGUI_GLFW_HAS_SETWINDOWFLOATING
ImGui_ImplGlfw_SetWindowFloating(vd->Window); ImGui_ImplGlfw_SetWindowFloating(vd->Window);
#endif #endif
#ifdef _WIN32 #ifdef _WIN32

View File

@@ -94,6 +94,12 @@ Other Changes:
- Backends: Vulkan: added ImGui_ImplVulkan_CreateMainPipeline() to recreate pipeline - Backends: Vulkan: added ImGui_ImplVulkan_CreateMainPipeline() to recreate pipeline
without reinitializing backend. (#8110, #8111) [@SuperRonan] without reinitializing backend. (#8110, #8111) [@SuperRonan]
Docking+Viewports Branch:
- Backends: GLFW: improve multi-viewport behavior in tiling WMs on X11.
Note: using GLFW backend on Linux/BSD etc. requires linking with `-lX11`.
(#8884, #8474, #8289) [@Ikos3k, @Madman10K]
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.92.2b (Released 2025-08-13) VERSION 1.92.2b (Released 2025-08-13)

View File

@@ -21,6 +21,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
@@ -32,7 +33,7 @@ LIBS =
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS += -lGL `pkg-config --static --libs glfw3` LIBS += $(LINUX_GL_LIBS) -lX11 `pkg-config --static --libs glfw3`
CXXFLAGS += `pkg-config --cflags glfw3` CXXFLAGS += `pkg-config --cflags glfw3`
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@@ -36,6 +36,7 @@ find_package(Vulkan REQUIRED)
#NAMES vulkan vulkan-1) #NAMES vulkan vulkan-1)
#set(LIBRARIES "glfw;${VULKAN_LIBRARY}") #set(LIBRARIES "glfw;${VULKAN_LIBRARY}")
set(LIBRARIES "glfw;Vulkan::Vulkan") set(LIBRARIES "glfw;Vulkan::Vulkan")
# FIXME: Linux needs linking with "X11" as well?
# Use vulkan headers from glfw: # Use vulkan headers from glfw:
include_directories(${GLFW_DIR}/deps) include_directories(${GLFW_DIR}/deps)

View File

@@ -33,7 +33,7 @@ LIBS =
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS += $(LINUX_GL_LIBS) `pkg-config --static --libs glfw3 vulkan` LIBS += $(LINUX_GL_LIBS) -lX11 `pkg-config --static --libs glfw3 vulkan`
CXXFLAGS += `pkg-config --cflags glfw3 vulkan` CXXFLAGS += `pkg-config --cflags glfw3 vulkan`
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)