Skip to content

Commit 3a90dc3

Browse files
committed
Platform IME: changed io.ImeSetInputScreenPosFn() to io.SetPlatformImeDataFn() API.
Ref #2589, #2598, #3108, #3113, #3653, #4642
1 parent 04bc0b0 commit 3a90dc3

File tree

7 files changed

+68
-26
lines changed

7 files changed

+68
-26
lines changed

backends/imgui_impl_glfw.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
246246
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
247247
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
248248
io.ClipboardUserData = bd->Window;
249+
250+
// Set platform dependent data in viewport
249251
#if defined(_WIN32)
250-
io.ImeWindowHandle = (void*)glfwGetWin32Window(bd->Window);
252+
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)glfwGetWin32Window(bd->Window);
251253
#endif
252254

253255
// Create mouse cursors

backends/imgui_impl_sdl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,12 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
230230
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
231231
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
232232

233+
// Set platform dependent data in viewport
233234
#ifdef _WIN32
234235
SDL_SysWMinfo info;
235236
SDL_VERSION(&info.version);
236237
if (SDL_GetWindowWMInfo(window, &info))
237-
io.ImeWindowHandle = info.info.win.window;
238+
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)info.info.win.window;
238239
#else
239240
(void)window;
240241
#endif

backends/imgui_impl_win32.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ bool ImGui_ImplWin32_Init(void* hwnd)
122122
bd->Time = perf_counter;
123123
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
124124

125-
io.ImeWindowHandle = hwnd;
125+
// Set platform dependent data in viewport
126+
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
126127

127128
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
128129
io.KeyMap[ImGuiKey_Tab] = VK_TAB;

docs/CHANGELOG.txt

+11
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,24 @@ Breaking Changes:
4343
- ImGui::TreeAdvanceToLabelPos() -> use ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetTreeNodeToLabelSpacing());
4444
- ImFontAtlas::CustomRect -> use ImFontAtlasCustomRect
4545
- ImGuiColorEditFlags_RGB/HSV/HEX -> use ImGuiColorEditFlags_DisplayRGB/HSV/Hex
46+
- Removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn() for IME support.
47+
Because this field was mostly only ever used by Dear ImGui internally, not by backends nor the vast majority
48+
of user code, this should only affect a very small fraction for users who are already very IME-aware.
49+
- Obsoleted 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'.
50+
This removes an incompatibility between 'master' and 'multi-viewports' backends and toward enabling
51+
better support for IME. Updated backends accordingly. Because the old field is set by existing backends,
52+
we are keeping it (marked as obsolete).
53+
4654

4755
Other Changes:
4856

4957
- Fixed a situation where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with zero triangles,
5058
which would makes the draw operation of some backends assert (e.g. Metal with debugging). (#4857)
5159
- Tables, ImDrawListSplitter: Fixed erroneously stripping trailing ImDrawList::AddCallback() when submitted in
5260
last column or last channel and when there are no other drawing operation. (#4843, #4844) [@hoffstadt]
61+
- Platform IME: changed io.ImeSetInputScreenPosFn() to io.SetPlatformImeDataFn() API,
62+
now taking a ImGuiPlatformImeData structure which we can more easily extend in the future.
63+
- Platform IME: moved io.ImeWindowHandle to GetMainViewport()->PlatformHandleRaw.
5364
- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk]
5465
It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers.
5566
- Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz]

docs/FAQ.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,8 @@ Text input: it is up to your application to pass the right character code by cal
607607
The applications in examples/ are doing that.
608608
Windows: you can use the WM_CHAR or WM_UNICHAR or WM_IME_CHAR message (depending if your app is built using Unicode or MultiByte mode).
609609
You may also use MultiByteToWideChar() or ToUnicode() to retrieve Unicode codepoints from MultiByte characters or keyboard state.
610-
Windows: if your language is relying on an Input Method Editor (IME), you copy the HWND of your window to io.ImeWindowHandle in order for
611-
the default implementation of io.ImeSetInputScreenPosFn() to set your Microsoft IME position correctly.
610+
Windows: if your language is relying on an Input Method Editor (IME), you can write your HWND to ImGui::GetMainViewport()->PlatformHandleRaw
611+
in order for the default the default implementation of io.SetPlatformImeDataFn() to set your Microsoft IME position correctly.
612612
613613
##### [Return to Index](#index)
614614

imgui.cpp

+26-18
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ CODE
386386
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
387387
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
388388

389+
- 2022/03/05 (1.87) - removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn(). Removed 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'.
389390
- 2022/03/01 (1.87) - commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019)
390391
- ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen()
391392
- ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x
@@ -919,7 +920,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSetti
919920
// Platform Dependents default implementation for IO functions
920921
static const char* GetClipboardTextFn_DefaultImpl(void* user_data);
921922
static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
922-
static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
923+
static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatformImeData* data);
923924

