Mercurial > vim
comparison src/mbyte.c @ 12924:85a601f985ab v8.0.1338
patch 8.0.1338: USE_IM_CONTROL is confusing and incomplete
commit https://github.com/vim/vim/commit/819edbe078c8579f3620d12dac830f12ccdc5a45
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Nov 25 17:14:33 2017 +0100
patch 8.0.1338: USE_IM_CONTROL is confusing and incomplete
Problem: USE_IM_CONTROL is confusing and incomplete.
Solution: Just use FEAT_MBYTE. Call 'imactivatefunc' also without GUI.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 25 Nov 2017 17:15:05 +0100 |
parents | 6bafba651e20 |
children | 75ffa8ee989c |
comparison
equal
deleted
inserted
replaced
12923:abe981c46a62 | 12924:85a601f985ab |
---|---|
4792 argv[0] = (char_u *)"1"; | 4792 argv[0] = (char_u *)"1"; |
4793 else | 4793 else |
4794 argv[0] = (char_u *)"0"; | 4794 argv[0] = (char_u *)"0"; |
4795 (void)call_func_retnr(p_imaf, 1, argv, FALSE); | 4795 (void)call_func_retnr(p_imaf, 1, argv, FALSE); |
4796 } | 4796 } |
4797 | |
4798 static int | |
4799 call_imstatusfunc(void) | |
4800 { | |
4801 int is_active; | |
4802 | |
4803 /* FIXME: Don't execute user function in unsafe situation. */ | |
4804 if (exiting | |
4805 # ifdef FEAT_AUTOCMD | |
4806 || is_autocmd_blocked() | |
4807 # endif | |
4808 ) | |
4809 return FALSE; | |
4810 /* FIXME: :py print 'xxx' is shown duplicate result. | |
4811 * Use silent to avoid it. */ | |
4812 ++msg_silent; | |
4813 is_active = call_func_retnr(p_imsf, 0, NULL, FALSE); | |
4814 --msg_silent; | |
4815 return (is_active > 0); | |
4816 } | |
4797 #endif | 4817 #endif |
4798 | 4818 |
4799 #if defined(FEAT_XIM) || defined(PROTO) | 4819 #if defined(FEAT_XIM) || defined(PROTO) |
4800 | 4820 |
4801 # if defined(FEAT_GUI_GTK) || defined(PROTO) | 4821 # if defined(FEAT_GUI_GTK) || defined(PROTO) |
4836 | 4856 |
4837 was_active = !!im_get_status(); | 4857 was_active = !!im_get_status(); |
4838 im_is_active = (active && !p_imdisable); | 4858 im_is_active = (active && !p_imdisable); |
4839 | 4859 |
4840 if (im_is_active != was_active) | 4860 if (im_is_active != was_active) |
4841 { | 4861 xim_reset(); |
4842 #ifdef FEAT_EVAL | |
4843 if (p_imaf[0] != NUL) | |
4844 call_imactivatefunc(im_is_active); | |
4845 else | |
4846 #endif | |
4847 xim_reset(); | |
4848 } | |
4849 } | 4862 } |
4850 | 4863 |
4851 void | 4864 void |
4852 xim_set_focus(int focus) | 4865 xim_set_focus(int focus) |
4853 { | 4866 { |
5673 } | 5686 } |
5674 | 5687 |
5675 void | 5688 void |
5676 xim_reset(void) | 5689 xim_reset(void) |
5677 { | 5690 { |
5691 #ifdef FEAT_EVAL | |
5692 if (p_imaf[0] != NUL) | |
5693 call_imactivatefunc(im_is_active); | |
5694 else | |
5695 #endif | |
5678 if (xic != NULL) | 5696 if (xic != NULL) |
5679 { | 5697 { |
5680 gtk_im_context_reset(xic); | 5698 gtk_im_context_reset(xic); |
5681 | 5699 |
5682 if (p_imdisable) | 5700 if (p_imdisable) |
5683 im_shutdown(); | 5701 im_shutdown(); |
5684 else | 5702 else |
5685 { | 5703 { |
5686 xim_set_focus(gui.in_focus); | 5704 xim_set_focus(gui.in_focus); |
5687 | 5705 |
5688 # ifdef FEAT_EVAL | 5706 if (im_activatekey_keyval != GDK_VoidSymbol) |
5689 if (p_imaf[0] != NUL) | |
5690 call_imactivatefunc(im_is_active); | |
5691 else | |
5692 # endif | |
5693 if (im_activatekey_keyval != GDK_VoidSymbol) | |
5694 { | 5707 { |
5695 if (im_is_active) | 5708 if (im_is_active) |
5696 { | 5709 { |
5697 g_signal_handler_block(xic, im_commit_handler_id); | 5710 g_signal_handler_block(xic, im_commit_handler_id); |
5698 im_synthesize_keypress(im_activatekey_keyval, | 5711 im_synthesize_keypress(im_activatekey_keyval, |
5854 int | 5867 int |
5855 im_get_status(void) | 5868 im_get_status(void) |
5856 { | 5869 { |
5857 # ifdef FEAT_EVAL | 5870 # ifdef FEAT_EVAL |
5858 if (p_imsf[0] != NUL) | 5871 if (p_imsf[0] != NUL) |
5859 { | 5872 return call_imstatusfunc(); |
5860 int is_active; | |
5861 | |
5862 /* FIXME: Don't execute user function in unsafe situation. */ | |
5863 if (exiting | |
5864 # ifdef FEAT_AUTOCMD | |
5865 || is_autocmd_blocked() | |
5866 # endif | |
5867 ) | |
5868 return FALSE; | |
5869 /* FIXME: :py print 'xxx' is shown duplicate result. | |
5870 * Use silent to avoid it. */ | |
5871 ++msg_silent; | |
5872 is_active = call_func_retnr(p_imsf, 0, NULL, FALSE); | |
5873 --msg_silent; | |
5874 return (is_active > 0); | |
5875 } | |
5876 # endif | 5873 # endif |
5877 return im_is_active; | 5874 return im_is_active; |
5878 } | 5875 } |
5879 | 5876 |
5880 int | 5877 int |
5892 # else /* !FEAT_GUI_GTK */ | 5889 # else /* !FEAT_GUI_GTK */ |
5893 | 5890 |
5894 static int xim_is_active = FALSE; /* XIM should be active in the current | 5891 static int xim_is_active = FALSE; /* XIM should be active in the current |
5895 mode */ | 5892 mode */ |
5896 static int xim_has_focus = FALSE; /* XIM is really being used for Vim */ | 5893 static int xim_has_focus = FALSE; /* XIM is really being used for Vim */ |
5897 #ifdef FEAT_GUI_X11 | 5894 # ifdef FEAT_GUI_X11 |
5898 static XIMStyle input_style; | 5895 static XIMStyle input_style; |
5899 static int status_area_enabled = TRUE; | 5896 static int status_area_enabled = TRUE; |
5900 #endif | 5897 # endif |
5901 | 5898 |
5902 /* | 5899 /* |
5903 * Switch using XIM on/off. This is used by the code that changes "State". | 5900 * Switch using XIM on/off. This is used by the code that changes "State". |
5901 * When 'imactivatefunc' is defined use that function instead. | |
5904 */ | 5902 */ |
5905 void | 5903 void |
5906 im_set_active(int active) | 5904 im_set_active(int active_arg) |
5907 { | 5905 { |
5908 if (xic == NULL) | 5906 int active = active_arg; |
5909 return; | |
5910 | 5907 |
5911 /* If 'imdisable' is set, XIM is never active. */ | 5908 /* If 'imdisable' is set, XIM is never active. */ |
5912 if (p_imdisable) | 5909 if (p_imdisable) |
5913 active = FALSE; | 5910 active = FALSE; |
5914 #if !defined(FEAT_GUI_GTK) | 5911 # if !defined(FEAT_GUI_GTK) |
5915 else if (input_style & XIMPreeditPosition) | 5912 else if (input_style & XIMPreeditPosition) |
5916 /* There is a problem in switching XIM off when preediting is used, | 5913 /* There is a problem in switching XIM off when preediting is used, |
5917 * and it is not clear how this can be solved. For now, keep XIM on | 5914 * and it is not clear how this can be solved. For now, keep XIM on |
5918 * all the time, like it was done in Vim 5.8. */ | 5915 * all the time, like it was done in Vim 5.8. */ |
5919 active = TRUE; | 5916 active = TRUE; |
5920 #endif | 5917 # endif |
5918 | |
5919 # if defined(FEAT_EVAL) | |
5920 if (p_imaf[0] != NUL) | |
5921 { | |
5922 if (active != im_get_status()) | |
5923 { | |
5924 call_imactivatefunc(active); | |
5925 im_is_active = active; | |
5926 } | |
5927 return; | |
5928 } | |
5929 # endif | |
5930 | |
5931 if (xic == NULL) | |
5932 return; | |
5921 | 5933 |
5922 /* Remember the active state, it is needed when Vim gets keyboard focus. */ | 5934 /* Remember the active state, it is needed when Vim gets keyboard focus. */ |
5923 xim_is_active = active; | 5935 xim_is_active = active; |
5924 xim_set_preedit(); | 5936 xim_set_preedit(); |
5925 } | 5937 } |
6017 EMSG(_("E284: Cannot set IC values")); | 6029 EMSG(_("E284: Cannot set IC values")); |
6018 XFree(attr_list); | 6030 XFree(attr_list); |
6019 } | 6031 } |
6020 } | 6032 } |
6021 | 6033 |
6022 #if defined(FEAT_GUI_X11) | 6034 # if defined(FEAT_GUI_X11) |
6023 static char e_xim[] = N_("E285: Failed to create input context"); | 6035 static char e_xim[] = N_("E285: Failed to create input context"); |
6024 #endif | 6036 # endif |
6025 | 6037 |
6026 #if defined(FEAT_GUI_X11) || defined(PROTO) | 6038 # if defined(FEAT_GUI_X11) || defined(PROTO) |
6027 # if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(SUN_SYSTEM) | 6039 # if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && !defined(SUN_SYSTEM) |
6028 # define USE_X11R6_XIM | 6040 # define USE_X11R6_XIM |
6029 # endif | 6041 # endif |
6030 | 6042 |
6031 static int xim_real_init(Window x11_window, Display *x11_display); | 6043 static int xim_real_init(Window x11_window, Display *x11_display); |
6032 | 6044 |
6033 | 6045 |
6034 #ifdef USE_X11R6_XIM | 6046 # ifdef USE_X11R6_XIM |
6035 static void xim_destroy_cb(XIM im, XPointer client_data, XPointer call_data); | 6047 static void xim_destroy_cb(XIM im, XPointer client_data, XPointer call_data); |
6036 | 6048 |
6037 static void | 6049 static void |
6038 xim_instantiate_cb( | 6050 xim_instantiate_cb( |
6039 Display *display, | 6051 Display *display, |
6041 XPointer call_data UNUSED) | 6053 XPointer call_data UNUSED) |
6042 { | 6054 { |
6043 Window x11_window; | 6055 Window x11_window; |
6044 Display *x11_display; | 6056 Display *x11_display; |
6045 | 6057 |
6046 #ifdef XIM_DEBUG | 6058 # ifdef XIM_DEBUG |
6047 xim_log("xim_instantiate_cb()\n"); | 6059 xim_log("xim_instantiate_cb()\n"); |
6048 #endif | 6060 # endif |
6049 | 6061 |
6050 gui_get_x11_windis(&x11_window, &x11_display); | 6062 gui_get_x11_windis(&x11_window, &x11_display); |
6051 if (display != x11_display) | 6063 if (display != x11_display) |
6052 return; | 6064 return; |
6053 | 6065 |
6065 XPointer call_data UNUSED) | 6077 XPointer call_data UNUSED) |
6066 { | 6078 { |
6067 Window x11_window; | 6079 Window x11_window; |
6068 Display *x11_display; | 6080 Display *x11_display; |
6069 | 6081 |
6070 #ifdef XIM_DEBUG | 6082 # ifdef XIM_DEBUG |
6071 xim_log("xim_destroy_cb()\n"); | 6083 xim_log("xim_destroy_cb()\n"); |
6072 #endif | 6084 #endif |
6073 gui_get_x11_windis(&x11_window, &x11_display); | 6085 gui_get_x11_windis(&x11_window, &x11_display); |
6074 | 6086 |
6075 xic = NULL; | 6087 xic = NULL; |
6076 status_area_enabled = FALSE; | 6088 status_area_enabled = FALSE; |
6077 | 6089 |
6078 gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH); | 6090 gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH); |
6079 | 6091 |
6080 XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL, | 6092 XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL, |
6081 xim_instantiate_cb, NULL); | 6093 xim_instantiate_cb, NULL); |
6082 } | 6094 } |
6083 #endif | 6095 # endif |
6084 | 6096 |
6085 void | 6097 void |
6086 xim_init(void) | 6098 xim_init(void) |
6087 { | 6099 { |
6088 Window x11_window; | 6100 Window x11_window; |
6089 Display *x11_display; | 6101 Display *x11_display; |
6090 | 6102 |
6091 #ifdef XIM_DEBUG | 6103 # ifdef XIM_DEBUG |
6092 xim_log("xim_init()\n"); | 6104 xim_log("xim_init()\n"); |
6093 #endif | 6105 # endif |
6094 | 6106 |
6095 gui_get_x11_windis(&x11_window, &x11_display); | 6107 gui_get_x11_windis(&x11_window, &x11_display); |
6096 | 6108 |
6097 xic = NULL; | 6109 xic = NULL; |
6098 | 6110 |
6099 if (xim_real_init(x11_window, x11_display)) | 6111 if (xim_real_init(x11_window, x11_display)) |
6100 return; | 6112 return; |
6101 | 6113 |
6102 gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH); | 6114 gui_set_shellsize(FALSE, FALSE, RESIZE_BOTH); |
6103 | 6115 |
6104 #ifdef USE_X11R6_XIM | 6116 # ifdef USE_X11R6_XIM |
6105 XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL, | 6117 XRegisterIMInstantiateCallback(x11_display, NULL, NULL, NULL, |
6106 xim_instantiate_cb, NULL); | 6118 xim_instantiate_cb, NULL); |
6107 #endif | 6119 # endif |
6108 } | 6120 } |
6109 | 6121 |
6110 static int | 6122 static int |
6111 xim_real_init(Window x11_window, Display *x11_display) | 6123 xim_real_init(Window x11_window, Display *x11_display) |
6112 { | 6124 { |
6114 char *p, | 6126 char *p, |
6115 *s, | 6127 *s, |
6116 *ns, | 6128 *ns, |
6117 *end, | 6129 *end, |
6118 tmp[1024]; | 6130 tmp[1024]; |
6119 #define IMLEN_MAX 40 | 6131 # define IMLEN_MAX 40 |
6120 char buf[IMLEN_MAX + 7]; | 6132 char buf[IMLEN_MAX + 7]; |
6121 XIM xim = NULL; | 6133 XIM xim = NULL; |
6122 XIMStyles *xim_styles; | 6134 XIMStyles *xim_styles; |
6123 XIMStyle this_input_style = 0; | 6135 XIMStyle this_input_style = 0; |
6124 Boolean found; | 6136 Boolean found; |
6179 verbose_leave(); | 6191 verbose_leave(); |
6180 } | 6192 } |
6181 return FALSE; | 6193 return FALSE; |
6182 } | 6194 } |
6183 | 6195 |
6184 #ifdef USE_X11R6_XIM | 6196 # ifdef USE_X11R6_XIM |
6185 { | 6197 { |
6186 XIMCallback destroy_cb; | 6198 XIMCallback destroy_cb; |
6187 | 6199 |
6188 destroy_cb.callback = xim_destroy_cb; | 6200 destroy_cb.callback = xim_destroy_cb; |
6189 destroy_cb.client_data = NULL; | 6201 destroy_cb.client_data = NULL; |
6190 if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL)) | 6202 if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL)) |
6191 EMSG(_("E287: Warning: Could not set destroy callback to IM")); | 6203 EMSG(_("E287: Warning: Could not set destroy callback to IM")); |
6192 } | 6204 } |
6193 #endif | 6205 # endif |
6194 | 6206 |
6195 if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles) | 6207 if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles) |
6196 { | 6208 { |
6197 EMSG(_("E288: input method doesn't support any style")); | 6209 EMSG(_("E288: input method doesn't support any style")); |
6198 XCloseIM(xim); | 6210 XCloseIM(xim); |
6264 over_spot.y = TEXT_Y(gui.row); | 6276 over_spot.y = TEXT_Y(gui.row); |
6265 input_style = this_input_style; | 6277 input_style = this_input_style; |
6266 | 6278 |
6267 /* A crash was reported when trying to pass gui.norm_font as XNFontSet, | 6279 /* A crash was reported when trying to pass gui.norm_font as XNFontSet, |
6268 * thus that has been removed. Hopefully the default works... */ | 6280 * thus that has been removed. Hopefully the default works... */ |
6269 #ifdef FEAT_XFONTSET | 6281 # ifdef FEAT_XFONTSET |
6270 if (gui.fontset != NOFONTSET) | 6282 if (gui.fontset != NOFONTSET) |
6271 { | 6283 { |
6272 preedit_list = XVaCreateNestedList(0, | 6284 preedit_list = XVaCreateNestedList(0, |
6273 XNSpotLocation, &over_spot, | 6285 XNSpotLocation, &over_spot, |
6274 XNForeground, (Pixel)gui.def_norm_pixel, | 6286 XNForeground, (Pixel)gui.def_norm_pixel, |
6280 XNBackground, (Pixel)gui.def_back_pixel, | 6292 XNBackground, (Pixel)gui.def_back_pixel, |
6281 XNFontSet, (XFontSet)gui.fontset, | 6293 XNFontSet, (XFontSet)gui.fontset, |
6282 NULL); | 6294 NULL); |
6283 } | 6295 } |
6284 else | 6296 else |
6285 #endif | 6297 # endif |
6286 { | 6298 { |
6287 preedit_list = XVaCreateNestedList(0, | 6299 preedit_list = XVaCreateNestedList(0, |
6288 XNSpotLocation, &over_spot, | 6300 XNSpotLocation, &over_spot, |
6289 XNForeground, (Pixel)gui.def_norm_pixel, | 6301 XNForeground, (Pixel)gui.def_norm_pixel, |
6290 XNBackground, (Pixel)gui.def_back_pixel, | 6302 XNBackground, (Pixel)gui.def_back_pixel, |
6322 } | 6334 } |
6323 | 6335 |
6324 return TRUE; | 6336 return TRUE; |
6325 } | 6337 } |
6326 | 6338 |
6327 #endif /* FEAT_GUI_X11 */ | 6339 # endif /* FEAT_GUI_X11 */ |
6328 | 6340 |
6329 /* | 6341 /* |
6330 * Get IM status. When IM is on, return TRUE. Else return FALSE. | 6342 * Get IM status. When IM is on, return TRUE. Else return FALSE. |
6331 * FIXME: This doesn't work correctly: Having focus doesn't always mean XIM is | 6343 * FIXME: This doesn't work correctly: Having focus doesn't always mean XIM is |
6332 * active, when not having focus XIM may still be active (e.g., when using a | 6344 * active, when not having focus XIM may still be active (e.g., when using a |
6333 * tear-off menu item). | 6345 * tear-off menu item). |
6334 */ | 6346 */ |
6335 int | 6347 int |
6336 im_get_status(void) | 6348 im_get_status(void) |
6337 { | 6349 { |
6350 # ifdef FEAT_EVAL | |
6351 if (p_imsf[0] != NUL) | |
6352 return call_imstatusfunc(); | |
6353 # endif | |
6338 return xim_has_focus; | 6354 return xim_has_focus; |
6339 } | 6355 } |
6340 | 6356 |
6341 # endif /* !FEAT_GUI_GTK */ | 6357 # endif /* !FEAT_GUI_GTK */ |
6342 | 6358 |
6456 # endif | 6472 # endif |
6457 | 6473 |
6458 #else /* !defined(FEAT_XIM) */ | 6474 #else /* !defined(FEAT_XIM) */ |
6459 | 6475 |
6460 # ifndef FEAT_GUI_W32 | 6476 # ifndef FEAT_GUI_W32 |
6477 static int im_was_set_active = FALSE; | |
6478 | |
6461 int | 6479 int |
6462 im_get_status() | 6480 im_get_status() |
6463 { | 6481 { |
6464 # ifdef FEAT_EVAL | 6482 # ifdef FEAT_EVAL |
6465 if (p_imsf[0] != NUL) | 6483 if (p_imsf[0] != NUL) |
6466 { | 6484 return call_imstatusfunc(); |
6467 int is_active; | |
6468 | |
6469 /* FIXME: Don't execute user function in unsafe situation. */ | |
6470 if (exiting | |
6471 # ifdef FEAT_AUTOCMD | |
6472 || is_autocmd_blocked() | |
6473 # endif | |
6474 ) | |
6475 return FALSE; | |
6476 /* FIXME: :py print 'xxx' is shown duplicate result. | |
6477 * Use silent to avoid it. */ | |
6478 ++msg_silent; | |
6479 is_active = call_func_retnr(p_imsf, 0, NULL, FALSE); | |
6480 --msg_silent; | |
6481 return (is_active > 0); | |
6482 } | |
6483 # endif | 6485 # endif |
6484 return FALSE; | 6486 return im_was_set_active; |
6485 } | 6487 } |
6486 | 6488 |
6487 void | 6489 void |
6488 im_set_active(int active) | 6490 im_set_active(int active_arg) |
6489 { | 6491 { |
6490 # if defined(USE_IM_CONTROL) && defined(FEAT_EVAL) | 6492 # if defined(FEAT_MBYTE) && defined(FEAT_EVAL) |
6491 if (p_imaf[0] != NUL) | 6493 int active = !p_imdisable && active_arg; |
6492 call_imactivatefunc(p_imdisable ? FALSE : active); | 6494 |
6495 if (p_imaf[0] != NUL && active != im_get_status()) | |
6496 { | |
6497 call_imactivatefunc(active); | |
6498 im_was_set_active = active; | |
6499 } | |
6493 # endif | 6500 # endif |
6494 } | 6501 } |
6495 # endif | 6502 # endif |
6496 | 6503 |
6497 #endif /* FEAT_XIM */ | 6504 #endif /* FEAT_XIM */ |