LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

Ещё man XKeyEvent — там же subwindow прилетает, так что focus не нужен, вот такой вариант у меня работает:

#include <cassert>
#include <cstdio>

#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main() {
    const auto d = XOpenDisplay(0);
    const auto r = XDefaultRootWindow(d);
    const auto m_ctrl = ControlMask;
    const auto k_y = XKeysymToKeycode(d, XK_Y);
    XGrabKey(d, k_y, m_ctrl, r, False, GrabModeAsync, GrabModeAsync);
    XEvent e;
    while (1) {
        XNextEvent(d, &e);
        if (e.type == KeyPress) {
            assert(e.xkey.state == m_ctrl && e.xkey.keycode == k_y);
            printf("hot key pressed on %lu, resending...\n", e.xkey.subwindow);
            const auto w = e.xkey.subwindow;
            static XKeyEvent e;
            e.display = d;
            e.window = w;
            e.time = CurrentTime;
            e.type = KeyPress;
            e.state = m_ctrl;
            e.keycode = k_y;
            XSendEvent(d, w, True, KeyPressMask, (XEvent*)&e);
            e.type = KeyRelease;
            XSendEvent(d, w, True, KeyPressMask, (XEvent*)&e);
        }
    }
}

Исходная версия quasimoto, :

Ещё man XKeyEvent — там же subwindow прилетает, так что focus не нужен, вот такой вариант у меня работает:

#include <cassert>
#include <cstdio>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

int main() {
    const auto d = XOpenDisplay(0);
    const auto r = XDefaultRootWindow(d);
    const auto m_ctrl = ControlMask;
    const auto k_y = XKeysymToKeycode(d, XK_Y);
    XGrabKey(d, k_y, m_ctrl, r, False, GrabModeAsync, GrabModeAsync);
    XEvent e;
    while (1) {
        XNextEvent(d, &e);
        if (e.type == KeyPress) {
            assert(e.xkey.state == m_ctrl && e.xkey.keycode == k_y);
            printf("hot key pressed on %lu, resending...\n", e.xkey.subwindow);
            const auto w = e.xkey.subwindow;
            static XKeyEvent e;
            e.display = d;
            e.window = w;
            e.time = CurrentTime;
            e.type = KeyPress;
            e.state = m_ctrl;
            e.keycode = k_y;
            XSendEvent(d, w, True, KeyPressMask, (XEvent*)&e);
            e.type = KeyRelease;
            XSendEvent(d, w, True, KeyPressMask, (XEvent*)&e);
        }
    }
}