如何将客户端事件异步发送到GtkWidget?

时间:2010-06-15 00:34:35

标签: gtk

我正在尝试使用win32平台上的GtkWidget发送和接收客户端事件。发送代码如下所示:

GtkWidget *Wnd;
GdkNativeWindow Hnd =
#ifdef WIN32
    GDK_WINDOW_HWND(Wnd->window);
#else
    GDK_WINDOW_XWINDOW(Wnd->window);
#endif
GdkEvent *Event = gdk_event_new(GDK_CLIENT_EVENT);
// fill out Event params
gdk_event_send_client_message(Event, Hnd);

接收代码如下:

static gboolean MyClientEvent(GtkWidget *widget, GdkEventClient *ev, MyWnd *Wnd)
{
    // breakpoint here...
    return TRUE;
}

GtkWidget *Wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(   G_OBJECT(Wnd),
                    "client-event",
                    G_CALLBACK(MyClientEvent),
                    this);
gtk_widget_add_events(Wnd, GDK_ALL_EVENTS_MASK);

我使用Spy ++来查看发送的消息,所以我知道发送方是可以的。然而,接收方没有得到客户端事件。我期待回调中的断点触发......但事实并非如此。

我甚至不确定GtkWindow是否可以接收客户端事件......根据X11的过去经验我觉得它在这方面与其他任何GtkWidget几乎相同。也许在win32平台上它有点不同。但我仍然希望能够让这个工作。

我希望这能以异步方式工作,并且以线程安全的方式工作,这样我就可以将工作线程中的事件发送到GUI线程。

1 个答案:

答案 0 :(得分:0)

我有一个似乎有效的解决方案。它可能不是最佳的,但它在球场。

struct GlibEventParams
{
    GtkWidget *w;
    GdkEvent *e;
};

static gboolean 
GlibPostMessage(GlibEventParams *p)
{
    GDK_THREADS_ENTER ();
    gtk_propagate_event(p->w, p->e);
    gdk_event_free(p->e);
    delete p;
    GDK_THREADS_LEAVE ();

    return FALSE;
}

bool MySendEvent(GtkWidget *Wnd, GtkEvent *Event)
{
    bool Status = false;

    if (Event && Wnd)
    {
        GlibEventParams *p = new GlibEventParams;
        p->w = Wnd;
        p->e = gdk_event_new(GDK_CLIENT_EVENT);
        *p->e = *Event;
        Status = g_idle_add((GSourceFunc)GlibPostMessage, p) > 0;
    }
    else assert(!"No Event or Wnd");

    return Status;
}

如果其他人有建设性意见,我会根据需要添加/修改。