x11motif

XmDrawingArea input callback misses events


I'm trying to track down a problem that looks like missing events in a Motif drawing area.

If I hit mouse button 1 inside the drawing area I get the ButtonPress and ButtonRelease events but then I stop getting Key events for Ctrl and Shift Keys (other keys seem ok). In this state if I hit another key (say ESC) I get the KeyPress and KeyRelease for the ESC key and then I start to get Key events for Ctrl and Shift too (not the ones I missed - just any new presses)

Hit Button one again and Ctrl/Shift "disappear" again. Click mouse button 3 and Ctrl/Shift are back.

Hold Ctrl and Click button 1 (then release Ctrl) and I get the KeyPress and a ButtonRelease then KeyRelease. (No ButtonPress)

Is there any explanation for all of this ? I'm seeing it using eXceed on Windows and a native X server (via x2go). I'm seeing it with both Linux and Solaris clients.

Edit: My actual app has a "custom" event loop (just grabs an event, optionally logs it then dispatches). I was to see the missing events are seen by the X11 event loop but they don't make it though to the drawing area input CB.

#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/DrawingA.h>

void inputCb(Widget w, XtPointer client, XtPointer call)
{
    char *type;
    char data[16] = {0};
    
    XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call;

    switch(cbs->event->type)
    {
        case ButtonPress:
            type="ButtonPress";
            break;
        case ButtonRelease:
            type="ButtonRelease";
            break;
        case KeyPress:
            type="KeyPress";
            break;
        case KeyRelease:
            type="KeyRelease";
            break;
        default:
            type="Other";
            sprintf(data, " (%d)", cbs->event->type);
            break;
    }
    printf("%s%s\n", type, data);
}

int
main(int argc, char *argv[])
{
  XtAppContext appContext;
  Widget toplevel, drawingArea;

  toplevel = XtVaAppInitialize(&appContext, "drawingArea", NULL, 0,
                   &argc, argv, NULL, NULL);
  drawingArea= XtVaCreateManagedWidget("drawingArea", xmDrawingAreaWidgetClass, toplevel,
    NULL);

  XtAddCallback(drawingArea, XmNinputCallback, inputCb, (XtPointer)0);
  XtRealizeWidget(toplevel);
  XtAppMainLoop(appContext);
  return 0;
}

Solution

  • I'm still not sure why the input callback misses some events. It may be down to a Motif version difference.

    My workaround was to not use the input callback at all but instead use an event handler that gets Button Press/Release + Key Press/Release events. In the Event handler I create a dummy CB struct so I can call my client code the same as if the event came from the CB

     XtAddEventHandler(drawArea,
            ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask,
            False, (XtEventHandler)inputEH, (XtPointer)0);
    
    
    static void inputEH(Widget     w,
                     XtPointer     clientData,
                     XEvent*       event,
                     Boolean*      continueToDispatch)
    {
        // Create a dummy call_data so it looks like we've come from the InputCB
        //
        XmAnyCallbackStruct call_data;
        call_data.reason = XmCR_INPUT;
        call_data.event = event;
    
        client_code_that_expects_certain_args(w, clientData, &call_data);
    }