Skip to content

Commit fac19e1

Browse files
committed
Backends: SDL2:+SDL3 Implement SetPlatformImeDataFn (amends). (#6071, #1953) + fix SDL3 setting PlatformHandleRaw. (#6146)
1 parent 734c6af commit fac19e1

File tree

14 files changed

+95
-44
lines changed

14 files changed

+95
-44
lines changed

backends/imgui_impl_sdl2.cpp

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
99
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
1010
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
11-
// Missing features:
12-
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
11+
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
1312

1413
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1514
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -18,6 +17,7 @@
1817

1918
// CHANGELOG
2019
// (minor and older changes stripped away, please see git history for details)
20+
// 2023-02-07: Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()).
2121
// 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.
2222
// 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).
2323
// 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)
@@ -84,7 +84,6 @@
8484
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
8585
#endif
8686
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
87-
#define SDL_HAS_SET_TEXT_INPUT_RECT SDL_VERSION_ATLEAST(2,0,0)
8887

8988
// SDL Data
9089
struct ImGui_ImplSDL2_Data
@@ -127,6 +126,25 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
127126
SDL_SetClipboardText(text);
128127
}
129128

129+
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
130+
static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
131+
{
132+
if (data->WantVisible)
133+
{
134+
SDL_Rect r;
135+
r.x = (int)data->InputPos.x;
136+
r.y = (int)data->InputPos.y;
137+
r.w = 1;
138+
r.h = (int)data->InputLineHeight;
139+
SDL_SetTextInputRect(&r);
140+
SDL_StartTextInput();
141+
}
142+
else
143+
{
144+
SDL_StopTextInput();
145+
}
146+
}
147+
130148
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
131149
{
132150
switch (keycode)
@@ -337,27 +355,6 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
337355
return false;
338356
}
339357

340-
#if SDL_HAS_SET_TEXT_INPUT_RECT
341-
static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlatformImeData* data)
342-
{
343-
(void)viewport;
344-
if (data->WantVisible)
345-
{
346-
SDL_Rect r;
347-
r.x = (int)data->InputPos.x;
348-
r.y = (int)data->InputPos.y;
349-
r.w = 1;
350-
r.h = (int)data->InputLineHeight;
351-
SDL_SetTextInputRect(&r);
352-
SDL_StartTextInput();
353-
}
354-
else
355-
{
356-
SDL_StopTextInput();
357-
}
358-
}
359-
#endif
360-
361358
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
362359
{
363360
ImGuiIO& io = ImGui::GetIO();
@@ -388,10 +385,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
388385
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
389386
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
390387
io.ClipboardUserData = nullptr;
391-
392-
#if SDL_HAS_SET_TEXT_INPUT_RECT
393388
io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData;
394-
#endif
395389

396390
// Load mouse cursors
397391
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
@@ -428,6 +422,13 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
428422
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
429423
#endif
430424

425+
// From 2.0.18: Enable native IME.
426+
// IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any.
427+
// For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow().
428+
#ifdef SDL_HINT_IME_SHOW_UI
429+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
430+
#endif
431+
431432
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
432433
#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE
433434
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");

backends/imgui_impl_sdl2.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
88
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
99
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
10-
// Missing features:
11-
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
10+
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
1211

1312
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1413
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

backends/imgui_impl_sdl3.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
99
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
1010
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
11+
// Missing features:
12+
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
1113

1214
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1315
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -75,6 +77,24 @@ static void ImGui_ImplSDL3_SetClipboardText(void*, const char* text)
7577
SDL_SetClipboardText(text);
7678
}
7779

80+
static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
81+
{
82+
if (data->WantVisible)
83+
{
84+
SDL_Rect r;
85+
r.x = (int)data->InputPos.x;
86+
r.y = (int)data->InputPos.y;
87+
r.w = 1;
88+
r.h = (int)data->InputLineHeight;
89+
SDL_SetTextInputRect(&r);
90+
SDL_StartTextInput();
91+
}
92+
else
93+
{
94+
SDL_StopTextInput();
95+
}
96+
}
97+
7898
static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
7999
{
80100
switch (keycode)
@@ -310,6 +330,7 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer)
310330
io.SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
311331
io.GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
312332
io.ClipboardUserData = nullptr;
333+
io.SetPlatformImeDataFn = ImGui_ImplSDL3_SetPlatformImeData;
313334

314335
// Load mouse cursors
315336
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
@@ -327,11 +348,11 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer)
327348
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
328349
main_viewport->PlatformHandleRaw = nullptr;
329350
SDL_SysWMinfo info;
330-
if (SDL_GetWindowWMInfo(window, &info, SDL_SYSWM_CURRENT_VERSION))
351+
if (SDL_GetWindowWMInfo(window, &info, SDL_SYSWM_CURRENT_VERSION) == 0)
331352
{
332-
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
353+
#if defined(SDL_ENABLE_SYSWM_WINDOWS)
333354
main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
334-
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
355+
#elif defined(__APPLE__) && defined(SDL_ENABLE_SYSWM_COCOA)
335356
main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
336357
#endif
337358
}

backends/imgui_impl_sdl3.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
99
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
1010
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
11+
// Missing features:
12+
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
1113

1214
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1315
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

