From 1229bd811867cc2ba5f569aa08e798b17ac76daf Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 7 Jan 2022 15:38:12 +0800 Subject: [PATCH] Allow controlling the X input method style * doc/emacs/xresources.texi (Table of Resources): Document new resource `inputStyle'. * etc/NEWS: Announce new resource. * src/xfns.c (create_frame_xic): Give the display info to `best_xim_style'. (best_xim_style): Take the display's preferred style into account. * src/xterm.c (x_term_init): Parse the preferred style if inputStyle is set. * src/xterm.h (struct x_display_info): New field `preferred_xim_style'. (STYLE_OFFTHESPOT, STYLE_OVERTHESPOT, STYLE_ROOT): (STYLE_CALLBACK, STYLE_NONE): New macros. --- doc/emacs/xresources.texi | 18 ++++++++++++++++++ etc/NEWS | 5 +++++ src/xfns.c | 20 +++++++++++--------- src/xterm.c | 23 +++++++++++++++++++++++ src/xterm.h | 8 ++++++++ 5 files changed, 65 insertions(+), 9 deletions(-) diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi index ef3d4c768ca..c27fb8ad03e 100644 --- a/doc/emacs/xresources.texi +++ b/doc/emacs/xresources.texi @@ -332,6 +332,24 @@ Disable use of X input methods (XIM) if @samp{false} or @samp{off}. This is only relevant if your Emacs is built with XIM support. It might be useful to turn off XIM on slow X client/server links. +@item @code{inputStyle} (class @code{InputStyle}) +@cindex inputStyle (X resource) +@cindex input method style, X +This resource controls how preview text generated by X input methods +is displayed. If its value is @samp{callback}, input methods will +direct Emacs to display the contents of their preview text in the +current buffer. + +If it is @samp{offthespot}, input methods will display their preview +text inside a separate area of the display provided by Emacs. + +If it is @samp{overthespot}, input methods will display their preview +text inside a popup window at the location of the point in the current +window. + +If it is @samp{root}, input methods will display their preview text +inside a portion of the display specific to each input method. + @item @code{verticalScrollBars} (class @code{ScrollBars}) Give frames scroll bars on the left if @samp{left}, on the right if @samp{right}; don't have scroll bars if @samp{off} (@pxref{Scroll Bars}). diff --git a/etc/NEWS b/etc/NEWS index 2e6ba9da21c..ea08f7f3de7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -144,6 +144,11 @@ buffer isn't displayed. This controls the thickness of the external borders of the menu bars and pop-up menus. ++++ +** New X resource: "inputStyle". +This controls the style of the pre-edit and status areas of X input +methods. + --- ** New minor mode 'pixel-scroll-precision-mode'. When enabled, and if your mouse supports it, you can scroll the diff --git a/src/xfns.c b/src/xfns.c index d87e67f95b1..dbba374d751 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -2622,13 +2622,6 @@ xic_free_xfontset (struct frame *f) /* Create XIC for frame F. */ - -#define STYLE_OFFTHESPOT (XIMPreeditArea | XIMStatusArea) -#define STYLE_OVERTHESPOT (XIMPreeditPosition | XIMStatusNothing) -#define STYLE_ROOT (XIMPreeditNothing | XIMStatusNothing) -#define STYLE_CALLBACK (XIMPreeditCallbacks | XIMStatusNothing) -#define STYLE_NONE (XIMPreeditNothing | XIMStatusNothing) - static const XIMStyle supported_xim_styles[] = { STYLE_CALLBACK, @@ -2643,11 +2636,19 @@ static const XIMStyle supported_xim_styles[] = input method XIM. */ static XIMStyle -best_xim_style (XIMStyles *xim) +best_xim_style (struct x_display_info *dpyinfo, + XIMStyles *xim) { int i, j; int nr_supported = ARRAYELTS (supported_xim_styles); + if (dpyinfo->preferred_xim_style) + { + for (j = 0; j < xim->count_styles; ++j) + if (dpyinfo->preferred_xim_style == xim->supported_styles[j]) + return dpyinfo->preferred_xim_style; + } + for (i = 0; i < nr_supported; ++i) for (j = 0; j < xim->count_styles; ++j) if (supported_xim_styles[i] == xim->supported_styles[j]) @@ -2679,7 +2680,8 @@ create_frame_xic (struct frame *f) goto out; /* Determine XIC style. */ - xic_style = best_xim_style (FRAME_X_XIM_STYLES (f)); + xic_style = best_xim_style (FRAME_DISPLAY_INFO (f), + FRAME_X_XIM_STYLES (f)); /* Create X fontset. */ if (xic_style & (XIMPreeditPosition | XIMStatusArea)) diff --git a/src/xterm.c b/src/xterm.c index 73c0bcf89ea..b284fdd3123 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -15280,6 +15280,29 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) #endif } + { + AUTO_STRING (inputStyle, "inputStyle"); + AUTO_STRING (InputStyle, "InputStyle"); + Lisp_Object value = gui_display_get_resource (dpyinfo, inputStyle, InputStyle, + Qnil, Qnil); + +#ifdef HAVE_X_I18N + if (STRINGP (value)) + { + if (!strcmp (SSDATA (value), "callback")) + dpyinfo->preferred_xim_style = STYLE_CALLBACK; + else if (!strcmp (SSDATA (value), "none")) + dpyinfo->preferred_xim_style = STYLE_NONE; + else if (!strcmp (SSDATA (value), "overthespot")) + dpyinfo->preferred_xim_style = STYLE_OVERTHESPOT; + else if (!strcmp (SSDATA (value), "offthespot")) + dpyinfo->preferred_xim_style = STYLE_OFFTHESPOT; + else if (!strcmp (SSDATA (value), "root")) + dpyinfo->preferred_xim_style = STYLE_ROOT; + } +#endif + } + #ifdef HAVE_X_SM /* Only do this for the very first display in the Emacs session. Ignore X session management when Emacs was first started on a diff --git a/src/xterm.h b/src/xterm.h index dcac5732527..a796f69ddc1 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -434,6 +434,7 @@ struct x_display_info XIM xim; XIMStyles *xim_styles; struct xim_inst_t *xim_callback_data; + XIMStyle preferred_xim_style; #endif /* A cache mapping color names to RGB values. */ @@ -1331,6 +1332,13 @@ extern bool x_session_have_connection (void); extern void x_session_close (void); #endif +#ifdef HAVE_X_I18N +#define STYLE_OFFTHESPOT (XIMPreeditArea | XIMStatusArea) +#define STYLE_OVERTHESPOT (XIMPreeditPosition | XIMStatusNothing) +#define STYLE_ROOT (XIMPreeditNothing | XIMStatusNothing) +#define STYLE_CALLBACK (XIMPreeditCallbacks | XIMStatusNothing) +#define STYLE_NONE (XIMPreeditNothing | XIMStatusNothing) +#endif /* Is the frame embedded into another application? */ -- 2.39.2