Merge commit '17c41323d9a870a4c75d5dfc5def37f32278ced7' into back-to-imgui
This commit is contained in:
126
external/imgui/backends/imgui_impl_sdl2.cpp
vendored
126
external/imgui/backends/imgui_impl_sdl2.cpp
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user