mirror of
https://github.com/glfw/glfw.git
synced 2024-11-29 15:44: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}
|
### 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.
|
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 {#input_mouse}
|
||||||
|
|
||||||
Mouse input comes in many forms, including mouse motion, button presses and
|
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
|
the `VK_KHR_xlib_surface` extension. Possible values are `GLFW_TRUE` and
|
||||||
`GLFW_FALSE`. This is ignored on other platforms.
|
`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}
|
#### 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_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_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_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}
|
### 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] focused_block Focused block index.
|
||||||
* @param[in] caret Caret position.
|
* @param[in] caret Caret position.
|
||||||
*
|
*
|
||||||
* @sa @ref preedit
|
* @sa @ref ime_support
|
||||||
* @sa glfwSetPreeditCallback
|
* @sa glfwSetPreeditCallback
|
||||||
*
|
*
|
||||||
* @ingroup input
|
* @ingroup input
|
||||||
@ -1982,7 +1982,7 @@ typedef void (* GLFWpreeditfun)(GLFWwindow* window,
|
|||||||
*
|
*
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
*
|
*
|
||||||
* @sa @ref preedit
|
* @sa @ref ime_support
|
||||||
* @sa glfwSetIMEStatusCallback
|
* @sa glfwSetIMEStatusCallback
|
||||||
*
|
*
|
||||||
* @ingroup monitor
|
* @ingroup monitor
|
||||||
@ -5218,7 +5218,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
|||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* This function may only be called from the main thread.
|
* This function may only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref input_char
|
* @sa @ref ime_support
|
||||||
*
|
*
|
||||||
* @since Added in GLFW 3.X.
|
* @since Added in GLFW 3.X.
|
||||||
*
|
*
|
||||||
@ -5240,7 +5240,7 @@ GLFWAPI void glfwGetPreeditCursorRectangle(GLFWwindow* window, int* x, int* y, i
|
|||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* This function may only be called from the main thread.
|
* This function may only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref input_char
|
* @sa @ref ime_support
|
||||||
*
|
*
|
||||||
* @since Added in GLFW 3.X.
|
* @since Added in GLFW 3.X.
|
||||||
*
|
*
|
||||||
@ -5262,7 +5262,7 @@ GLFWAPI void glfwSetPreeditCursorRectangle(GLFWwindow* window, int x, int y, int
|
|||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* This function may only be called from the main thread.
|
* This function may only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref preedit
|
* @sa @ref ime_support
|
||||||
*
|
*
|
||||||
* @since Added in GLFW 3.X.
|
* @since Added in GLFW 3.X.
|
||||||
*
|
*
|
||||||
@ -5439,7 +5439,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
|
|||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* This function may only be called from the main thread.
|
* This function may only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref input_char
|
* @sa @ref ime_support
|
||||||
*
|
*
|
||||||
* @since Added in GLFW 3.X
|
* @since Added in GLFW 3.X
|
||||||
*
|
*
|
||||||
@ -5470,7 +5470,7 @@ GLFWAPI GLFWpreeditfun glfwSetPreeditCallback(GLFWwindow* window, GLFWpreeditfun
|
|||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* This function may only be called from the main thread.
|
* This function may only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref input_char
|
* @sa @ref ime_support
|
||||||
*
|
*
|
||||||
* @since Added in GLFW 3.X
|
* @since Added in GLFW 3.X
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user