【问题标题】:XmDrawingArea input callback misses eventsXmDrawingArea 输入回调未命中事件
【发布时间】:2021-10-29 21:03:12
【问题描述】:

我正在尝试查找一个看起来像是 Motif 绘图区域中缺少事件的问题。

如果我在绘图区域内点击鼠标按钮 1,我会收到 ButtonPress 和 ButtonRelease 事件,但随后我会停止收到 Ctrl 和 Shift 键的键事件(其他键似乎没问题)。 在这种状态下,如果我按下另一个键(比如 ESC),我会得到 ESC 键的 KeyPress 和 KeyRelease,然后我也开始获取 Ctrl 和 Shift 的键事件(不是我错过的那些 - 只是任何新的按下)

再次点击按钮,Ctrl/Shift 再次“消失”。单击鼠标按钮 3 并返回 Ctrl/Shift。

按住 Ctrl 并单击按钮 1(然后释放 Ctrl),我得到 KeyPress 和 ButtonRelease,然后是 KeyRelease。 (无按钮)

这一切有什么解释吗?我在 Windows 和本机 X 服务器(通过 x2go)上使用 eXceed 看到它。我在 Linux 和 Solaris 客户端都看到了它。

编辑:我的实际应用有一个“自定义”事件循环(只是抓取一个事件,可选择记录它然后分派)。我是看到 X11 事件循环看到了丢失的事件,但它们没有进入绘图区域输入 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;
}

【问题讨论】:

    标签: x11 motif


    【解决方案1】:

    我仍然不确定为什么输入回调会错过一些事件。可能是 Motif 版本不同。

    我的解决方法是根本不使用输入回调,而是使用事件处理程序来获取按钮按下/释放 + 按键按下/释放事件。 在事件处理程序中,我创建了一个虚拟 CB 结构,因此我可以调用我的客户端代码,就像事件来自 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-07
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多