tomato/backends/imgui_impl_sdl2.cpp
Green Sky b8ca49f7dc Squashed 'external/imgui/imgui/' changes from cb16568fca5..5c1d2d1e4c5
5c1d2d1e4c5 Version 1.91.7
9f8481a842e (Breaking) TreeNode: renamed ImGuiTreeNodeFlags_SpanTextWidth to ImGuiTreeNodeFlags_SpanLabelWidth. (#6937)
21902e2f536 Backends: SDL_GPU: fixed SDL_GPUViewport initialisation. (#8163, #7998, #7988)
c38c18c1a07 Avoid using 1<<31 for ImGuiWindowFlags_NavFlattened as it seems to confuse some binding generators.
c5f60942bdd Demo: tweak demo for ImGuiTreeNodeFlags_LabelSpanAllColumns. (#8318, #3565)
290e402a020 TreeNode, Tables: added ImGuiTreeNodeFlags_LabelSpanAllColumns. (#8318, #3565)
6fb7d442559 Backends: SDL2/SDL3: Comments. (#7672, #7670)
32cea853317 Debug Tools:  Item Picker: Always available in menu. Tweak Demo Debug Options. (#2673, #1651)
00f12b9a09d InputText: Fixed not calling CallbackEdit on revert/clear with Escape key. (#8273) + rework comments.
a604d4f717b Fixed IsItemDeactivated(), IsItemDeactivatedAfterEdit() to work when interrupted before/after the active id is submitted. (#5184, #5904, #6766, #8303, #8004)
a28ffa81c4a Docs: added more references to IsKeyDown(), InFlags. (#8317)
1d962820d8b Error Handling: Turned common EndTable() and other TableXXX functions fail cases into recoverable errors. (#1651, #8314)
0b8ff4b2382 Backends, Examples: Vulkan: add IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE. use in descriptor pools sizes. (#6642)
e7fb97208a8 Backends: Metal: Added missing IM_UNUSED (#8302)
596e09770d3 Backends: SDL3: Added ImGui_ImplSDL3_InitForSDLGPU() for consistency. (#8163, #7998, #7988)
e7998492726 Backends: SDLGPU3: Added sdl_gpu backend (amends). (#8163, #7998, #7988)
8bbccf7a977 Backends: SDLGPU3: Added sdl_gpu backend. (#8163, #7998, #7988)
940d9540f3f Fixed MinGW builds uses UTF-8 friendly _wfopen(). (#8300)
c7983115e9f Fonts: Further tweaks for Ellipsis ("...") character width when automatically created from a single comma character: use AdvanceX as min.
90094a871a5 Fonts: Fixed miscalculation of Ellipsis ("...") character width when automatically created from a single comma character.
1c67a3412e1 BeginChild: also caller to manually set ImGuiNextWindowDataFlags_HasChildFlags / ChildFlags. (#8280)
2b8545684ca Refactor: moved Window Focus related functions to a dedicated section.
bbbdc70f26b Refactor: moved FindBlockingModal() in its section.
e6a7c7689f5 Backends: Metal: Fixed memory leaks. (#8276, #8166)
0514332474f Avoid clang/gcc warnings: -Wnontrivial-memaccess in backends. (#8295, #8129, #8135)
3115ae08159 Demo: Font selector combo sets default focus.
cec8ff1885d Backends: Vulkan: Fixed building with using VK_NO_PROTOTYPES. (#8180)
f04d3cbdaaf Backends: DirectX10: Expose selected render state in ImGui_ImplDX10_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks. (#6969, #5834, #7468, #3590)
af271e73303 Backends: DX11: Expose vertex constant buffer in ImGui_ImplDX11_RenderState.
93a93071a27 Examples: Add Win32+Vulkan example, amends. (#8180)
38e606a153b Examples: Add Win32+Vulkan example. (#8180)
a2e21727c01 Backends: Vulkan: moved helpers to backend: ImGui_ImplVulkanH_SelectPhysicalDevice(), ImGui_ImplVulkanH_SelectQueueFamilyIndex(). (#8180)
dbf76f62f9e Update issue_template.yml
e7e898ea179 Tables: Fixed TableAngledHeadersRow() creating an infinite horizontal scrolling region when the table is hosted in a viewport with negative coordinates.
d0021e16215 Backends: Metal: Fixed resource leak when using multiple contexts. (#7419)
2f1194a2961 Demo: Added label edition to Property Editor demo + fix an ID issue. (#8266)
80aafbc81b0 Data types: moved ImGuiDataType_String to public API as a convenience enum value only. (#8266)
f169102c8ea Misc: fixed misc/cpp/imgui_stdlib.h/.cpp not supporting IMGUI_DISABLE. (#8294)
a0f907933d8 Happy new year!
c147a59bb0e Clarified alternative for ImGuiButtonFlags_Repeat being ImGuiItemFlags_ButtonRepeat. (#8293)
2d2c7d3f955 Backends: Allegro5: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
87f3109c1af Fix capitalization of ImGuiID in comment. (#8283)
6982ce43f5b InputText: fixed badly broken clipboard copy/bug (#8254, #8242)
18929bd6d6c Internals: merge ScaleWindowsInViewport() from docking branch.
2a600bddcbe ImGuiDebugLogFlags_EventFont should not be set by default (had no effect on master tho)
006721fbd6b Added ImFontAtlas section index in comments + minor tweaks to DX12 backends.
7219fa65c02 Revert "Fonts: Allowing PushFont()/PopFont() to be called outside the imgui frame scope. (#3621)"
61d4bf95dc5 Fonts: Allowing PushFont()/PopFont() to be called outside the imgui frame scope. (#3621)
d30e102f3ad Scrollbar, TestEngine: for consistency, scrollbars are registered in _Menu layer.
91e8f2b0feb Debug Tools: Debug Log: hovering 0xXXXXXXXX values in log is allowed even if a popup is blocking mouse access to the debug log window. (#5855)
eed95027956 Error Handling: Fixed bugs recovering from within a table that created a child window, and from nested child windows. (#1651)
fd932297703 Tables, MultiSelect: Fixed an issue where column width may be mismeasured when calling BeginMultiSelect() while inside a table. (#8250)
9b0e61aaaa7 InputText: sanity checks to e.g. detect non zero-terminated buffers + removed a redundant strlen() call during activation.
ae839620b96 Docs: Updated EXAMPLES.md (#8246)
457fae24e7a Silence more zealous GCC warning. (#8241)
cd6c83cdccb Fixes GCC warnings (#8241)
32f11402f96 InputText: use TextSrc more consistently to facilitate accessing user buffer in text processing code. (#8242)
e900571ac24 InputText: Fixed issue when activating a ReadOnly field when the underlying value is being modified. (#8242)
f31d53093b5 TestEngine: for consistency, title bar / window items are registered in _Menu layer.
13c4084362b Nav: Fixed an issue where Alt key would clear current active item on windows with the ImGuiWindowFlags_NoNavInputs flag. (#8231)
f5f11e94be3 InputText: Fixed a bug where character replacements performed from a callback were not applied when pasting from clipbard. (#8229)
324d4bb1402 InputText: calling ReloadUserBuf doesn't clear undo stack. (#2890)
8237ab450e3 Drags, Sliders: store initial value on activation, as a convenience for some mods. (#8223)
4ad5496474b Drags: Added ImGuiSliderFlags_NoSpeedTweaks flag to disable keyboard modifiers altering the tweak speed. (#8223)
f9f4e22f6f7 InputText: some tidying up. (#7925)
4cc464eadc1 BeginListBox(): Comments (#8220)
1d069cf4352 Fonts: store 0 for unset EllipsisChar/FallbackChar. Pull config in BuildLookupTable().
e487eb9da08 Backends: Vulkan: Fixed setting VkSwapchainCreateInfoKHR::preTransform for platforms not supporting VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. (#8222)
f25665f3600 Version 1.91.7 WIP
993fa347495 Version 1.91.6
2ca83f0bc72 Fixed missing symbols when using IMGUI_DISABLE_DEMO_WINDOWS (e.g. with ImPlot) (#8221)
c3ffd4c53e9 Misc: Added IMGUI_USE_LEGACY_CRC32_ADLER to use old tables. (#8169, #4933)
d78e823449f InputText: added ImGuiInputTextFlags_ElideLeft. (#1442, #1440, #4391, #7208, #8216)
d2645423de8 InputText: reactivating last activated InputText() doesn't restore horizontal scrolling.
f3147f446a7 Backends: OpenGL3: call glGetString(GL_VERSION) even in GS ES 2.0 path. (#8197)
921c22f5adc Examples: GLFW+OpenGL3, SDL3+OpenGL3: Provide ES3 context creation code + failure handling. (#8197)
6b348622bb8 Examples: SDL2+OpenGL3: Provide ES3 context creation code + failure handling. (#8197)
fce07bb1cb4 Don't enable SSE4 under Emscripten - Fix. (#8213, #8169, #4933)
53dd7552dcb Backends: DX12: let the user specifies the DepthStencilView format. (#8217)
2671f68f7f8 Don't enable SSE4 under Emscripten (#8213, #8169, #4933)
3f3c62a3c99 ScrollbarEx: clarify use of flags and make them optional. (#8215)
18e5d769fd7 Backends: DX10: create sampler outside of ImGui_ImplDX11_CreateFontsTexture().
43fbd7ce840 Backends: standardized top of file comments.
566558b17c5 Replacing NULL with nullptr in examples/backends when they creeped back. (#6313, #7071, #4537)
6f6ac84228a Demo: Assets Browser: use correct axis for layout computation, to allow making items non-square. (#8207)
70b6ba42402 Clarify that IMGUI_USE_BGRA_PACKED_COLOR requires backend support. (#8201)
923ca4765a8 Backends: OpenGL3: Fix compile error with IMGUI_IMPL_OPENGL_ES2 and IMGUI_IMPL_OPENGL_DEBUG (#8197)
43c51eb12d1 Tables: fixed SetNextWindowScroll() value being ignored by BeginTable() during the first frame or when scrolling flags have changed. (#8196)
ee2119d7cbe imgui_freetype: Fix build broken by 19a1f2a (#8107)
19a1f2a5d2c Fonts: fixed AddCustomRect() not being packed with TexGlyphPadding + not accounted in surface area. (#8107)
9b26743c6b3 SliderAngle: only write back to value v_rad on value_changed. (#8193)
dda7672008e Backends: Vulkan: removed sizeof(ImTextureID) check.
c1123fd8d05 Backends: Vulkan: small refactor to use a texture struct.
90dd510df1e Backends: DX11: create sampler outside of ImGui_ImplDX11_CreateFontsTexture().
96877eb9c30 Backends: Vulkan: fixed build with VK_NO_PROTOTYPES. (#8172, #4867)
2d660108b27 Misc: amend crc32 to use _mm_crc32_u32. (#8169, #4933)
326dc95f9c7 Misc: use native crc32 instructions on SEE 4.2 targets. (#8169, #4933)
e6dd8f626a1 Misc: changed CRC32 table to use crc32c polynomial in order to be compatible with SSE 4.2 instructions. (#8169, #4933)
61ab94d5534 Backends: Vulkan: Make descriptor pool optional (#8172, #4867)
9b273294377 Comments on ImageButton(). (#8165) + comments on Emscripten -sSINGLE_FILE option. (#8153)
5b7feebfd8f Backends: DX9: extract RGBA convert loop as we are going to need it more often.
dfbf1b4f6b1 Backends: DX9: cache result of ImGui_ImplDX9_CheckFormatSupport() as we are going to need it more often.
20360e00ceb Merge miscellaneous small changes to reduce drift with texture update branch.
551b6c4d662 Tools: binary_to_compressed_c: added -u8/-u32/-base85 export options.
d0e870aad2c Misc: changed embedded ProggyClean encoding to save a bit of binary space (~12kb to 9.5kb). (#8161)
5ae3dd52a07 Fonts: added IMGUI_DISABLE_DEFAULT_FONT macro. (#8161)
eb0ad66d88d Demo: example tree used by Property Editor & Selection demos properly freed on app closure. (#8158)
142827f7d86 Backends: DX12: rework legacy path for handling ImGui_ImplDX12_Init() being called with space for a single descriptor.
08400f5be7f Backends: DX12: tidying up, added a ImGui_ImplDX12_Texture helper struct.
40b2286d16e (Breaking) Backends: DX12: changed ImGui_ImplDX12_Init() signature. Added ImGui_ImplDX12_InitInfo. Added support for Srv allocators.
3260ea69545 Examples: Win32+DX12: Tweaks.
8be0723fb7a Amend Changelog to better document how changing button behavior of InputInt/InputFloat step buttons affected some mis-uses (#8149)
e97b97467e4 Error Handling: fixed cases where recoverable error handling would crash. (#1651)
3381ab423b3 Version 1.91.6 WIP + fixed typo in tooltip.
f401021d5a5 Version 1.91.5
31b967f098d Fix 01d27a4 (sorry I cherry-picked from wrong branch)
01d27a4acde Internals: added IM_LIKELY(), IM_UNLIKELY() helper macros (yet unused). Added ImFontGetCharAdvanceX() macro.
419a9ada16e Ignore clang warning Wnontrivial-memaccess (#8129, #8135)
17bd417a3d1 AddCustomRectFontGlyph: added storage for Colored bool in ImFontAtlasCustomRect. (#8133)
3b683927ee6 imgui_freetype: Fixed a crash in build font atlas when using merged fonts and the first font in a merged set has no loaded glyph. (#8081)
3543dfda953 Docs: document removal of ImFont const qualifier as potentially breaking.
d97bbf19042 Tabs, Style: made ImGuiCol_TabDimmedSelectedOverline alpha 0 (not visible) in default styles.
df0776e931d (Breaking) Removed ImGuiKey_COUNT. (#4921)
738d6db3e6b (Breaking) Removed used of ImGuiKey_KeysData_SIZE, ImGuiKey_KeysData_OFFSET. (#4921)
6f287dd16d5 (Breaking) Removed pre-1.87 obsolete io.KeyMap[], io.KeysDown[], io.NavInputs[]. Remove IMGUI_DISABLE_OBSOLETE_KEYIO. (#4921)
57ab2b42260 Fixed unused function warning (#8130)
ec2f1d69c8d Docs: word-wrap some the older changelogs.
63234f8dd0a InputText: Internals: rename CurLenA->TextLen, InitialTextA->TextToRevertTo.
be2d006e2e7 Align warning blocks. Removed -Wunused-function, -Wmissing-prototypes from imgui_internal.h
88e232739bc Ignore clang warning Wnontrivial-memaccess (#8129)
d4791f1bbef Fixed a comment typo. (#8128)
82d0584e7bb InputText: using CurLenA instead of TextA.Size for correctness. (#7925)
75f83de52ab InputText: fixed a bug (regression in 1.91.2) where modifying text buffer within a callback would sometimes prevents further appending to the buffer. (#7925)
f77d22837c0 Examples: Android+OpenGL: Using ALooper_pollOnce() instead of ALooper_pollAll(). (#8013)
71c77c081ac Demo: added a "Windows" section.
772ca9e9a9d Log/Capture: added experimental io.ConfigWindowsCopyContentsWithCtrlC config option.
f37a9a27e58 Log/Capture: reworked scope + decorating menus, tabs.
a4fcc93f4af Log/Capture: renaming ImGuiLogType to ImGuiLogFlags
9a0dff1bc56 Buttons: using ImGuiItemFlags_ButtonRepeat makes default button behavior use PressedOnClick instead of PressedOnClickRelease when unspecified.
0bde57c25a9 Font, Misc: remove qualifier from most font functions.
3b8c7d0326d Backends: Win32: rework to add ImGui_ImplWin32_WndProcHandlerEx() not using current context (experimental). (#8069, #6293, #5856, #586)
d67e2eea1a0 Backends: Win32: internal rename.
81b689b9693 Backends: OpenGL3: added additional debug GL_CALL enclosure for glCreateShader() calls. (#8104)
81cfe096578 Selectable, Style: selected Selectable() use _Header color instead of an arbitrary lerp between _Header and _HeaderHovered. (#8106, #1861)
ccb6646baea Examples: added SDL3+Vulkan example. (#8084, #8085)
1039b7f543c Examples: added more build_win64.bat helpers.
a908d73c16a Backends: avoid missing -Wmissing-declaration warning.  (#8087, #7997)
b4033b37ad7 Backends: WGPU: update for Dawn WGPU String usage. (#8082, #8083)
a855bd8df3c Backends: SDL2: Replace SDL_Vulkan_GetDrawableSize() forward declaration with the actual include. (#8095, #7967, #3190)
06092a9756b Backends: SDL2, SDL3: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten. (#4019, #6096, #1463)
062e580436e Fixed copy/paste error in DebugModeWindow() (#8094)
4994e75852a Backends: DX12: Unmap() call specify written range.
41f02825fc5 Version 1.91.5 WIP
99109c0b3b0 Amend Changelog, oops didn't get it in the previous commit.
83b64b8be22 Version 1.91.4
ab9ce2a927a Nav: added io.ConfigNavCursorVisibleAuto, io.ConfigNavCursorVisibleAlways. (#1074, #2048, #7237, #8059, #3200, #787)
3982cb35dcf Nav, Docs: consistently use "keyboard/gamepad" instead of sometimes "gamepad/keyboard".
1ff9768aa30 Nav: (Breaking) renamed ImGuiCol_NavHighlight to ImGuiCol_NavCursor. (#1074, #2048, #7237, #8059, #1712, #7370, #787)
634a7ed9886 Nav: added SetNavCursorVisible(). (#1074, #2048, #7237, #8059)
0bae2db77fd Internals: (Breaking) renamed NavDisableMouseHover to NavHighlightItemUnderNav.
0536ace2b6c Internals: (Breaking) renamed RenderNavHighlight() to RenderNavCursor(), ImGuiNavHighlightFlags to ImGuiNavRenderCursorFlags. (#1074, #2048, #7237, #8059, #1712, #7370, #787)
23b655f8e3a Internals: (Breaking) changed g.NavDisableHighlight to g.NavCursorVisible : same logic but inverted value. (#1074, #2048, #7237, #8059, #1712, #7370, #787)
7a56b411247 Nav: added io.ConfigNavEscapeClearFocusItem. (#8059, #2048, #1074, #3200)
db26fe7ca8d Debug Tools: Metrics: Fixed a crash when browsing "InputText" section before using one. (#8071)
604f2fa84aa InputScalar: added an assert to clarify that ImGuiInputTextFlags_EnterReturnsTrue is not supported by InputFloat, InputInt etc. (#8065)
38617a5ad34 Internals: remove ImGuiInputTextFlags_NoMarkEdited and g.LockMarkEdited n favor of ImGuiItemFlags_NoMarkEdited.
0f6a463fae5 Internals: rename ImGuiTreeNodeStackData::InFlags and ImGuiNavItemData::InFlags to ItemFlags too.
e6b5cafe65f Internals: rename ImGuiLastItemData::InFlags -> ItemFlags. ImGuiNextItemData::Flags -> HasFlags to avoid mistakes.
706438a43c3 Disabled: clicking a disabled item focuses parent window. Fix/amend 83ecc84. (#8064)
04d9a045570 imgui_freetype: Added support for plutosvg to render OpenType SVG fonts.  (#7927, #7187 + #6591, #6607)
83ecc846dc4 Disabled: clicking a disabled item focuses parent window. (#8064)
67e5f3505d4 InvisibleButton: disable navigation properly + added ImGuiButtonFlags_EnableNav to enable navigation. (#8057)
971d243a872 Fixed typo (#8063)
49a9eee33f2 Commented out obsolete internals's SetItemUsingMouseWheel() (#2891), TreeNodeBehaviorIsOpen() (#4814, #5423, #282, #2958, #924)
50de550ecdd Tooltips: fixed incorrect tooltip positioning when using keyboard/gamepad navigation (1.91.3 regression). (#8036)
42f47590f98 Fixed ad37b79 breaking IsItemHovered()->IsItemFocused() passthrough for navigation.
97da66209cf Internals: removing ImGuiButtonFlags_Repeat (in favor of ImGuiItemFlags_ButtonRepeat), ImGuiButtonFlags_DontClosePopups (unused)
462d1674568 Nav: rectangle highlight not rendered for items with ImGuiItemFlags_NoNav. (#8057)
ad37b79bca2 Nav: shallow tidying up.
626d358e55e Nav: fixed Ctrl+Tab so when starting with no focused window it starts from the top-most window. (#3200)
b0010389011 Nav: added io.ConfigNavEscapeClearFocusWindow to clear focused window on Escape. (#3200)
ba5161740ea Amend d885fe4, fixes default value of ConfigNavCaptureKeyboard. (#2517, #2009)
d885fe4dd0c (Breaking) moved ImGuiConfigFlags_NavEnableSetMousePos -> io.ConfigNavMoveSetMousePos, ImGuiConfigFlags_NavNoCaptureKeyboard -> ConfigNavCaptureKeyboard. (#2517, #2009)
349af8766cb InputText: ensure mouse cursor is set regardless of whether keyboard mode is enabled or not. (#6417)
20ae8bd4c32 Error Handling: turned IsItemHovered()/IsWindowHovered() checks into IM_ASSERT_USER_ERROR. (#1651)
c4bc6744824 IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921)
98d52b7b26c DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665)
f29e505d94e CI: remove --disableLicenseExpirationCheck.
a0b811dd373 Backends: SDLRenderer2/3: expose selected state in ImGui_ImplXXXX_RenderState structures during render loop. (#6969, #5834, #7468, #3590 + #7616)
9fbc3134591 InputText: amend 661bba0. (#8048)
661bba09ce1 InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys. (#8048)
f3d242a90d6 Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218)
c3629adbeb2 Backends: Metal: fixed ImTextureID cast. (#1641)
6b8accbfa1b Fixed building when defining ImTextureID to a multi-token name. (#1641)
92b94980c69 (Breaking) Default ImTextureID to use a Im64 instead of void* (#1641)
19b494df89f Examples: DirectX12: update Windows SDK version.
f890d853816 Backends: Fixed typo in comments from old wip work 'io.BackendRendererRenderState' -> 'platform_io.Renderer_RenderState'.  (#6969, #5834, #7468, #3590
42206b3d513 Backends: DX9, DX10, DX11, DX12, OpenGL, Vulkan, WGPU: Changed default texture sampler to Clamp instead of Repeat/Wrap. (#7468, #7511, #5999, #5502)
74dd38d27c9 Backends: Vulkan: fixed warnings when building in 32-bit mode.
e94f95d82b9 Backends: DX11, DX12, Vulkan, WGPU: Expose some backend-specific render state usable for callbacks. (#6969, #5834, #7468, #3590)
9bd5d8a2405 Backends: misc renaming of locals. Use 'draw_list' instead of 'cmd_list'. Avoid using 'ctx'.
1dde20ff4a1 Version 1.91.4 WIP

git-subtree-dir: external/imgui/imgui
git-subtree-split: 5c1d2d1e4c562a2ed3efbc64476e703a655b45fd
2025-01-18 13:40:21 +01:00

812 lines
42 KiB
C++

// dear imgui: Platform Backend for SDL2
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
// (Prefer SDL 2.0.5+ for full feature support.)
// Implemented features:
// [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
// - io.PlatformSetImeDataFn -> platform_io.Platform_SetImeDataFn
// 2024-08-19: Storing SDL's Uint32 WindowID inside ImGuiViewport::PlatformHandle instead of SDL_Window*.
// 2024-08-19: ImGui_ImplSDL2_ProcessEvent() now ignores events intended for other SDL windows. (#7853)
// 2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
// 2024-02-14: Inputs: Handle gamepad disconnection. Added ImGui_ImplSDL2_SetGamepadMode().
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's unclear exactly what their relation is to IME. (#6306)
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
// 2023-02-23: Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644)
// 2023-02-07: Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()).
// 2023-02-07: *BREAKING CHANGE* Renamed this backend file from imgui_impl_sdl.cpp/.h to imgui_impl_sdl2.cpp/.h in prevision for the future release of SDL3.
// 2023-02-02: Avoid calling SDL_SetCursor() when cursor has not changed, as the function is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version).
// 2023-02-02: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data for smooth scrolling + Scaling X value on Emscripten (bug?). (#4019, #6096)
// 2023-02-02: Removed SDL_MOUSEWHEEL value clamping, as values seem correct in latest Emscripten. (#4019)
// 2023-02-01: Flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-09-26: Inputs: Disable SDL 2.0.22 new "auto capture" (SDL_HINT_MOUSE_AUTO_CAPTURE) which prevents drag and drop across windows for multi-viewport support + don't capture when drag and dropping. (#5710)
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
// 2022-03-22: Inputs: Fix mouse position issues when dragging outside of boundaries. SDL_CaptureMouse() erroneously still gives out LEAVE events when hovering OS decorations.
// 2022-03-22: Inputs: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2).
// 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer.
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates.
// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
// 2021-06-29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'.
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples.
// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter.
// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText).
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS).
// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes.
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS.
// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_impl_sdl2.h"
// Clang warnings with -Weverything
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#endif
// SDL
#include <SDL.h>
#include <SDL_syswm.h>
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten/em_js.h>
#endif
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
#else
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
#endif
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
#if SDL_HAS_VULKAN
#include <SDL_vulkan.h>
#endif
// SDL Data
struct ImGui_ImplSDL2_Data
{
SDL_Window* Window;
Uint32 WindowID;
SDL_Renderer* Renderer;
Uint64 Time;
char* ClipboardTextData;
// Mouse handling
Uint32 MouseWindowID;
int MouseButtonsDown;
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
SDL_Cursor* MouseLastCursor;
int MouseLastLeaveFrame;
bool MouseCanUseGlobalState;
// Gamepad handling
ImVector<SDL_GameController*> Gamepads;
ImGui_ImplSDL2_GamepadMode GamepadMode;
bool WantUpdateGamepadsList;
ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); }
};
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
{
return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
}
// Functions
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
if (bd->ClipboardTextData)
SDL_free(bd->ClipboardTextData);
bd->ClipboardTextData = SDL_GetClipboardText();
return bd->ClipboardTextData;
}
static void ImGui_ImplSDL2_SetClipboardText(ImGuiContext*, const char* text)
{
SDL_SetClipboardText(text);
}
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport*, ImGuiPlatformImeData* data)
{
if (data->WantVisible)
{
SDL_Rect r;
r.x = (int)data->InputPos.x;
r.y = (int)data->InputPos.y;
r.w = 1;
r.h = (int)data->InputLineHeight;
SDL_SetTextInputRect(&r);
}
}
// Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
{
IM_UNUSED(scancode);
switch (keycode)
{
case SDLK_TAB: return ImGuiKey_Tab;
case SDLK_LEFT: return ImGuiKey_LeftArrow;
case SDLK_RIGHT: return ImGuiKey_RightArrow;
case SDLK_UP: return ImGuiKey_UpArrow;
case SDLK_DOWN: return ImGuiKey_DownArrow;
case SDLK_PAGEUP: return ImGuiKey_PageUp;
case SDLK_PAGEDOWN: return ImGuiKey_PageDown;
case SDLK_HOME: return ImGuiKey_Home;
case SDLK_END: return ImGuiKey_End;
case SDLK_INSERT: return ImGuiKey_Insert;
case SDLK_DELETE: return ImGuiKey_Delete;
case SDLK_BACKSPACE: return ImGuiKey_Backspace;
case SDLK_SPACE: return ImGuiKey_Space;
case SDLK_RETURN: return ImGuiKey_Enter;
case SDLK_ESCAPE: return ImGuiKey_Escape;
case SDLK_QUOTE: return ImGuiKey_Apostrophe;
case SDLK_COMMA: return ImGuiKey_Comma;
case SDLK_MINUS: return ImGuiKey_Minus;
case SDLK_PERIOD: return ImGuiKey_Period;
case SDLK_SLASH: return ImGuiKey_Slash;
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
case SDLK_EQUALS: return ImGuiKey_Equal;
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen;
case SDLK_PAUSE: return ImGuiKey_Pause;
case SDLK_KP_0: return ImGuiKey_Keypad0;
case SDLK_KP_1: return ImGuiKey_Keypad1;
case SDLK_KP_2: return ImGuiKey_Keypad2;
case SDLK_KP_3: return ImGuiKey_Keypad3;
case SDLK_KP_4: return ImGuiKey_Keypad4;
case SDLK_KP_5: return ImGuiKey_Keypad5;
case SDLK_KP_6: return ImGuiKey_Keypad6;
case SDLK_KP_7: return ImGuiKey_Keypad7;
case SDLK_KP_8: return ImGuiKey_Keypad8;
case SDLK_KP_9: return ImGuiKey_Keypad9;
case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal;
case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide;
case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract;
case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
case SDLK_LCTRL: return ImGuiKey_LeftCtrl;
case SDLK_LSHIFT: return ImGuiKey_LeftShift;
case SDLK_LALT: return ImGuiKey_LeftAlt;
case SDLK_LGUI: return ImGuiKey_LeftSuper;
case SDLK_RCTRL: return ImGuiKey_RightCtrl;
case SDLK_RSHIFT: return ImGuiKey_RightShift;
case SDLK_RALT: return ImGuiKey_RightAlt;
case SDLK_RGUI: return ImGuiKey_RightSuper;
case SDLK_APPLICATION: return ImGuiKey_Menu;
case SDLK_0: return ImGuiKey_0;
case SDLK_1: return ImGuiKey_1;
case SDLK_2: return ImGuiKey_2;
case SDLK_3: return ImGuiKey_3;
case SDLK_4: return ImGuiKey_4;
case SDLK_5: return ImGuiKey_5;
case SDLK_6: return ImGuiKey_6;
case SDLK_7: return ImGuiKey_7;
case SDLK_8: return ImGuiKey_8;
case SDLK_9: return ImGuiKey_9;
case SDLK_a: return ImGuiKey_A;
case SDLK_b: return ImGuiKey_B;
case SDLK_c: return ImGuiKey_C;
case SDLK_d: return ImGuiKey_D;
case SDLK_e: return ImGuiKey_E;
case SDLK_f: return ImGuiKey_F;
case SDLK_g: return ImGuiKey_G;
case SDLK_h: return ImGuiKey_H;
case SDLK_i: return ImGuiKey_I;
case SDLK_j: return ImGuiKey_J;
case SDLK_k: return ImGuiKey_K;
case SDLK_l: return ImGuiKey_L;
case SDLK_m: return ImGuiKey_M;
case SDLK_n: return ImGuiKey_N;
case SDLK_o: return ImGuiKey_O;
case SDLK_p: return ImGuiKey_P;
case SDLK_q: return ImGuiKey_Q;
case SDLK_r: return ImGuiKey_R;
case SDLK_s: return ImGuiKey_S;
case SDLK_t: return ImGuiKey_T;
case SDLK_u: return ImGuiKey_U;
case SDLK_v: return ImGuiKey_V;
case SDLK_w: return ImGuiKey_W;
case SDLK_x: return ImGuiKey_X;
case SDLK_y: return ImGuiKey_Y;
case SDLK_z: return ImGuiKey_Z;
case SDLK_F1: return ImGuiKey_F1;
case SDLK_F2: return ImGuiKey_F2;
case SDLK_F3: return ImGuiKey_F3;
case SDLK_F4: return ImGuiKey_F4;
case SDLK_F5: return ImGuiKey_F5;
case SDLK_F6: return ImGuiKey_F6;
case SDLK_F7: return ImGuiKey_F7;
case SDLK_F8: return ImGuiKey_F8;
case SDLK_F9: return ImGuiKey_F9;
case SDLK_F10: return ImGuiKey_F10;
case SDLK_F11: return ImGuiKey_F11;
case SDLK_F12: return ImGuiKey_F12;
case SDLK_F13: return ImGuiKey_F13;
case SDLK_F14: return ImGuiKey_F14;
case SDLK_F15: return ImGuiKey_F15;
case SDLK_F16: return ImGuiKey_F16;
case SDLK_F17: return ImGuiKey_F17;
case SDLK_F18: return ImGuiKey_F18;
case SDLK_F19: return ImGuiKey_F19;
case SDLK_F20: return ImGuiKey_F20;
case SDLK_F21: return ImGuiKey_F21;
case SDLK_F22: return ImGuiKey_F22;
case SDLK_F23: return ImGuiKey_F23;
case SDLK_F24: return ImGuiKey_F24;
case SDLK_AC_BACK: return ImGuiKey_AppBack;
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
default: break;
}
return ImGuiKey_None;
}
static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
{
ImGuiIO& io = ImGui::GetIO();
io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & KMOD_CTRL) != 0);
io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & KMOD_SHIFT) != 0);
io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & KMOD_ALT) != 0);
io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0);
}
static ImGuiViewport* ImGui_ImplSDL2_GetViewportForWindowID(Uint32 window_id)
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
return (window_id == bd->WindowID) ? ImGui::GetMainViewport() : nullptr;
}
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
{
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();
switch (event->type)
{
case SDL_MOUSEMOTION:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->motion.windowID) == nullptr)
return false;
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
return true;
}
case SDL_MOUSEWHEEL:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->wheel.windowID) == nullptr)
return false;
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
#if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten!
float wheel_x = -event->wheel.preciseX;
float wheel_y = event->wheel.preciseY;
#else
float wheel_x = -(float)event->wheel.x;
float wheel_y = (float)event->wheel.y;
#endif
#if defined(__EMSCRIPTEN__) && !SDL_VERSION_ATLEAST(2,31,0)
wheel_x /= 100.0f;
#endif
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
io.AddMouseWheelEvent(wheel_x, wheel_y);
return true;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->button.windowID) == nullptr)
return false;
int mouse_button = -1;
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
if (event->button.button == SDL_BUTTON_X1) { mouse_button = 3; }
if (event->button.button == SDL_BUTTON_X2) { mouse_button = 4; }
if (mouse_button == -1)
break;
io.AddMouseSourceEvent(event->button.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN));
bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
return true;
}
case SDL_TEXTINPUT:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->text.windowID) == nullptr)
return false;
io.AddInputCharactersUTF8(event->text.text);
return true;
}
case SDL_KEYDOWN:
case SDL_KEYUP:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID) == nullptr)
return false;
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.
return true;
}
case SDL_WINDOWEVENT:
{
if (ImGui_ImplSDL2_GetViewportForWindowID(event->window.windowID) == nullptr)
return false;
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
// - However we won't get a correct LEAVE event for a captured window.
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
// causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why
// we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details.
Uint8 window_event = event->window.event;
if (window_event == SDL_WINDOWEVENT_ENTER)
{
bd->MouseWindowID = event->window.windowID;
bd->MouseLastLeaveFrame = 0;
}
if (window_event == SDL_WINDOWEVENT_LEAVE)
bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1;
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
io.AddFocusEvent(true);
else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
io.AddFocusEvent(false);
return true;
}
case SDL_CONTROLLERDEVICEADDED:
case SDL_CONTROLLERDEVICEREMOVED:
{
bd->WantUpdateGamepadsList = true;
return true;
}
}
return false;
}
#ifdef __EMSCRIPTEN__
EM_JS(void, ImGui_ImplSDL2_EmscriptenOpenURL, (char const* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); });
#endif
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
{
ImGuiIO& io = ImGui::GetIO();
IMGUI_CHECKVERSION();
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
// Check and store if we are on a SDL backend that supports global mouse position
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
bool mouse_can_use_global_state = false;
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
const char* sdl_backend = SDL_GetCurrentVideoDriver();
const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
mouse_can_use_global_state = true;
#endif
// Setup backend capabilities flags
ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
io.BackendPlatformUserData = (void*)bd;
io.BackendPlatformName = "imgui_impl_sdl2";
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
bd->Window = window;
bd->WindowID = SDL_GetWindowID(window);
bd->Renderer = renderer;
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
platform_io.Platform_ClipboardUserData = nullptr;
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData;
#ifdef __EMSCRIPTEN__
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
#endif
// Gamepad handling
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
bd->WantUpdateGamepadsList = true;
// Load mouse cursors
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
// Set platform dependent data in viewport
// Our mouse update function expect PlatformHandle to be filled for the main viewport
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = (void*)(intptr_t)bd->WindowID;
main_viewport->PlatformHandleRaw = nullptr;
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWindowWMInfo(window, &info))
{
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
#endif
}
// From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
// Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
// (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
// It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
// you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
#endif
// From 2.0.18: Enable native IME.
// IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any.
// For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow().
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
#endif
(void)sdl_gl_context; // Unused in 'master' branch.
return true;
}
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
{
return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context);
}
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
{
#if !SDL_HAS_VULKAN
IM_ASSERT(0 && "Unsupported");
#endif
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
}
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
{
#if !defined(_WIN32)
IM_ASSERT(0 && "Unsupported");
#endif
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
}
bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
{
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
}
bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
{
return ImGui_ImplSDL2_Init(window, renderer, nullptr);
}
bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
{
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
}
static void ImGui_ImplSDL2_CloseGamepads();
void ImGui_ImplSDL2_Shutdown()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO();
if (bd->ClipboardTextData)
SDL_free(bd->ClipboardTextData);
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
SDL_FreeCursor(bd->MouseCursors[cursor_n]);
ImGui_ImplSDL2_CloseGamepads();
io.BackendPlatformName = nullptr;
io.BackendPlatformUserData = nullptr;
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
IM_DELETE(bd);
}
static void ImGui_ImplSDL2_UpdateMouseData()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
SDL_Window* focused_window = SDL_GetKeyboardFocus();
const bool is_app_focused = (bd->Window == focused_window);
#else
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
#endif
if (is_app_focused)
{
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
if (io.WantSetMousePos)
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
{
int window_x, window_y, mouse_x_global, mouse_y_global;
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
SDL_GetWindowPosition(bd->Window, &window_x, &window_y);
io.AddMousePosEvent((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
}
}
}
static void ImGui_ImplSDL2_UpdateMouseCursor()
{
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
SDL_ShowCursor(SDL_FALSE);
}
else
{
// Show OS mouse cursor
SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
if (bd->MouseLastCursor != expected_cursor)
{
SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113)
bd->MouseLastCursor = expected_cursor;
}
SDL_ShowCursor(SDL_TRUE);
}
}
static void ImGui_ImplSDL2_CloseGamepads()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
if (bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
for (SDL_GameController* gamepad : bd->Gamepads)
SDL_GameControllerClose(gamepad);
bd->Gamepads.resize(0);
}
void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array, int manual_gamepads_count)
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGui_ImplSDL2_CloseGamepads();
if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
{
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
for (int n = 0; n < manual_gamepads_count; n++)
bd->Gamepads.push_back(manual_gamepads_array[n]);
}
else
{
IM_ASSERT(manual_gamepads_array == nullptr && manual_gamepads_count <= 0);
bd->WantUpdateGamepadsList = true;
}
bd->GamepadMode = mode;
}
static void ImGui_ImplSDL2_UpdateGamepadButton(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerButton button_no)
{
bool merged_value = false;
for (SDL_GameController* gamepad : bd->Gamepads)
merged_value |= SDL_GameControllerGetButton(gamepad, button_no) != 0;
io.AddKeyEvent(key, merged_value);
}
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; }
static void ImGui_ImplSDL2_UpdateGamepadAnalog(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerAxis axis_no, float v0, float v1)
{
float merged_value = 0.0f;
for (SDL_GameController* gamepad : bd->Gamepads)
{
float vn = Saturate((float)(SDL_GameControllerGetAxis(gamepad, axis_no) - v0) / (float)(v1 - v0));
if (merged_value < vn)
merged_value = vn;
}
io.AddKeyAnalogEvent(key, merged_value > 0.1f, merged_value);
}
static void ImGui_ImplSDL2_UpdateGamepads()
{
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGuiIO& io = ImGui::GetIO();
// Update list of controller(s) to use
if (bd->WantUpdateGamepadsList && bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
{
ImGui_ImplSDL2_CloseGamepads();
int joystick_count = SDL_NumJoysticks();
for (int n = 0; n < joystick_count; n++)
if (SDL_IsGameController(n))
if (SDL_GameController* gamepad = SDL_GameControllerOpen(n))
{
bd->Gamepads.push_back(gamepad);
if (bd->GamepadMode == ImGui_ImplSDL2_GamepadMode_AutoFirst)
break;
}
bd->WantUpdateGamepadsList = false;
}
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return;
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (bd->Gamepads.Size == 0)
return;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
// Update gamepad inputs
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK);
ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768);
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
}
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 time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
static Uint64 frequency = SDL_GetPerformanceFrequency();
Uint64 current_time = SDL_GetPerformanceCounter();
if (current_time <= bd->Time)
current_time = bd->Time + 1;
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time;
if (bd->MouseLastLeaveFrame && bd->MouseLastLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
{
bd->MouseWindowID = 0;
bd->MouseLastLeaveFrame = 0;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
}
ImGui_ImplSDL2_UpdateMouseData();
ImGui_ImplSDL2_UpdateMouseCursor();
// Update game controllers (if enabled and available)
ImGui_ImplSDL2_UpdateGamepads();
}
//-----------------------------------------------------------------------------
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE