I am currently searching for a way to receive widgets focus change events from X server on Linux OS.
I have tried using XSelectInput(dpy, focuswin, FocusChangeMask);
, but the server notifies me only when the focused window changes, not the focused widget (eg a text input) inside a specific window.
I want to accomplish this in order to show a virtual keyboard whenever an editable text area gains focus.
The code written until now is:
#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();
}
}
The X server has no concept of widgets. It only knows windows.
If an application has a text input, a radio group, and a push button implemented all in a single window, then nothing outside of the application has any idea about which widget it currently considers active or focused or whatever.
If the text widget is actually implemented as a window, you can get focus change events on it. You need to call XSelectInput on that window .
In addition, it's not clear how you can differentiate between text input windows and other kinds of windows in other applications. The X server has no idea which windows are text-input ones.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.