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

如何将客户端事件异步发送到GtkWidget?,gtk,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

我正在尝试在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);
接收代码如下所示:

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线程。

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

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

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

为什么要通过本机窗口而不是GtkWindow发送?Gtk的较新版本在本机窗口和小部件之间没有1:1的对应关系,您可能应该完全使用GdkWindows,甚至只使用GTKwidget。可能会困扰您的问题是,您希望来自本机窗口的所有事件在GDK链中向上传递,但这种情况不再发生,请参见:是的,我在概念上理解客户端窗口,但如何向GtkWindow或GtkWidget发送客户端消息?与GdkNativeWindowI刚刚注意到的gtk_传播_事件相反。。。这是正确的方法吗?gtk_propagate_事件实现了我想要的功能,但它是同步的。我希望有一种方法可以将事件发布到线程安全的队列中!以后再发。gtk_main_do_event也看到了吗?你是说我应该叫gtk_main_do_event而不是gtk_propagate_event?这意味着我必须手动设置GtkWidget指针,而不是GtkEvent结构。。。我能做到。这就是gtk_main_do_事件获取小部件指针的地方吗?