924925
namespace ImGui
925926
{
@@ -1136,8 +1137,7 @@ ImGuiIO::ImGuiIO()
11361137
GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations
11371138
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
11381139
ClipboardUserData = NULL;
1139-
ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
1140-
ImeWindowHandle = NULL;
1140+
SetPlatformImeDataFn = SetPlatformImeDataFn_DefaultImpl;
11411141

11421142
// Input (NB: we already have memset zero the entire structure!)
11431143
MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
@@ -4553,9 +4553,11 @@ void ImGui::EndFrame()
45534553
ErrorCheckEndFrameSanityChecks();
45544554

45554555
// Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
4556-
if (g.IO.ImeSetInputScreenPosFn && (g.PlatformImeLastPos.x == FLT_MAX || ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f))
4556+
if (g.IO.SetPlatformImeDataFn && (g.PlatformImeLastPos.x == FLT_MAX || ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f))
45574557
{
4558-
g.IO.ImeSetInputScreenPosFn((int)g.PlatformImePos.x, (int)g.PlatformImePos.y);
4558+
ImGuiPlatformImeData data;
4559+
data.InputPos = g.PlatformImePos;
4560+
g.IO.SetPlatformImeDataFn(GetMainViewport(), &data);
45594561
g.PlatformImeLastPos = g.PlatformImePos;
45604562
}
45614563

@@ -11500,25 +11502,31 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
1150011502
#pragma comment(lib, "imm32")
1150111503
#endif
1150211504

11503-
static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
11505+
static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatformImeData* data)
1150411506
{
1150511507
// Notify OS Input Method Editor of text input position
11506-
ImGuiIO& io = ImGui::GetIO();
11507-
if (HWND hwnd = (HWND)io.ImeWindowHandle)
11508-
if (HIMC himc = ::ImmGetContext(hwnd))
11509-
{
11510-
COMPOSITIONFORM cf;
11511-
cf.ptCurrentPos.x = x;
11512-
cf.ptCurrentPos.y = y;
11513-
cf.dwStyle = CFS_FORCE_POSITION;
11514-
::ImmSetCompositionWindow(himc, &cf);
11515-
::ImmReleaseContext(hwnd, himc);
11516-
}
11508+
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
11509+
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
11510+
if (hwnd == 0)
11511+
hwnd = (HWND)ImGui::GetIO().ImeWindowHandle;
11512+
#endif
11513+
if (hwnd == 0)
11514+
return;
11515+
11516+
if (HIMC himc = ::ImmGetContext(hwnd))
11517+
{
11518+
COMPOSITIONFORM cf;
11519+
cf.ptCurrentPos.x = (LONG)data->InputPos.x;
11520+
cf.ptCurrentPos.y = (LONG)data->InputPos.y;
11521+
cf.dwStyle = CFS_FORCE_POSITION;
11522+
::ImmSetCompositionWindow(himc, &cf);
11523+
::ImmReleaseContext(hwnd, himc);
11524+
}
1151711525
}
1151811526

1151911527
#else
1152011528

11521-
static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {}
11529+
static void SetPlatformImeDataFn_De(int, int) {}
1152211530

1152311531
#endif
1152411532

imgui.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Index of this file:
3535
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData)
3636
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
3737
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
38+
// [SECTION] Platform Dependent Interfaces (ImGuiPlatformImeData)
3839
// [SECTION] Obsolete functions and types
3940
4041
*/
@@ -64,7 +65,7 @@ Index of this file:
6465
// Version
6566
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
6667
#define IMGUI_VERSION "1.87 WIP"
67-
#define IMGUI_VERSION_NUM 18602
68+
#define IMGUI_VERSION_NUM 18603
6869
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
6970
#define IMGUI_HAS_TABLE
7071

@@ -154,6 +155,7 @@ struct ImGuiInputTextCallbackData; // Shared state of InputText() when using cu
154155
struct ImGuiListClipper; // Helper to manually clip large list of items
155156
struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame
156157
struct ImGuiPayload; // User data payload for drag and drop operations
158+
struct ImGuiPlatformImeData; // Platform IME data for io.SetPlatformImeDataFn() function.
157159
struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use)
158160
struct ImGuiStorage; // Helper for key->value storage
159161
struct ImGuiStyle; // Runtime data for styling/colors
@@ -1868,8 +1870,12 @@ struct ImGuiIO
18681870

18691871
// Optional: Notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME on Windows)
18701872
// (default to use native imm32 api on Windows)
1871-
void (*ImeSetInputScreenPosFn)(int x, int y);
1872-
void* ImeWindowHandle; // = NULL // (Windows) Set this to your HWND to get automatic IME cursor positioning.
1873+
void (*SetPlatformImeDataFn)(ImGuiViewport* viewport, ImGuiPlatformImeData* data);
1874+
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
1875+
void* ImeWindowHandle; // = NULL // [Obsolete] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning.
1876+
#else
1877+
void* _UnusedPadding; // Unused field to keep data structure the same size.
1878+
#endif
18731879

18741880
//------------------------------------------------------------------
18751881
// Input - Fill before calling NewFrame()
@@ -2809,13 +2815,26 @@ struct ImGuiViewport
28092815
ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos)
28102816
ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size)
28112817

2818+
// Platform/Backend Dependent Data
2819+
void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms)
2820+
28122821
ImGuiViewport() { memset(this, 0, sizeof(*this)); }
28132822

28142823
// Helpers
28152824
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
28162825
ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); }
28172826
};
28182827

2828+
//-----------------------------------------------------------------------------
2829+
// [SECTION] Platform Dependent Interfaces
2830+
//-----------------------------------------------------------------------------
2831+
2832+
// (Optional) Support for IME (Input Method Editor) via the io.SetPlatformImeDataFn() function.
2833+
struct ImGuiPlatformImeData
2834+
{
2835+
ImVec2 InputPos; // Position of the input cursor
2836+
};
2837+
28192838
//-----------------------------------------------------------------------------
28202839
// [SECTION] Obsolete functions and types
28212840
// (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details)

0 commit comments

Comments
 (0)