【问题标题】:X11, sending an event with XSendEvent(3)X11,使用 XSendEvent(3) 发送事件
【发布时间】:2011-06-20 12:38:45
【问题描述】:

我在 Motif 窗口中嵌入了一个 X11 应用程序 (xterm)。一切似乎都工作正常,但是如果我在指针不在嵌入式应用程序上方时按下一个键,它就不会得到它。为了解决这个问题,我更改了主应用程序的主循环。现在是这样的:

  XEvent ev;
  for (;;)
    {
      XtAppNextEvent (app, &ev);

      /* If the event is a keypress, send it to
       * the xterm window. Else, dispatch it.
       */
      Window *xtW = NULL, parent, _root;
      unsigned int noC;

      if (ev.type == KeyPress || ev.type == KeyRelease)
   {
#ifdef DEBUG
     fprintf (stderr, "Key event\n");
#endif
     while (xtW == NULL)
       XQueryTree (XtDisplay (drawW), XtWindow (drawW), &_root,
         &parent, &xtW, &noC);

     XSendEvent (XtDisplay (drawW), *xtW, True,
            (KeyPressMask | KeyReleaseMask), &ev);
     XFlush (XtDisplay (drawW));
#ifdef DEBUG
     fprintf (stderr, "sent key event\n");
#endif
   }
      else
     XtDispatchEvent (&ev);
    }

当我按下嵌入式 xterm 外部的键时,调试行正在打印,但 xterm 不打印我发送的密钥。

我该如何解决这个问题?如果需要,我会发布代码。

--mghis

【问题讨论】:

  • 您至少应该将ev.Window 设置为正确的值。
  • Gcc 说 ev 没有成员窗口(也没有窗口)。如果您的意思是ev.xkey.window,我尝试使用ev.xkey.window = *xtW;,但应用仍然无法获取密钥。
  • 是的,ev 实际上是一个联合,它没有window 成员,但所有联合成员都有。所以你对ev.xkey.window 语法是正确的。您还应该专门启用xterm 以接受使用XSendEvent 发送的事件,方法是将其allowSendEvents 资源设置为True
  • 非常感谢! 它有效! 设置该资源就可以了! 非常感谢

标签: c linux x11 xterm motif


【解决方案1】:

首先,您假设XQueryTree 只会返回一个子窗口 - 也许它返回的子窗口不止一个,而您将事件传递给错误的子窗口?

我不确定 XQueryTree 调用周围的 while 循环是什么。

您还应该在完成后调用XFree 来释放子窗口列表,否则您将泄漏内存。

【讨论】:

  • drawW中只有一个窗口。这是肯定的,我使用相同的XQueryTree 函数来调整该窗口的大小。需要 while 循环,因为嵌入式窗口在主窗口之后开始,在另一个线程中。使用 while 循环,我确定嵌入式应用程序已启动并且 XQueryTree 找到了它。谢谢XFree,我加了。 XSendEvent 问题呢?
  • 那么您是否检查过没有任何 X 调用返回错误?另请参阅有关在事件中设置目标窗口的问题的评论。
  • 我回答了评论。我用assert() 验证了 X 调用,但调用返回 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2018-09-28
  • 2019-08-03
  • 1970-01-01
相关资源
最近更新 更多