2014-02-20 3 views
0

В настоящее время я ищу способ получения виджетов событий смены фокуса с X-сервера на ОС Linux.Получать сфокусированные изменения виджета с помощью X11/Xlib

Я пробовал использовать 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(); 
    } 
} 

ответ

1

Сервер X не имеет понятия виджетов. Он знает только окна.

Если приложение имеет текстовый ввод, группу радиостанций и кнопку, реализованную в одном окне, то ничто вне приложения не имеет представления о том, какой виджет в данный момент он считает активным или сфокусированным или каким-либо другим.

Если текстовый виджет фактически реализован как окно, вы можете получить на нем события смены фокуса. Вы должны вызвать XSelectInput в этом окне.

Кроме того, неясно, как вы можете различать окна ввода текста и другие виды окон в других приложениях. Сервер X не знает, какие окна являются текстовыми.

+0

спасибо! Тогда есть ли способ сделать это? Получать уведомление всякий раз, когда текстовый ввод получает фокус? Или, когда изменилась видимость курсора (предполагается, что она видна только тогда, когда виджет, который принимает ввод клавиатуры, сфокусирован)? – niculare

+1

X-сервер не знает о текстовом курсоре. Это просто нарисовано, как любая другая графическая форма. –

+0

Вы можете обнаружить его с помощью формы курсора, не уверен, насколько это надежна. Вам нужно расширение XFixes для прослушивания событий смены курсора. –