我目前正在寻找一种方法来从linux操作系统上的x服务器接收widgets焦点更改事件。
我试过使用XSelectInput(dpy, focuswin, FocusChangeMask);
,但服务器仅在聚焦窗口更改时通知我,而不是特定窗口中的聚焦小部件(例如文本输入)。
我想实现这一点,以便在可编辑文本区域获得焦点时显示虚拟键盘。
到目前为止编写的代码是:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
static Display *dpy;
static Window focuswin = None;
static void attach_to_focuswin(void) {
int revert_to = 0;
XGetInputFocus(dpy, &focuswin, &revert_to);
XSetWindowAttributes attr;
attr.event_mask = FocusChangeMask;
XChangeWindowAttributes(dpy, focuswin, CWEventMask, &attr);
if (focuswin != None)
XSelectInput(dpy, focuswin, FocusChangeMask);
else
sleep(1);
}
static void handle_event(void) {
XEvent ev;
char buf[100];
int len;
XNextEvent(dpy, &ev);
if (ev.xany.type == FocusOut) {
focuswin = None;
fprintf(stdout, "func: handle_event -> focusing out of window\n\n\n");
} else if (ev.xany.type == FocusIn) {
fprintf(stdout, "func: handle_event -> focusing out of window\n\n\n");
} else if (ev.xany.type == KeyPress) {
len = XLookupString(&ev.xkey, buf, 99, 0, 0);
buf[len] = 0;
printf("%s", buf);
fflush(stdout);
} else {
fprintf(stdout, "func: handle_event -> something else %d\n\n\n", ev.type);
}
}
int main(void) {
dpy = XOpenDisplay(getenv("DISPLAY"));
if (dpy == NULL) {
fprintf(stdout, "cannot init display\n");
exit(1);
}
while (1) {
if (focuswin == None)
attach_to_focuswin();
else
handle_event();
}
}
最佳答案
x服务器没有小部件的概念。它只知道窗户。
如果一个应用程序有一个文本输入、一个单选组和一个在单个窗口中实现的按钮,那么应用程序之外的任何东西都不知道它当前认为哪个小部件是活动的或集中的或其他什么。
如果文本小部件实际上是作为窗口实现的,则可以在其上获取焦点更改事件。您需要在该窗口上调用xselectinput。
此外,还不清楚如何区分文本输入窗口和其他应用程序中的其他窗口。x服务器不知道哪些窗口是文本输入窗口。
关于linux - 使用X11/Xlib接收有重点的窗口小部件更改事件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21904572/