Merge commit '17c41323d9a870a4c75d5dfc5def37f32278ced7' into back-to-imgui

This commit is contained in:
irisz64
2025-06-26 22:18:57 +02:00
92 changed files with 8646 additions and 3961 deletions

View File

@@ -26,6 +26,8 @@
// CHANGELOG
// (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-06-11: Added ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window) and ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index) helper to facilitate making DPI-aware apps.
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
// 2025-04-09: [Docking] Revert update monitors and work areas information every frame. Only do it on Windows. (#8415, #8558)
// 2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561)
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
@@ -111,6 +113,7 @@
// Clang warnings with -Weverything
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#endif
@@ -118,6 +121,7 @@
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
#include <SDL.h>
#include <SDL_syswm.h>
#include <stdio.h> // for snprintf()
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
@@ -152,6 +156,7 @@ struct ImGui_ImplSDL2_Data
SDL_Renderer* Renderer;
Uint64 Time;
char* ClipboardTextData;
char BackendPlatformName[48];
bool UseVulkan;
bool WantUpdateMonitors;
@@ -453,14 +458,15 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID) == nullptr)
ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID);
if (viewport == nullptr)
return false;
//IMGUI_DEBUG_LOG("SDL_KEY%s : key=0x%08X ('%s'), scancode=%d ('%s'), mod=%X, windowID=%d, viewport=%08X\n",
// (event->type == SDL_KEYDOWN) ? "DOWN" : "UP ", event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.mod, event->key.windowID, viewport ? viewport->ID : 0);
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
//IMGUI_DEBUG_LOG("SDL_KEY_%s : key=%d ('%s'), scancode=%d ('%s'), mod=%X\n",
// (event->type == SDL_KEYDOWN) ? "DOWN" : "UP ", event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.mod);
ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey(event->key.keysym.sym, event->key.keysym.scancode);
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
io.SetKeyEventNativeData(key, (int)event->key.keysym.sym, (int)event->key.keysym.scancode, (int)event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
return true;
}
#if SDL_HAS_DISPLAY_EVENT
@@ -491,15 +497,17 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
}
if (window_event == SDL_WINDOWEVENT_LEAVE)
bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1;
//if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) { IMGUI_DEBUG_LOG("SDL_WINDOWEVENT_FOCUS_GAINED: windowId %d, viewport: %08X\n", event->window.windowID, viewport ? viewport->ID : 0); }
//if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) { IMGUI_DEBUG_LOG("SDL_WINDOWEVENT_FOCUS_LOST: windowId %d, viewport: %08X\n", event->window.windowID, viewport ? viewport->ID : 0); }
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
io.AddFocusEvent(true);
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
io.AddFocusEvent(false);
else if (window_event == SDL_WINDOWEVENT_CLOSE)
if (window_event == SDL_WINDOWEVENT_CLOSE)
viewport->PlatformRequestClose = true;
else if (window_event == SDL_WINDOWEVENT_MOVED)
if (window_event == SDL_WINDOWEVENT_MOVED)
viewport->PlatformRequestMove = true;
else if (window_event == SDL_WINDOWEVENT_RESIZED)
if (window_event == SDL_WINDOWEVENT_RESIZED)
viewport->PlatformRequestResize = true;
return true;
}
@@ -509,6 +517,8 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
bd->WantUpdateGamepadsList = true;
return true;
}
default:
break;
}
return false;
}
@@ -522,11 +532,20 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
//SDL_SetHint(SDL_HINT_EVENT_LOGGING, "2");
// Obtain compiled and runtime versions
SDL_version ver_compiled;
SDL_version ver_runtime;
SDL_VERSION(&ver_compiled);
SDL_GetVersion(&ver_runtime);
// Setup backend capabilities flags
ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
snprintf(bd->BackendPlatformName, sizeof(bd->BackendPlatformName), "imgui_impl_sdl2 (%u.%u.%u, %u.%u.%u)",
ver_compiled.major, ver_compiled.minor, ver_compiled.patch, ver_runtime.major, ver_runtime.minor, ver_runtime.patch);
io.BackendPlatformUserData = (void*)bd;
io.BackendPlatformName = "imgui_impl_sdl2";
io.BackendPlatformName = bd->BackendPlatformName;
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
// (ImGuiBackendFlags_PlatformHasViewports may be set just below)
@@ -557,7 +576,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
if (bd->MouseCanUseGlobalState)
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
@@ -795,6 +813,27 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
}
}
// - On Windows the process needs to be marked DPI-aware!! SDL2 doesn't do it by default. You can call ::SetProcessDPIAware() or call ImGui_ImplWin32_EnableDpiAwareness() from Win32 backend.
// - Apple platforms use FramebufferScale so we always return 1.0f.
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
float ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window)
{
return ImGui_ImplSDL2_GetContentScaleForDisplay(SDL_GetWindowDisplayIndex(window));
}
float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index)
{
#if SDL_HAS_PER_MONITOR_DPI
#ifndef __APPLE__
float dpi = 0.0f;
if (SDL_GetDisplayDPI(display_index, &dpi, nullptr, nullptr) == 0)
return dpi / 96.0f;
#endif
#endif
IM_UNUSED(display_index);
return 1.0f;
}
static void ImGui_ImplSDL2_CloseGamepads()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
@@ -920,45 +959,44 @@ static void ImGui_ImplSDL2_UpdateMonitors()
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
}
#endif
#if SDL_HAS_PER_MONITOR_DPI
// FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
// DpiScale to cocoa_window.backingScaleFactor here.
float dpi = 0.0f;
if (!SDL_GetDisplayDPI(n, &dpi, nullptr, nullptr))
{
if (dpi <= 0.0f)
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
monitor.DpiScale = dpi / 96.0f;
}
#endif
float dpi_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(n);
if (dpi_scale <= 0.0f)
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
monitor.DpiScale = dpi_scale;
monitor.PlatformHandle = (void*)(intptr_t)n;
platform_io.Monitors.push_back(monitor);
}
}
static void ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(SDL_Window* window, SDL_Renderer* renderer, ImVec2* out_size, ImVec2* out_framebuffer_scale)
{
int w, h;
int display_w, display_h;
SDL_GetWindowSize(window, &w, &h);
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
w = h = 0;
if (renderer != nullptr)
SDL_GetRendererOutputSize(renderer, &display_w, &display_h);
#if SDL_HAS_VULKAN
else if (SDL_GetWindowFlags(window) & SDL_WINDOW_VULKAN)
SDL_Vulkan_GetDrawableSize(window, &display_w, &display_h);
#endif
else
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
if (out_size != nullptr)
*out_size = ImVec2((float)w, (float)h);
if (out_framebuffer_scale != nullptr)
*out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
}
void ImGui_ImplSDL2_NewFrame()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?");
ImGuiIO& io = ImGui::GetIO();
// Setup display size (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
SDL_GetWindowSize(bd->Window, &w, &h);
if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED)
w = h = 0;
if (bd->Renderer != nullptr)
SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h);
#if SDL_HAS_VULKAN
else if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_VULKAN)
SDL_Vulkan_GetDrawableSize(bd->Window, &display_w, &display_h);
#endif
else
SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h);
if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
// Setup main viewport size (every frame to accommodate for window resizing)
ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(bd->Window, bd->Renderer, &io.DisplaySize, &io.DisplayFramebufferScale);
// Update monitors
#ifdef WIN32
@@ -1089,7 +1127,7 @@ static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
{
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP) || (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)))
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
// SDL hack: Hide icon from task bar
@@ -1144,6 +1182,15 @@ static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
}
static ImVec2 ImGui_ImplSDL2_GetWindowFramebufferScale(ImGuiViewport* viewport)
{
// FIXME: SDL_Renderer does not support multi-viewport.
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
ImVec2 framebuffer_scale;
ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, nullptr, &framebuffer_scale);
return framebuffer_scale;
}
static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title)
{
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
@@ -1217,6 +1264,7 @@ static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sd
platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplSDL2_GetWindowFramebufferScale;
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;