Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用X11/Xlib接收聚焦小部件更改事件_Linux_X11_Xlib_Xorg - Fatal编程技术网

Linux 使用X11/Xlib接收聚焦小部件更改事件

Linux 使用X11/Xlib接收聚焦小部件更改事件,linux,x11,xlib,xorg,Linux,X11,Xlib,Xorg,我目前正在寻找一种从Linux操作系统上的X服务器接收Widget焦点更改事件的方法 我试过使用XSelectInput(dpy、focuswin、FocusChangeMask),但服务器仅在焦点窗口更改时通知我,而不是特定窗口内的焦点小部件(例如文本输入) 我想实现这一点,以便在可编辑文本区域获得焦点时显示虚拟键盘 到目前为止编写的代码是: #include <stdio.h> #include <stdlib.h> #include <unistd.h>

我目前正在寻找一种从Linux操作系统上的X服务器接收Widget焦点更改事件的方法

我试过使用
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();
    }
}
#包括
#包括
#包括
#包括
#包括
静态显示*dpy;
静态窗口焦点Win=无;
静态void将_附加到_focuswin(void){
int返回到=0;
XGetInputFocus(dpy、&focuswin、&revert_to);
xsetwindowatts attr;
attr.event_mask=焦点更改mask;
XChangeWindowAttributes(dpy、focuswin、CWEventMask和attr);
如果(focuswin!=无)
XSelectInput(dpy、focuswin、FocusChangeMask);
其他的
睡眠(1);
}
静态无效句柄\u事件(无效){
XEvent电动汽车;
char-buf[100];
内伦;
XNextEvent(dpy和ev);
if(ev.xany.type==FocusOut){
focuswin=无;
fprintf(stdout,“func:handle_event->在窗口外聚焦\n\n\n”);
}else if(ev.xany.type==FocusIn){
fprintf(stdout,“func:handle_event->在窗口外聚焦\n\n\n”);
}else if(ev.xany.type==按键){
len=XLookupString(&ev.xkey,buf,99,0,0);
buf[len]=0;
printf(“%s”,buf);
fflush(stdout);
}否则{
fprintf(标准输出,“func:handle\u event->something other%d\n\n”,ev.type);
}
}
内部主(空){
dpy=XOpenDisplay(getenv(“DISPLAY”);
如果(dpy==NULL){
fprintf(stdout,“无法初始化显示\n”);
出口(1);
}
而(1){
如果(focuswin==无)
将_连接到_focuswin();
其他的
handle_事件();
}
}

X服务器没有小部件的概念。它只知道窗户

如果一个应用程序有一个文本输入、一个单选组和一个按钮都在一个窗口中实现,那么应用程序之外的任何东西都不知道它当前认为哪个小部件是活动的或集中的,或者其他什么

如果文本小部件实际上是作为一个窗口实现的,那么您可以在其上获得焦点更改事件。您需要在该窗口上调用XSelectInput


此外,还不清楚如何在其他应用程序中区分文本输入窗口和其他类型的窗口。X服务器不知道哪些窗口是文本输入窗口。

非常感谢!那么有没有办法做到这一点呢?在文本输入获得焦点时接收通知?或者当光标的可见性发生变化时(假设只有当接受键盘输入的小部件聚焦时才可见)?X服务器不知道文本光标。它就像其他任何图形形状一样绘制。你可能会用光标形状来检测它,但不确定这有多可靠。您需要XFixes扩展来监听光标的更改events@AndreySidorov当您将光标移动到窗口上时,光标形状通常会改变,因此您需要将光标形状和焦点事件以及可能的光标坐标结合起来。报告光标改变时的afaik坐标(+服务器事件时间)