首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用XCB检测窗口焦点变化

用XCB检测窗口焦点变化
EN

Stack Overflow用户
提问于 2019-09-11 19:58:34
回答 1查看 1.1K关注 0票数 3

我正在用XCB编写一个程序,它需要在窗口获得焦点或失去焦点时进行检测。到目前为止,我有这个,但它只是挂在xcb_wait_for_event调用,从来没有进入循环。我在这里错过了什么来抓根事件?还是我完全错了,还有一个比听根更好的方法?

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>

int main (int argc, char **argv)
{
    xcb_connection_t* conn = xcb_connect(NULL, NULL);
    if (xcb_connection_has_error(conn)) {
        printf("Cannot open daemon connection.");
        return 0;
    }

    xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;

    uint32_t values[] = { XCB_EVENT_MASK_FOCUS_CHANGE };
    xcb_change_window_attributes(
        conn,
        screen->root,
        XCB_CW_EVENT_MASK,
        values);

    xcb_generic_event_t *ev;
    while ((ev = xcb_wait_for_event(conn))) {
        printf("IN LOOP\n");
        switch (ev->response_type & 0x7F) {
        case XCB_FOCUS_IN:
        case XCB_FOCUS_OUT:
            printf("IN CASE\n");
            break;
        default:
            printf("IN DEFAULT\n");
            break;
        }
        free(ev);
    }

    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-12 15:37:43

只有当选择这些事件的窗口接收或丢失焦点时,才会发送焦点事件,请参阅https://www.x.org/releases/X11R7.5/doc/x11proto/proto.html

FocusIn FocusOut ..。 这些事件是在输入焦点改变时生成的,并报告给选择窗口上的FocusChange的客户端。

若要使用此功能,您必须在所有窗口上选择此事件掩码,并监视新窗口的创建。

我建议一种不同的方法:监视根窗口上的PropertyChangeNotify事件,以查看_NET_ACTIVE_WINDOW属性何时发生变化。根据EWMH的说法,该物业应由水务署更新。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xcb/xcb.h>

static xcb_atom_t intern_atom(xcb_connection_t *conn, const char *atom)
{
    xcb_atom_t result = XCB_NONE;
    xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(conn,
            xcb_intern_atom(conn, 0, strlen(atom), atom), NULL);
    if (r)
        result = r->atom;
    free(r);
    return result;
}

int main (int argc, char **argv)
{
    xcb_connection_t* conn = xcb_connect(NULL, NULL);
    if (xcb_connection_has_error(conn)) {
        printf("Cannot open daemon connection.");
        return 0;
    }

    xcb_atom_t active_window = intern_atom(conn, "_NET_ACTIVE_WINDOW");
    xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;

    uint32_t values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
    xcb_change_window_attributes(
        conn,
        screen->root,
        XCB_CW_EVENT_MASK,
        values);

    xcb_flush(conn);

    xcb_generic_event_t *ev;
    while ((ev = xcb_wait_for_event(conn))) {
        printf("IN LOOP\n");
        switch (ev->response_type & 0x7F) {
        case XCB_PROPERTY_NOTIFY: {
            xcb_property_notify_event_t *e = (void *) ev;
            if (e->atom == active_window)
                puts("active window changed");
            break;
        }
        default:
            printf("IN DEFAULT\n");
            break;
        }
        free(ev);
    }

    return 0;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57896007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档