docs/CHANGELOG.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ All changes:
9898
for smooth scrolling as reported by SDL. (#4019, #6096)
9999
- Backends: SDL2: Avoid calling SDL_SetCursor() when cursor has not changed, as the function
100100
is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version). (#6113)
101+
- Backends: SDL2: Implement IME handler to call SDL_SetTextInputRect()/SDL_StartTextInput().
102+
It will only works with SDL 2.0.18+ if your code calls 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1")'
103+
prior to calling SDL_CreateWindow(). Updated all examples accordingly. (#6071, #1953)
101104
- Backends: SDL3: Added experimental imgui_impl_sdl3.cpp backend. (#6146) [@dovker, @ocornut]
102105
SDL 3.0.0 has not yet been released, so it is possible that its specs/api will change before
103106
release. This backend is provided as a convenience for early adopters etc. We don't recommend

examples/example_sdl2_directx11/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ int main(int, char**)
3535
return -1;
3636
}
3737

38+
// From 2.0.18: Enable native IME.
39+
#ifdef SDL_HINT_IME_SHOW_UI
40+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
41+
#endif
42+
3843
// Setup window
3944
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
4045
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);

examples/example_sdl2_metal/main.mm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ int main(int, char**)
5353
// Inform SDL that we will be using metal for rendering. Without this hint initialization of metal renderer may fail.
5454
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal");
5555

56+
// Enable native IME.
57+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
58+
5659
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
5760
if (window == NULL)
5861
{

examples/example_sdl2_opengl2/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ int main(int, char**)
2424
return -1;
2525
}
2626

27+
// From 2.0.18: Enable native IME.
28+
#ifdef SDL_HINT_IME_SHOW_UI
29+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
30+
#endif
31+
2732
// Setup window
2833
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
2934
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

examples/example_sdl2_opengl3/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ int main(int, char**)
5353
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
5454
#endif
5555

56+
// From 2.0.18: Enable native IME.
57+
#ifdef SDL_HINT_IME_SHOW_UI
58+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
59+
#endif
60+
5661
// Create window with graphics context
5762
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
5863
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

examples/example_sdl2_sdlrenderer/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ int main(int, char**)
2727
return -1;
2828
}
2929

30+
// From 2.0.18: Enable native IME.
31+
#ifdef SDL_HINT_IME_SHOW_UI
32+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
33+
#endif
34+
3035
// Create window with SDL_Renderer graphics context
3136
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
3237
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);

examples/example_sdl2_vulkan/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@ int main(int, char**)
350350
return -1;
351351
}
352352

353+
// From 2.0.18: Enable native IME.
354+
#ifdef SDL_HINT_IME_SHOW_UI
355+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
356+
#endif
357+
353358
// Create window with Vulkan graphics context
354359
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
355360
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);

examples/example_sdl3_opengl3/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ int main(int, char**)
5353
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
5454
#endif
5555

56+
// Enable native IME.
57+
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
58+
5659
// Create window with graphics context
5760
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
5861
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

examples/imgui_examples.sln

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl2_sdlrenderer",
2727
EndProject
2828
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl2_vulkan", "example_sdl2_vulkan\example_sdl2_vulkan.vcxproj", "{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}"
2929
EndProject
30-
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_opengl3", "example_sdl3_opengl3\example_sdl3_opengl3.vcxproj", "{84AAA301-84FE-428B-9E3E-817BC8123C0C}"
31-
EndProject
3230
Global
3331
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3432
Debug|Win32 = Debug|Win32
@@ -133,14 +131,6 @@ Global
133131
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|Win32.Build.0 = Release|Win32
134132
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|x64.ActiveCfg = Release|x64
135133
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|x64.Build.0 = Release|x64
136-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|Win32.ActiveCfg = Debug|Win32
137-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|Win32.Build.0 = Debug|Win32
138-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|x64.ActiveCfg = Debug|x64
139-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Debug|x64.Build.0 = Debug|x64
140-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|Win32.ActiveCfg = Release|Win32
141-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|Win32.Build.0 = Release|Win32
142-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|x64.ActiveCfg = Release|x64
143-
{84AAA301-84FE-428B-9E3E-817BC8123C0C}.Release|x64.Build.0 = Release|x64
144134
EndGlobalSection
145135
GlobalSection(SolutionProperties) = preSolution
146136
HideSolutionNode = FALSE

imgui.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4819,8 +4819,12 @@ void ImGui::EndFrame()
48194819
ErrorCheckEndFrameSanityChecks();
48204820

48214821
// Notify Platform/OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
4822-
if (g.IO.SetPlatformImeDataFn && memcmp(&g.PlatformImeData, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0)
4823-
g.IO.SetPlatformImeDataFn(GetMainViewport(), &g.PlatformImeData);
4822+
ImGuiPlatformImeData* ime_data = &g.PlatformImeData;
4823+
if (g.IO.SetPlatformImeDataFn && memcmp(ime_data, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0)
4824+
{
4825+
IMGUI_DEBUG_LOG_IO("Calling io.SetPlatformImeDataFn(): WantVisible: %d, InputPos (%.2f,%.2f)\n", ime_data->WantVisible, ime_data->InputPos.x, ime_data->InputPos.y);
4826+
g.IO.SetPlatformImeDataFn(GetMainViewport(), ime_data);
4827+
}
48244828

48254829
// Hide implicit/fallback "Debug" window if it hasn't been used
48264830
g.WithinFrameScopeWithImplicitWindow = false;

0 commit comments

Comments
 (0)