Fix: macOS wrong IME candidate window position on first display

IME conversion candidate window was displayed at the mouse position, instead of
below the cursor or text selection.

Blender need to tell the input method program where the conversion candidate
window is during Japanese and Chinese input.

In macOS, the `firstRectforCharacterRange` is called when input by the input
method starts, and the position of the conversion candidate window is
specified. Therefore, it is necessary to set the position of the conversion
candidate window before input starts. This patch changes it so that the position
of the conversion candidate window is always set when the cursor is drawn.

Differential Revision: https://developer.blender.org/D11697
This commit is contained in:
Yuki Hashimoto 2021-07-05 16:46:04 +02:00 committed by Brecht Van Lommel
parent 673c254c7d
commit ac1ed19eae
1 changed files with 38 additions and 11 deletions

View File

@ -2030,8 +2030,11 @@ static void widget_draw_text(const uiFontStyle *fstyle,
/* text button selection, cursor, composite underline */
if (but->editstr && but->pos != -1) {
int but_pos_ofs;
/* Shape of the cursor for drawing. */
rcti but_cursor_shape;
#ifdef WITH_INPUT_IME
bool ime_reposition_window = false;
int ime_win_x, ime_win_y;
#endif
/* text button selection */
if ((but->selend - but->selsta) > 0) {
@ -2056,14 +2059,28 @@ static void widget_draw_text(const uiFontStyle *fstyle,
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
rcti selection_shape;
selection_shape.xmin = rect->xmin + selsta_draw;
selection_shape.xmax = min_ii(rect->xmin + selwidth_draw, rect->xmax - 2);
selection_shape.ymin = rect->ymin + U.pixelsize;
selection_shape.ymax = rect->ymax - U.pixelsize;
immUniformColor4ubv(wcol->item);
immRecti(pos,
rect->xmin + selsta_draw,
rect->ymin + U.pixelsize,
min_ii(rect->xmin + selwidth_draw, rect->xmax - 2),
rect->ymax - U.pixelsize);
selection_shape.xmin,
selection_shape.ymin,
selection_shape.xmax,
selection_shape.ymax);
immUnbindProgram();
#ifdef WITH_INPUT_IME
/* IME candidate window uses selection position. */
if (!ime_reposition_window) {
ime_reposition_window = true;
ime_win_x = selection_shape.xmin;
ime_win_y = selection_shape.ymin;
}
#endif
}
}
@ -2096,6 +2113,8 @@ static void widget_draw_text(const uiFontStyle *fstyle,
immUniformThemeColor(TH_WIDGET_TEXT_CURSOR);
/* Shape of the cursor for drawing. */
rcti but_cursor_shape;
but_cursor_shape.xmin = (rect->xmin + t) - U.pixelsize;
but_cursor_shape.ymin = rect->ymin + U.pixelsize;
but_cursor_shape.xmax = (rect->xmin + t) + U.pixelsize;
@ -2109,15 +2128,23 @@ static void widget_draw_text(const uiFontStyle *fstyle,
but_cursor_shape.ymax);
immUnbindProgram();
#ifdef WITH_INPUT_IME
/* IME candidate window uses cursor position. */
if (!ime_reposition_window) {
ime_reposition_window = true;
ime_win_x = but_cursor_shape.xmax + 5;
ime_win_y = but_cursor_shape.ymin + 3;
}
#endif
}
#ifdef WITH_INPUT_IME
/* ime cursor following */
if (ime_reposition_window) {
ui_but_ime_reposition(but, ime_win_x, ime_win_y, false);
}
if (ime_data && ime_data->composite_len) {
/* ime cursor following */
if (but->pos >= but->ofs) {
ui_but_ime_reposition(but, but_cursor_shape.xmax + 5, but_cursor_shape.ymin + 3, false);
}
/* composite underline */
widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr);
}