Linux X11 - 全球键盘钩 [英] Linux X11 - Global Keyboard Hook

查看:583
本文介绍了Linux X11 - 全球键盘钩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可能(或如何)创建一个机制(在Linux X11,C + +),它在Windows中的全局钩子(SetWindowsHookEx())?



我想要能够捕获关键事件,但会有进一步传播的可能性。我尝试使用 XGrabKey 解决方案(例如 xbindkeys ),但当我设置捕获关键事件时,此事件为已消耗



此机制的要求如下:


  1. 全局
  2. catch-hold和catch-pass through的可能性

  3. 像这样:

      bool myFlagIsSet = false; 
    XEvent事件;
    while(true){
    while(XPending(display)> 0){
    usleep(SLEEP_TIME);
    }

    XNextEvent(display,& event);
    switch(e.type){
    case KeyPress:
    if(myFlagIsSet){
    //不传播
    }
    //传播
    break;
    case KeyRelease:
    if(myFlagIsSet){
    //不传播
    }
    //传播
    break;
    }
    }



    在Windows上,我写了:

      if(event.isConsumed()){
    return LRESULT(1);
    }
    // ...
    return CallNextHookEx(hookHandle,nCode,wParam,lParam);

    我也尝试过使用XUngrabKey和XSendEvent:

      switch(event.type){
    case KeyPress:
    if(myFlagIsSet){
    // do不传播
    }
    //传播
    XUngrabKey(...);
    XSendEvent(...,& event);
    XGrabKey(...);
    break;
    case KeyRelease:
    ...
    }

    不幸的是,XSendEvent



    是否可以成功完成这个方法?



    如果我被判定失败,请建议其他方法



    EDIT



    我想使用Compiz窗口管理器在Ubuntu Gnome上实现此操作

    解决方案

    XSendEvent()可能会发送它;但由于它被广泛认为是一个安全漏洞,大多数程序忽略UI事件与 send_event 标志设置。



    标准的X11协议不允许这样。 XInput 2.0扩展可能,但我怀疑;而Windows假定每个程序侦听的单个事件队列,以便程序可以拦截事件并防止它被向下发送到其他侦听器,每个X11客户端都有自己的独立队列和所有注册在一个事件在队列中接收它的独立副本。这意味着在正常情况下,一个错误的程序阻止其他程序运行是不可能的;但它也意味着,对于客户端必须阻止其他客户端的时候,它必须执行服务器抓取,以防止服务器处理任何其他客户端的事件。


    Is it possible (or how) to create a mechanism (in Linux X11, C++) that works like a global hook in windows (SetWindowsHookEx())?

    I would like to be able to catch the key event but with the possibility of further propagation. I'm trying to use a XGrabKey solution (like in xbindkeys) but when I set capturing the key event, this event is "consumed".

    Requirements for this mechanism are the following:

    1. Global / system-wide - catching events regardless of the window that has focus
    2. The possibility of "catch-hold" and "catch-pass through"
    3. It must be quite fast

    Sample code looks like this:

    bool myFlagIsSet = false;
    XEvent event;
    while (true) {
        while (XPending(display) > 0) {
            usleep(SLEEP_TIME);
        }
    
        XNextEvent(display, &event);
        switch (e.type) {
            case KeyPress:
                if (myFlagIsSet) {
                    //do not propagate
                }
                // propagate
                break;
            case KeyRelease:
                if (myFlagIsSet) {
                    //do not propagate
                }
                // propagate
                break;
        }
    }
    

    On Windows I simply wrote:

    if(event.isConsumed()) {
        return LRESULT(1);
    }
    //...
    return CallNextHookEx(hookHandle, nCode, wParam, lParam);
    

    I've also tried using XUngrabKey and XSendEvent:

    switch (event.type) {
        case KeyPress:
            if (myFlagIsSet) {
                //do not propagate
            }
            // propagate
            XUngrabKey(...);
            XSendEvent(..., &event);
            XGrabKey(...);
            break;
        case KeyRelease:
            ...
        }
    

    Unfortunately XSendEvent for unknown reasons to me - do not send this event even if XGrabKey line is commented.

    Is it possible to successfully complete this approach?

    Please suggest some other approach if I am condemned to failure

    EDIT

    I would like to implement this on Ubuntu Gnome using Compiz Window Manager

    解决方案

    XSendEvent() probably does send it; but as it's widely regarded as a security hole, most programs ignore UI events with the send_event flag set.

    The standard X11 protocol doesn't allow this. The XInput 2.0 extension might, but I doubt it; while Windows assumes a single event queue that every program listens to, so that a program can intercept an event and prevent it from being sent down the queue to other listeners, every X11 client has its own independent queue and all clients that register interest in an event receive an independent copy of it in their queue. This means that under normal circumstances it's impossible for an errant program to block other programs from running; but it also means that, for those times when a client must block other clients, it must do a server grab to prevent the server from processing events for any other client.

    这篇关于Linux X11 - 全球键盘钩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