tags:

views:

85

answers:

1

I'm trying to send and receive a client-event using a GtkWidget on the win32 platform. The sending code looks like this:

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

Receiving code looks like this:

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

I used Spy++ to see the message getting sent, so I know the sending side is ok. The receiving side however doesn't get the client-event. I was expecting my breakpoint in the callback to trigger... but it doesn't.

I'm not even sure if a GtkWindow can receive a client-event... from past experience on X11 I thought it was pretty much the same as any other GtkWidget in that respect. Maybe on the win32 platform it's kinda different. But still I'd like to be able to get this working.

I would like this to work with asynchronously, and in a thread-safe fashion, so that I can send events from worker threads up to the GUI thread.

A: 

I have a solution that seems to work. It may not be optimal but it's in the ball park.

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

If someone else has constructive comments I'll add/modify this as required.

fret
`gtk_main_do_event ()` http://library.gnome.org/devel/gtk/stable/gtk-General.html#gtk-main-do-event
Spudd86
also see http://library.gnome.org/devel/gobject/stable/signal.html#signal-emission
Spudd86
Are you saying I should be calling gtk_main_do_event instead of gtk_propagate_event? That would mean I have to set the GtkWidget pointer instead the GtkEvent structure by hand... which I can do. Is that where gtk_main_do_event gets it's widget pointer from?
fret