发送 XKeyEvent 到 gtk3 应用程序

发布于 2024-12-10 14:38:07 字数 1663 浏览 1 评论 0原文

我使用以下 文档 在 Vala 中编写一个方法来发送按键事件(例如V) 到具有焦点的应用程序。

代码如下:

public void press(string accelerator)
{
    X.KeyEvent key_event;
    if(create_key_event(accelerator, X.EventType.KeyPress, out key_event)) {
        X.Event event = (X.Event)key_event;
        key_event.display.send_event(key_event.window, false,
            X.EventMask.KeyPressMask, ref event);
    }
}

private bool create_key_event(string accelerator,
    int event_type, out X.KeyEvent key_event)
{
    // convert accelerator
    uint keysym;
    Gdk.ModifierType modifiers;
    Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
    unowned X.Display display = Gdk.x11_get_default_xdisplay();
    key_event = X.KeyEvent();

    int keycode = display.keysym_to_keycode(keysym);

    if(keycode != 0) {
        X.Window root_window = Gdk.x11_get_default_root_xwindow();

        // get window with focus
        X.Window focus;
        int revert_to_return;
        display.get_input_focus(out focus, out revert_to_return);

        key_event.display = display;
        key_event.root = root_window;
        key_event.window = focus;
        key_event.subwindow = X.None;
        key_event.time = X.CURRENT_TIME;
        key_event.keycode = keycode;
        key_event.state = modifiers;
        key_event.type = event_type;
        key_event.x = 1;
        key_event.y = 1;
        key_event.x_root = 1;
        key_event.y_root = 1;
        return true;
    }

    return false;
}

这在 gtk2 应用程序上运行良好。然而 gtk3 应用程序似乎完全忽略了此类事件。 有没有办法将此类事件发送到 gtk3 应用程序?

I used following documentation to write a method in Vala to send key press events (e.g. <Ctrl>V) to the application which has the focus.

Here is the code:

public void press(string accelerator)
{
    X.KeyEvent key_event;
    if(create_key_event(accelerator, X.EventType.KeyPress, out key_event)) {
        X.Event event = (X.Event)key_event;
        key_event.display.send_event(key_event.window, false,
            X.EventMask.KeyPressMask, ref event);
    }
}

private bool create_key_event(string accelerator,
    int event_type, out X.KeyEvent key_event)
{
    // convert accelerator
    uint keysym;
    Gdk.ModifierType modifiers;
    Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
    unowned X.Display display = Gdk.x11_get_default_xdisplay();
    key_event = X.KeyEvent();

    int keycode = display.keysym_to_keycode(keysym);

    if(keycode != 0) {
        X.Window root_window = Gdk.x11_get_default_root_xwindow();

        // get window with focus
        X.Window focus;
        int revert_to_return;
        display.get_input_focus(out focus, out revert_to_return);

        key_event.display = display;
        key_event.root = root_window;
        key_event.window = focus;
        key_event.subwindow = X.None;
        key_event.time = X.CURRENT_TIME;
        key_event.keycode = keycode;
        key_event.state = modifiers;
        key_event.type = event_type;
        key_event.x = 1;
        key_event.y = 1;
        key_event.x_root = 1;
        key_event.y_root = 1;
        return true;
    }

    return false;
}

This just works fine on gtk2 applications. However gtk3 applications seem to ignore such events altogether.
Is there a way to send such events to gtk3 applications as well?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦纸 2024-12-17 14:38:07

我对此做了更多调查。当使用 XTest 扩展发送时,gtk3 应用程序似乎会收到此类事件,并且在声明的 文档

这是 vala 中的示例,您需要将其绑定到 xtst.vapi 才能构建它:

public void press(string accelerator)
{
  if(perform_key_event(accelerator, true)) {
    debug("Successfully pressed key " + accelerator);
  }
}

private bool perform_key_event(string accelerator, bool press)
{
    // convert accelerator
    uint keysym;
    Gdk.ModifierType modifiers;
    Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
    unowned X.Display display = Gdk.x11_get_default_xdisplay();
    int keycode = display.keysym_to_keycode(keysym);

    if(keycode != 0) {

      if(Gdk.ModifierType.CONTROL_MASK in modifiers) {
        int modcode = display.keysym_to_keycode(Gdk.Key.Control_L);
        XTest.fake_key_event(display, modcode, press, delay);  
      }
      if(Gdk.ModifierType.SHIFT_MASK in modifiers) {
        int modcode = display.keysym_to_keycode(Gdk.Key.Shift_L);
        XTest.fake_key_event(display, modcode, press, delay);
      }

      X.Test.fake_key_event(display, keycode, press, 0);                
      return true;
    }

    return false;
}

I have done some more investigation on this. It seems that such events will be received by gtk3 application when sent with the XTest extension also mention on the stated documentation.

Here is a sample in vala and you will need to bind it against xtst.vapi to be able to build it:

public void press(string accelerator)
{
  if(perform_key_event(accelerator, true)) {
    debug("Successfully pressed key " + accelerator);
  }
}

private bool perform_key_event(string accelerator, bool press)
{
    // convert accelerator
    uint keysym;
    Gdk.ModifierType modifiers;
    Gtk.accelerator_parse(accelerator, out keysym, out modifiers);
    unowned X.Display display = Gdk.x11_get_default_xdisplay();
    int keycode = display.keysym_to_keycode(keysym);

    if(keycode != 0) {

      if(Gdk.ModifierType.CONTROL_MASK in modifiers) {
        int modcode = display.keysym_to_keycode(Gdk.Key.Control_L);
        XTest.fake_key_event(display, modcode, press, delay);  
      }
      if(Gdk.ModifierType.SHIFT_MASK in modifiers) {
        int modcode = display.keysym_to_keycode(Gdk.Key.Shift_L);
        XTest.fake_key_event(display, modcode, press, delay);
      }

      X.Test.fake_key_event(display, keycode, press, 0);                
      return true;
    }

    return false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文