UTF-8 输入和使用 XGetICValues

UTF-8 input and using XGetICValues

提问人:Irbis 提问时间:10/25/2023 最后编辑:Irbis 更新时间:10/28/2023 访问量:60

问:

我找到了一个 UTF-8 输入的示例(接受的答案),但我想知道该示例是否正确。结果可以传递给:XGetICValuesXSelectInput

unsigned long mask = 0;

if (!XGetICValues(ic, XNFilterEvents, &mask, NULL)) 
{
    XSelectInput(dpy, win, other_masks | mask);
}

您能解释一下上述代码的含义吗?是否必须获得正确的 UTF-8 输入?执行上述代码后,我是否也应该调用?XFilterEvent

Linux UTF-8 x11 xlib

评论


答:

1赞 VonC 10/28/2023 #1

执行上述代码后,我是否也应该调用 XFilterEvent ?

我怀疑您应该:为了正确处理 UTF-8 输入,不仅要获取事件掩码和选择输入事件,还要可能过滤这些事件以正确处理多字节或特殊输入序列。

应在事件循环中使用 XFilterEvent。它将有助于管理输入法以正确解释多字节或特殊键序列。
正如“XLIB 编程手册/过滤事件”中提到的,它是在 XNextEvent() 之后调用的。

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
    
int main(int argc, char ** argv)
{
    // Your initialization code
    
    while(1) {
        XNextEvent(dpy, &ev);
        if (XFilterEvent(&ev, win))  // Filter the event through the input method
            continue;
        switch(ev.type){
        case MappingNotify:
            XRefreshKeyboardMapping(&ev.xmapping);
            break;
        case KeyPress:
            {
                int count = 0;
                KeySym keysym = 0;
                char buf[20];
                Status status = 0;
                count = Xutf8LookupString(ic, (XKeyPressedEvent*)&ev, buf, 20, &keysym, &status);
    
                printf("count: %d\n", count);
                if (status == XBufferOverflow)
                    printf("BufferOverflow\n");
    
                if (count)
                    printf("buffer: %.*s\n", count, buf);
 
                if (status == XLookupKeySym || status == XLookupBoth) {
                    printf("status: %d\n", status);
                }
                printf("pressed KEY: %d\n", (int)keysym);
            }
            break;
        case KeyRelease:
            // Rest of your code for other cases
        }
        fflush(stdout);
    }
}

如果返回 ,则表示事件已由输入法过滤和处理,则执行该语句以跳过循环的其余部分并处理下一个事件。XFilterEventTruecontinue

+--------------------+    XNFilterEvents        +--------------+
| Input Context (IC) |------------------------->| Event Mask   |
+--------------------+                          +--------------+
           |                                           |
      XGetICValues                               Retrieved Mask
           |                                           |
           V                                           V
+--------------------+    other_masks | mask    +--------------+
| XSelectInput       |------------------------->| Event Input  |
+--------------------+                          +--------------+
           |                                           |
           |                                    +--------------+
           |                                    | X Event      |
           |                                    +--------------+
           |                                           |
           V                                           V
+--------------------+    XFilterEvent          +--------------+
| Event Loop         |------------------------->| Event Filter |
+--------------------+    (optional)            +--------------+
  • 查询输入上下文 (IC) 以获取事件掩码,这是了解要侦听哪些事件所需的。XSelectInput
  • XSelectInput 与其他掩码和检索到的掩码的组合一起调用,以指定应为指定窗口报告的事件。
  • 在事件循环中,被调用以过滤事件队列中的相关输入事件,这在处理多字节或特殊输入序列时特别有用。此步骤标记为可选,因为它基于处理特殊输入序列的要求。XFilterEvent

评论

0赞 Irbis 10/28/2023
因此,将从 XGetICValues 检索到的掩码传递给 XSelectInput 是正确过滤事件的必要条件,对吧?
1赞 VonC 10/28/2023
@Irbis 将从 XGetICValues 检索到的事件掩码传递给 XSelectInput 不是强制性的,但它对于正确筛选和处理输入事件至关重要,尤其是在存在多字节或特殊输入序列的情况下。使用 XNFilterEvents 属性从 XGetICValues 获取的掩码提供了输入法正确操作所需的事件集。
1赞 n. m. could be an AI 10/28/2023 #2

既然这是我的例子/答案,我觉得有义务插话。

在我的示例中,对于我的特定 IM,您无需调用 .它将掩码设置为我无论如何都设置的掩码。但是,通常,对于输入掩码的其他选择和/或其他输入方法,您确实需要调用 。XGetICValuesKeyPressMask|KeyReleaseMaskXGetICValues

显然,如果您不设置其中任何一个或自己,它将不起作用。但远不止于此。如果输入法涉及屏幕键盘,则 IM 将需要处理鼠标事件,如果不使用 .KeyPressMaskKeyReleaseMaskXGetICValues

所以一般来说,是的,请调用并将掩码传递给 .是的,您确实需要打电话,因为这就是 IM 魔术发生的地方。XSelectInputXSelectInputXFilterEvent

我将更新您参考的答案以反映这一点。