2

I embedded a X11 app (xterm) in a Motif window. All seems to work fine, but if I press a key when the pointer isn't above the embedded app, it doesn't get it. Trying to fix this, I changed the main loop of the main app. Now it's like this:

  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);
    }

When I press a key outside embedded xterm the debug line being printed, but xterm doesn't print the key I sent.

How can I fix this? If needed, I'll post the code.

--mghis

mghis
  • 517
  • 1
  • 5
  • 14
  • You should at least set `ev.Window` to the correct value. – n. m. could be an AI Jun 20 '11 at 12:52
  • Gcc says ev has no member window (nor Window). If you mean `ev.xkey.window`, I tried with `ev.xkey.window = *xtW;` and the app still doesn't get the key. – mghis Jun 20 '11 at 13:35
  • 1
    Yes, ev is actually a union, it has no `window` member, but all of the union members do. So you're right about the `ev.xkey.window` syntax. You also should specifically enable `xterm` to accept events sent with `XSendEvent`, by setting its `allowSendEvents` resource to `True`. – n. m. could be an AI Jun 20 '11 at 13:50
  • Thanks a bunch! **It works!** Setting that resource did it! **Thanks** a lot! – mghis Jun 20 '11 at 13:54

1 Answers1

1

Well to start with you are assuming the XQueryTree will only return one child window - maybe it is returning more than one and you are passing the event on to the wrong one?

I'm not sure what that while loop around the XQueryTree call is for either.

You should also be calling XFree to free the child window list once you're done with it, or you will be leaking memory.

TomH
  • 8,900
  • 2
  • 32
  • 30
  • There is only one window in drawW. This is for sure and I use the same `XQueryTree` function to resize that window. The while loop is needed because the embedded window starts a bit after the main window, in another thread. With while loop, I'm sure embedded app is started and `XQueryTree` found it. Thanks for `XFree`, I added it. What about `XSendEvent` problem? – mghis Jun 20 '11 at 13:05
  • Well have you checked that none of the X calls are returning an error? See also the comment on your question about setting the target window in the event. – TomH Jun 20 '11 at 13:36
  • I answered the comment. I verified the X calls with `assert()` but the calls return 0. – mghis Jun 20 '11 at 13:40