Отправка XKeyEvent в приложения gtk3 - PullRequest
3 голосов
/ 19 октября 2011

Я использовал следующую документацию , чтобы написать метод в 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?

1 Ответ

2 голосов
/ 26 октября 2011

Я провел еще несколько расследований по этому вопросу. Похоже, что такие события будут получены приложением gtk3 при отправке с расширением XTest, также упомяните в заявленной документации 1002 *.

Вот пример в 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;
}
...