mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Doc: Improve document about IME features
This commit is contained in:
parent
d5795ba0a5
commit
1ba8267f20
258
docs/input.md
258
docs/input.md
@ -229,96 +229,6 @@ void character_callback(GLFWwindow* window, unsigned int codepoint)
|
||||
}
|
||||
```
|
||||
|
||||
@subsection preedit IME Support
|
||||
|
||||
All desktop operating systems support IME (Input Method Editor) to input characters
|
||||
that are not mapped with physical keys. IME have been popular among Eeastern Asian people.
|
||||
And some operating systems start supporting voice input via IME mechanism.
|
||||
|
||||
GLFW provides IME support functions to help
|
||||
you implement better text input features. You should add suitable visualization code for
|
||||
preedit text.
|
||||
|
||||
IME works in front of actual character input events (@ref input_char).
|
||||
If your application uses text input and you want to support IME,
|
||||
you should register preedit callback to receive preedit text before committed.
|
||||
|
||||
@code
|
||||
glfwSetPreeditCallback(window, preedit_callback);
|
||||
@endcode
|
||||
|
||||
The callback function receives chunk of text and focused block information.
|
||||
|
||||
@code
|
||||
static void preedit_callback(GLFWwindow* window, int strLength, unsigned int* string, int blockLength, int* blocks, int focusedBlock) {
|
||||
}
|
||||
@endcode
|
||||
|
||||
strLength and string parameter reprsent whole preedit text. Each character of the preedit string is a codepoint like @ref input_char.
|
||||
|
||||
If you want to type the text "寿司(sushi)", Usually the callback is called several times like the following sequence:
|
||||
|
||||
-# key event: s
|
||||
-# preedit: [string: "s", block: [1], focusedBlock: 0]
|
||||
-# key event: u
|
||||
-# preedit: [string: "す", block: [1], focusedBlock: 0]
|
||||
-# key event: s
|
||||
-# preedit: [string: "すs", block: [2], focusedBlock: 0]
|
||||
-# key event: h
|
||||
-# preedit: [string: "すsh", block: [2], focusedBlock: 0]
|
||||
-# key event: i
|
||||
-# preedit: [string: "すし", block: [2], focusedBlock: 0]
|
||||
-# key event: ' '
|
||||
-# preedit: [string: "寿司", block: [2], focusedBlock: 0]
|
||||
-# char: '寿'
|
||||
-# char: '司'
|
||||
-# preedit: [string: "", block: [], focusedBlock: 0]
|
||||
|
||||
If preedit text includes several semantic blocks, preedit callbacks returns several blocks after a space key pressed:
|
||||
|
||||
-# preedit: [string: "わたしはすしをたべます", block: [11], focusedBlock: 0]
|
||||
-# preedit: [string: "私は寿司を食べます", block: [2, 7], focusedBlock: 1]
|
||||
|
||||
"blocks" is a list of block length. The above case, it contains the following blocks and second block is focused.
|
||||
|
||||
- 私は
|
||||
- [寿司を食べます]
|
||||
|
||||
commited text(passed via regular @ref input_char event), unfocused block, focused block should have different text style.
|
||||
|
||||
|
||||
GLFW provides helper function to teach suitable position of the candidate window to window system.
|
||||
Window system decides the best position from text cursor geometry (x, y coords and height). You should call this function
|
||||
in the above preedit text callback function.
|
||||
|
||||
@code
|
||||
glfwSetPreeditCursorPos(window, x, y, h);
|
||||
glfwGetPreeditCursorPos(window, &x, &y, &h);
|
||||
@endcode
|
||||
|
||||
Sometimes IME task is interrupted by user or application. There are several functions to support these situation.
|
||||
You can receive notification about IME status change(on/off) by using the following function:
|
||||
|
||||
@code
|
||||
glfwSetIMEStatusCallback(window, imestatus_callback);
|
||||
@endcode
|
||||
|
||||
imestatus_callback has simple sigunature like this:
|
||||
|
||||
@code
|
||||
static void imestatus_callback(GLFWwindow* window) {
|
||||
}
|
||||
@endcode
|
||||
|
||||
You can implement the code that resets or commits preedit text when IME status is changed and preedit text is not empty.
|
||||
|
||||
When the focus is gone from text box, you can use the following functions to reset IME status:
|
||||
|
||||
@code
|
||||
void glfwResetPreeditText(GLFWwindow* window);
|
||||
void glfwSetIMEStatus(GLFWwindow* window, int active)
|
||||
int glfwGetIMEStatus(GLFWwindow* window)
|
||||
@endcode
|
||||
|
||||
### Key names {#input_key_name}
|
||||
|
||||
@ -336,6 +246,174 @@ ignored. This matches the behavior of the key callback, meaning the callback
|
||||
arguments can always be passed unmodified to this function.
|
||||
|
||||
|
||||
@section ime_support IME support
|
||||
|
||||
IME (Input Method Editor/Engine) is used to input characters not mapped with
|
||||
physical keys. It is popular among East Asian people.
|
||||
|
||||
|
||||
@subsection ime_style IME styles
|
||||
|
||||
GLFW supports the following two styles of IME.
|
||||
|
||||
- On-the-spot
|
||||
- Over-the-spot
|
||||
|
||||
On-the-spot style is supported on Windows, macOS and Wayland. On these platforms,
|
||||
applications need to draw preedit text directly in their UI by using the preedit
|
||||
callback (See [Preedit input](@ref input_preedit)).
|
||||
|
||||
Over-the-spot style is supported on X11. On this platform, the IME displays preedit
|
||||
text, and applications don't need to draw it. So the preedit callback doesn't work
|
||||
on X11.
|
||||
|
||||
In both styles, applications should manage the position of the candidate window.
|
||||
See [Candidate window](@ref candidate_window) for details.
|
||||
|
||||
@note
|
||||
@x11 You can use on-the-spot style also on X11 by using @ref GLFW_X11_ONTHESPOT_hint.
|
||||
In this case, the preedit callback also works on X11. However, on-the-spot style on
|
||||
X11 is unstable, so it is not recommended.
|
||||
|
||||
|
||||
@subsection input_preedit Preedit input
|
||||
|
||||
When inputting text with IME, the text is temporarily inputted, then conversion
|
||||
and other processing are performed and finally committed. The committed text is
|
||||
inputted in the same way as input without IME (See [Text input](@ref input_char)).
|
||||
|
||||
This temporary input is called "preedit" or "pre-edit".
|
||||
|
||||
On Windows, macOS and Wayland, that use on-the-spot sytle, applications need to
|
||||
take preedit information and draw it in their UI.
|
||||
|
||||
You can register the preedit callback as follows.
|
||||
|
||||
@code
|
||||
glfwSetPreeditCallback(window, preedit_callback);
|
||||
@endcode
|
||||
|
||||
The callback receives the following information.
|
||||
|
||||
@code
|
||||
void preedit_callback(GLFWwindow* window,
|
||||
int preedit_count,
|
||||
unsigned int* preedit_string,
|
||||
int block_count,
|
||||
int* block_sizes,
|
||||
int focused_block,
|
||||
int caret)
|
||||
{
|
||||
}
|
||||
@endcode
|
||||
|
||||
"preedit_count" and "preedit_string" parameter represent the whole preedit text.
|
||||
Each character of the preedit string is a native endian UTF-32 like @ref input_char.
|
||||
|
||||
If you want to type the text "寿司(sushi)", Usually the callback is called several
|
||||
times like the following sequence:
|
||||
|
||||
-# key event: s
|
||||
-# preedit: [preedit_string: "s", block_sizes: [1], focused_block: 0]
|
||||
-# key event: u
|
||||
-# preedit: [preedit_string: "す", block_sizes: [1], focused_block: 0]
|
||||
-# key event: s
|
||||
-# preedit: [preedit_string: "すs", block_sizes: [2], focused_block: 0]
|
||||
-# key event: h
|
||||
-# preedit: [preedit_string: "すsh", block_sizes: [3], focused_block: 0]
|
||||
-# key event: i
|
||||
-# preedit: [preedit_string: "すし", block_sizes: [2], focused_block: 0]
|
||||
-# key event: ' '
|
||||
-# preedit: [preedit_string: "寿司", block_sizes: [2], focused_block: 0]
|
||||
-# char: '寿'
|
||||
-# char: '司'
|
||||
-# preedit: [preedit_string: "", block_sizes: [], focused_block: 0]
|
||||
|
||||
If preedit text includes several semantic blocks, the callback returns several blocks:
|
||||
|
||||
-# preedit: [preedit_string: "わたしはすしをたべます", block_sizes: [11], focused_block: 0]
|
||||
-# preedit: [preedit_string: "私は寿司を食べます", block_sizes: [2, 7], focused_block: 1]
|
||||
|
||||
"block_sizes" is a list of the sizes of each block. The above case, it contains the following
|
||||
blocks and the second block is focused.
|
||||
|
||||
- 私は
|
||||
- [寿司を食べます]
|
||||
|
||||
The application side should draw a focused block and unfocused blocks
|
||||
in different styles.
|
||||
|
||||
You can use the "caret" parameter to draw the caret of the preedit text.
|
||||
The specification of this parameter depends on the specification of the input method.
|
||||
The following is an example on Win32.
|
||||
|
||||
- "あいうえお|" (caret: 5)
|
||||
- key event: arrow-left
|
||||
- "あいうえ|お" (caret: 4)
|
||||
- ...
|
||||
- "|あいうえお" (caret: 0)
|
||||
|
||||
|
||||
@subsection candidate_window Candidate window
|
||||
|
||||
The application has to manage the position of the candidate window that shows
|
||||
the preedit candidate list. To do this, the application has to manage the area
|
||||
of the preedit text cursor by the following functions. The IME displays the
|
||||
candidate window in the appropriate position based on the area of the preedit
|
||||
text cursor.
|
||||
|
||||
@code
|
||||
glfwSetPreeditCursorRectangle(window, x, y, w, h);
|
||||
glfwGetPreeditCursorRectangle(window, &x, &y, &w, &h);
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection ime_status IME status
|
||||
|
||||
Sometimes, IME task needs to be interrupted by a user or an application. There
|
||||
are several functions to support these situations.
|
||||
|
||||
@note
|
||||
@x11 @wayland This feature is not supported.
|
||||
|
||||
You can receive notification about IME status change(on/off) by using the following
|
||||
function:
|
||||
|
||||
@code
|
||||
glfwSetIMEStatusCallback(window, imestatus_callback);
|
||||
@endcode
|
||||
|
||||
The callback has a simple signature like this:
|
||||
|
||||
@code
|
||||
void imestatus_callback(GLFWwindow* window)
|
||||
{
|
||||
}
|
||||
@endcode
|
||||
|
||||
@anchor GLFW_IME
|
||||
You can get the current IME status by the following function:
|
||||
|
||||
@code
|
||||
glfwGetInputMode(window, GLFW_IME);
|
||||
@endcode
|
||||
|
||||
If you get GLFW_TRUE, it means the IME is on, and GLFW_FALSE means the IME is off.
|
||||
|
||||
You can also change the IME status by the following function:
|
||||
|
||||
@code
|
||||
glfwSetInputMode(window, GLFW_IME, GLFW_TRUE);
|
||||
glfwSetInputMode(window, GLFW_IME, GLFW_FALSE);
|
||||
@endcode
|
||||
|
||||
You can use the following function to clear the current preedit.
|
||||
|
||||
@code
|
||||
glfwResetPreeditText(window);
|
||||
@endcode
|
||||
|
||||
|
||||
## Mouse input {#input_mouse}
|
||||
|
||||
Mouse input comes in many forms, including mouse motion, button presses and
|
||||
|
@ -152,6 +152,15 @@ __GLFW_X11_XCB_VULKAN_SURFACE__ specifies whether to prefer the
|
||||
the `VK_KHR_xlib_surface` extension. Possible values are `GLFW_TRUE` and
|
||||
`GLFW_FALSE`. This is ignored on other platforms.
|
||||
|
||||
@anchor GLFW_X11_ONTHESPOT_hint
|
||||
__GLFW_X11_ONTHESPOT__ specifies whether to use on-the-spot input method style.
|
||||
On X11 platform, over-the-spot style is used if this hint is `GLFW_FALSE`,
|
||||
which is the default value. You can set `GLFW_TRUE` to use on-the-spot style
|
||||
as with other platforms. However, on-the-spot style on X11 is unstable, so
|
||||
it is recommended not to use this hint in normal cases. Possible values are
|
||||
`GLFW_TRUE` and `GLFW_FALSE`. This is ignored on other platforms. Please see
|
||||
@ref ime_support for more information about IME support.
|
||||
|
||||
|
||||
#### Supported and default values {#init_hints_values}
|
||||
|
||||
@ -164,6 +173,7 @@ Initialization hint | Default value | Supported v
|
||||
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
@ref GLFW_WAYLAND_LIBDECOR | `GLFW_WAYLAND_PREFER_LIBDECOR` | `GLFW_WAYLAND_PREFER_LIBDECOR` or `GLFW_WAYLAND_DISABLE_LIBDECOR`
|
||||
@ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
@ref GLFW_X11_ONTHESPOT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
|
||||
|
||||
### Runtime platform selection {#platform}
|
||||
|
@ -1963,7 +1963,7 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int
|
||||
* @param[in] focused_block Focused block index.
|
||||
* @param[in] caret Caret position.
|
||||
*
|
||||
* @sa @ref preedit
|
||||
* @sa @ref ime_support
|
||||
* @sa glfwSetPreeditCallback
|
||||
*
|
||||
* @ingroup input
|
||||
@ -1982,7 +1982,7 @@ typedef void (* GLFWpreeditfun)(GLFWwindow* window,
|
||||
*
|
||||
* @param[in] window The window that received the event.
|
||||
*
|
||||
* @sa @ref preedit
|
||||
* @sa @ref ime_support
|
||||
* @sa glfwSetIMEStatusCallback
|
||||
*
|
||||
* @ingroup monitor
|
||||
@ -5218,7 +5218,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
||||
* @par Thread Safety
|
||||
* This function may only be called from the main thread.
|
||||
*
|
||||
* @sa @ref input_char
|
||||
* @sa @ref ime_support
|
||||
*
|
||||
* @since Added in GLFW 3.X.
|
||||
*
|
||||
@ -5240,7 +5240,7 @@ GLFWAPI void glfwGetPreeditCursorRectangle(GLFWwindow* window, int* x, int* y, i
|
||||
* @par Thread Safety
|
||||
* This function may only be called from the main thread.
|
||||
*
|
||||
* @sa @ref input_char
|
||||
* @sa @ref ime_support
|
||||
*
|
||||
* @since Added in GLFW 3.X.
|
||||
*
|
||||
@ -5262,7 +5262,7 @@ GLFWAPI void glfwSetPreeditCursorRectangle(GLFWwindow* window, int x, int y, int
|
||||
* @par Thread Safety
|
||||
* This function may only be called from the main thread.
|
||||
*
|
||||
* @sa @ref preedit
|
||||
* @sa @ref ime_support
|
||||
*
|
||||
* @since Added in GLFW 3.X.
|
||||
*
|
||||
@ -5439,7 +5439,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
|
||||
* @par Thread Safety
|
||||
* This function may only be called from the main thread.
|
||||
*
|
||||
* @sa @ref input_char
|
||||
* @sa @ref ime_support
|
||||
*
|
||||
* @since Added in GLFW 3.X
|
||||
*
|
||||
@ -5470,7 +5470,7 @@ GLFWAPI GLFWpreeditfun glfwSetPreeditCallback(GLFWwindow* window, GLFWpreeditfun
|
||||
* @par Thread Safety
|
||||
* This function may only be called from the main thread.
|
||||
*
|
||||
* @sa @ref input_char
|
||||
* @sa @ref ime_support
|
||||
*
|
||||
* @since Added in GLFW 3.X
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user