2010-06-15 3 views
0

Я пытаюсь отправить и получить клиент-событие с помощью GtkWidget на платформе 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 это совсем другое. Но все же я бы хотел, чтобы это работало.

Я хотел бы, чтобы это работало асинхронно и поточно-безопасным образом, чтобы я мог отправлять события из рабочих потоков до потока графического интерфейса.

+0

Почему вы отправляете четное через собственное окно вместо GtkWindow? Более новые версии Gtk не имеют соответствия 1: 1 между родными окнами и виджетами, вероятно, вы должны полностью придерживаться GdkWindows или даже GtkWidgets. Проблема, которая может вас укусить, состоит в том, что вы ожидаете, что все события из собственного окна будут переданы цепочке в GDK, но этого больше не происходит, см. Http://library.gnome.org/devel/gtk/ stable/gtk-migrating-ClientSideWindows.html – Spudd86

+0

Да, я понимаю клиентские окна в концепции, но как отправить сообщение клиента в GtkWindow или GtkWidget? (в отличие от GdkNativeWindow) – fret

+0

Я только что заметил gtk_propagate_event ... это то, что правильный метод использовать? – fret

ответ

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

Если у кого-то есть конструктивные комментарии, я буду добавлять/изменять это по мере необходимости.

+0

'gtk_main_do_event()' http://library.gnome.org/devel/gtk/stable/gtk-General.html#gtk-main-do-event – Spudd86

+0

также см. Http://library.gnome.org/devel/ gobject/stable/signal.html # signal-emission – Spudd86

+0

Вы говорите, что я должен называть gtk_main_do_event вместо gtk_propagate_event? Это означало бы, что я должен установить указатель GtkWidget вместо структуры GtkEvent вручную ... что я могу сделать. Это откуда gtk_main_do_event получает указатель виджетов? – fret

Смежные вопросы