diff options
| author | Po Lu | 2022-01-09 19:46:14 +0800 |
|---|---|---|
| committer | Po Lu | 2022-01-09 19:46:14 +0800 |
| commit | d5499e3eb2765ddf212e3f21fed7b356b8f0ec76 (patch) | |
| tree | 9682a607892cc56967ab38d17ba7fa4bcdc90e4f /src | |
| parent | 3dfefb8bb4d99ea67b576bf177804dd386159874 (diff) | |
| download | emacs-d5499e3eb2765ddf212e3f21fed7b356b8f0ec76.tar.gz emacs-d5499e3eb2765ddf212e3f21fed7b356b8f0ec76.zip | |
Display caret in preedit text where the input method asked
* src/xfns.c (xic_preedit_start_callback): Clear caret position.
(xic_preedit_caret_callback): Record new caret position and
announce it.
(xic_preedit_done_callback): Clear caret position.
(xic_preedit_draw_callback): Set caret position appropriately.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/xfns.c b/src/xfns.c index 073200ff75a..0254b3d0b16 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -2922,6 +2922,7 @@ xic_preedit_start_callback (XIC xic, XPointer client_data, | |||
| 2922 | 2922 | ||
| 2923 | output->preedit_size = 0; | 2923 | output->preedit_size = 0; |
| 2924 | output->preedit_active = true; | 2924 | output->preedit_active = true; |
| 2925 | output->preedit_caret = 0; | ||
| 2925 | 2926 | ||
| 2926 | if (output->preedit_chars) | 2927 | if (output->preedit_chars) |
| 2927 | xfree (output->preedit_chars); | 2928 | xfree (output->preedit_chars); |
| @@ -2936,7 +2937,54 @@ static void | |||
| 2936 | xic_preedit_caret_callback (XIC xic, XPointer client_data, | 2937 | xic_preedit_caret_callback (XIC xic, XPointer client_data, |
| 2937 | XIMPreeditCaretCallbackStruct *call_data) | 2938 | XIMPreeditCaretCallbackStruct *call_data) |
| 2938 | { | 2939 | { |
| 2940 | struct frame *f = x_xic_to_frame (xic); | ||
| 2941 | struct x_output *output; | ||
| 2942 | struct input_event ie; | ||
| 2943 | EVENT_INIT (ie); | ||
| 2944 | |||
| 2945 | if (f) | ||
| 2946 | { | ||
| 2947 | output = FRAME_X_OUTPUT (f); | ||
| 2948 | |||
| 2949 | if (!output->preedit_active) | ||
| 2950 | return; | ||
| 2951 | |||
| 2952 | switch (call_data->direction) | ||
| 2953 | { | ||
| 2954 | case XIMAbsolutePosition: | ||
| 2955 | output->preedit_caret = call_data->position; | ||
| 2956 | break; | ||
| 2957 | case XIMForwardChar: | ||
| 2958 | case XIMForwardWord: | ||
| 2959 | call_data->position = output->preedit_caret++; | ||
| 2960 | break; | ||
| 2961 | case XIMBackwardChar: | ||
| 2962 | case XIMBackwardWord: | ||
| 2963 | call_data->position = max (0, output->preedit_caret--); | ||
| 2964 | break; | ||
| 2965 | default: | ||
| 2966 | call_data->position = output->preedit_caret; | ||
| 2967 | } | ||
| 2968 | |||
| 2969 | if (output->preedit_chars) | ||
| 2970 | { | ||
| 2971 | ie.kind = PREEDIT_TEXT_EVENT; | ||
| 2972 | XSETFRAME (ie.frame_or_window, f); | ||
| 2973 | ie.arg = make_string_from_utf8 (output->preedit_chars, | ||
| 2974 | output->preedit_size); | ||
| 2975 | |||
| 2976 | Fput_text_property (make_fixnum (0), | ||
| 2977 | make_fixnum (SCHARS (ie.arg)), | ||
| 2978 | Qcursor, | ||
| 2979 | make_fixnum (output->preedit_caret), | ||
| 2980 | ie.arg); | ||
| 2939 | 2981 | ||
| 2982 | XSETINT (ie.x, 0); | ||
| 2983 | XSETINT (ie.y, 0); | ||
| 2984 | |||
| 2985 | kbd_buffer_store_event (&ie); | ||
| 2986 | } | ||
| 2987 | } | ||
| 2940 | } | 2988 | } |
| 2941 | 2989 | ||
| 2942 | 2990 | ||
| @@ -2966,6 +3014,7 @@ xic_preedit_done_callback (XIC xic, XPointer client_data, | |||
| 2966 | output->preedit_size = 0; | 3014 | output->preedit_size = 0; |
| 2967 | output->preedit_active = false; | 3015 | output->preedit_active = false; |
| 2968 | output->preedit_chars = NULL; | 3016 | output->preedit_chars = NULL; |
| 3017 | output->preedit_caret = 0; | ||
| 2969 | } | 3018 | } |
| 2970 | } | 3019 | } |
| 2971 | 3020 | ||
| @@ -3137,6 +3186,8 @@ xic_preedit_draw_callback (XIC xic, XPointer client_data, | |||
| 3137 | if (text) | 3186 | if (text) |
| 3138 | xfree (text); | 3187 | xfree (text); |
| 3139 | 3188 | ||
| 3189 | output->preedit_caret = call_data->caret; | ||
| 3190 | |||
| 3140 | /* This is okay because this callback is called from the big XIM | 3191 | /* This is okay because this callback is called from the big XIM |
| 3141 | event filter, which runs inside XTread_socket. */ | 3192 | event filter, which runs inside XTread_socket. */ |
| 3142 | 3193 | ||
| @@ -3144,6 +3195,13 @@ xic_preedit_draw_callback (XIC xic, XPointer client_data, | |||
| 3144 | XSETFRAME (ie.frame_or_window, f); | 3195 | XSETFRAME (ie.frame_or_window, f); |
| 3145 | ie.arg = make_string_from_utf8 (output->preedit_chars, | 3196 | ie.arg = make_string_from_utf8 (output->preedit_chars, |
| 3146 | output->preedit_size); | 3197 | output->preedit_size); |
| 3198 | |||
| 3199 | Fput_text_property (make_fixnum (0), | ||
| 3200 | make_fixnum (SCHARS (ie.arg)), | ||
| 3201 | Qcursor, | ||
| 3202 | make_fixnum (output->preedit_caret), | ||
| 3203 | ie.arg); | ||
| 3204 | |||
| 3147 | XSETINT (ie.x, 0); | 3205 | XSETINT (ie.x, 0); |
| 3148 | XSETINT (ie.y, 0); | 3206 | XSETINT (ie.y, 0); |
| 3149 | 3207 | ||
| @@ -3160,6 +3218,7 @@ xic_preedit_draw_callback (XIC xic, XPointer client_data, | |||
| 3160 | output->preedit_chars = NULL; | 3218 | output->preedit_chars = NULL; |
| 3161 | output->preedit_size = 0; | 3219 | output->preedit_size = 0; |
| 3162 | output->preedit_active = false; | 3220 | output->preedit_active = false; |
| 3221 | output->preedit_caret = 0; | ||
| 3163 | } | 3222 | } |
| 3164 | 3223 | ||
| 3165 | void | 3224 | void |