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 */