diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 10c1097045..dc0d32c66b 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -64,6 +64,53 @@ extern bool g_isIdle; extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; +static bool g_hasDoubleClicked = FALSE; + +//----------------------------------------------------------------------------- +// "button_release_event" +//----------------------------------------------------------------------------- + +/* we would normally emit a wxEVT_COMMAND_LISTBOX_DOUBLECLICKED event once + a GDK_2BUTTON_PRESS occurs, but this has the particular problem of the + listbox keeping the focus until it receives a GDK_BUTTON_RELEASE event. + this can lead to race conditions so that we emit the dclick event + after the GDK_BUTTON_RELEASE event after the GDK_2BUTTON_PRESS event */ + +static gint +gtk_listbox_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxListBox *listbox ) +{ + if (g_isIdle) wxapp_install_idle_handler(); + + if (g_blockEventsOnDrag) return FALSE; + if (g_blockEventsOnScroll) return FALSE; + + if (!listbox->m_hasVMT) return FALSE; + + if (!g_hasDoubleClicked) return FALSE; + + wxCommandEvent event( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, listbox->GetId() ); + event.SetEventObject( listbox ); + + wxArrayInt aSelections; + int count = listbox->GetSelections(aSelections); + if ( count > 0 ) + { + event.m_commandInt = aSelections[0] ; + event.m_clientData = listbox->GetClientData( event.m_commandInt ); + wxString str(listbox->GetString(event.m_commandInt)); + if (!str.IsEmpty()) event.m_commandString = str; + } + else + { + event.m_commandInt = -1 ; + event.m_commandString.Empty(); + } + + listbox->GetEventHandler()->ProcessEvent( event ); + + return FALSE; +} + //----------------------------------------------------------------------------- // "button_press_event" //----------------------------------------------------------------------------- @@ -91,30 +138,9 @@ gtk_listbox_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, event.SetInt( sel ); listbox->GetEventHandler()->ProcessEvent( event ); } - - if (gdk_event->type == GDK_2BUTTON_PRESS) - { - wxCommandEvent event( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, listbox->GetId() ); - event.SetEventObject( listbox ); - - wxArrayInt aSelections; - int count = listbox->GetSelections(aSelections); - if ( count > 0 ) - { - event.m_commandInt = aSelections[0] ; - event.m_clientData = listbox->GetClientData( event.m_commandInt ); - wxString str(listbox->GetString(event.m_commandInt)); - if (!str.IsEmpty()) event.m_commandString = str; - } - else - { - event.m_commandInt = -1 ; - event.m_commandString.Empty(); - } - - listbox->GetEventHandler()->ProcessEvent( event ); - - } + + /* emit wxEVT_COMMAND_LISTBOX_DOUBLECLICKED later */ + g_hasDoubleClicked = (gdk_event->type == GDK_2BUTTON_PRESS); return FALSE; } @@ -269,6 +295,11 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, (GtkSignalFunc)gtk_listbox_button_press_callback, (gpointer) this ); + gtk_signal_connect_after( GTK_OBJECT(list_item), + "button_release_event", + (GtkSignalFunc)gtk_listbox_button_release_callback, + (gpointer) this ); + if (m_hasCheckBoxes) { gtk_signal_connect( GTK_OBJECT(list_item), diff --git a/src/gtk/win_gtk.c b/src/gtk/win_gtk.c index d7f721c56b..43f275e840 100644 --- a/src/gtk/win_gtk.c +++ b/src/gtk/win_gtk.c @@ -228,7 +228,7 @@ gtk_myfixed_put (GtkMyFixed *myfixed, if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget)) gtk_widget_realize (widget); - if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget)) + if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget) && GTK_WIDGET_VISIBLE (widget)) gtk_widget_map (widget); if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed)) diff --git a/src/gtk1/listbox.cpp b/src/gtk1/listbox.cpp index 10c1097045..dc0d32c66b 100644 --- a/src/gtk1/listbox.cpp +++ b/src/gtk1/listbox.cpp @@ -64,6 +64,53 @@ extern bool g_isIdle; extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; +static bool g_hasDoubleClicked = FALSE; + +//----------------------------------------------------------------------------- +// "button_release_event" +//----------------------------------------------------------------------------- + +/* we would normally emit a wxEVT_COMMAND_LISTBOX_DOUBLECLICKED event once + a GDK_2BUTTON_PRESS occurs, but this has the particular problem of the + listbox keeping the focus until it receives a GDK_BUTTON_RELEASE event. + this can lead to race conditions so that we emit the dclick event + after the GDK_BUTTON_RELEASE event after the GDK_2BUTTON_PRESS event */ + +static gint +gtk_listbox_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxListBox *listbox ) +{ + if (g_isIdle) wxapp_install_idle_handler(); + + if (g_blockEventsOnDrag) return FALSE; + if (g_blockEventsOnScroll) return FALSE; + + if (!listbox->m_hasVMT) return FALSE; + + if (!g_hasDoubleClicked) return FALSE; + + wxCommandEvent event( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, listbox->GetId() ); + event.SetEventObject( listbox ); + + wxArrayInt aSelections; + int count = listbox->GetSelections(aSelections); + if ( count > 0 ) + { + event.m_commandInt = aSelections[0] ; + event.m_clientData = listbox->GetClientData( event.m_commandInt ); + wxString str(listbox->GetString(event.m_commandInt)); + if (!str.IsEmpty()) event.m_commandString = str; + } + else + { + event.m_commandInt = -1 ; + event.m_commandString.Empty(); + } + + listbox->GetEventHandler()->ProcessEvent( event ); + + return FALSE; +} + //----------------------------------------------------------------------------- // "button_press_event" //----------------------------------------------------------------------------- @@ -91,30 +138,9 @@ gtk_listbox_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, event.SetInt( sel ); listbox->GetEventHandler()->ProcessEvent( event ); } - - if (gdk_event->type == GDK_2BUTTON_PRESS) - { - wxCommandEvent event( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, listbox->GetId() ); - event.SetEventObject( listbox ); - - wxArrayInt aSelections; - int count = listbox->GetSelections(aSelections); - if ( count > 0 ) - { - event.m_commandInt = aSelections[0] ; - event.m_clientData = listbox->GetClientData( event.m_commandInt ); - wxString str(listbox->GetString(event.m_commandInt)); - if (!str.IsEmpty()) event.m_commandString = str; - } - else - { - event.m_commandInt = -1 ; - event.m_commandString.Empty(); - } - - listbox->GetEventHandler()->ProcessEvent( event ); - - } + + /* emit wxEVT_COMMAND_LISTBOX_DOUBLECLICKED later */ + g_hasDoubleClicked = (gdk_event->type == GDK_2BUTTON_PRESS); return FALSE; } @@ -269,6 +295,11 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, (GtkSignalFunc)gtk_listbox_button_press_callback, (gpointer) this ); + gtk_signal_connect_after( GTK_OBJECT(list_item), + "button_release_event", + (GtkSignalFunc)gtk_listbox_button_release_callback, + (gpointer) this ); + if (m_hasCheckBoxes) { gtk_signal_connect( GTK_OBJECT(list_item), diff --git a/src/gtk1/win_gtk.c b/src/gtk1/win_gtk.c index d7f721c56b..43f275e840 100644 --- a/src/gtk1/win_gtk.c +++ b/src/gtk1/win_gtk.c @@ -228,7 +228,7 @@ gtk_myfixed_put (GtkMyFixed *myfixed, if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget)) gtk_widget_realize (widget); - if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget)) + if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget) && GTK_WIDGET_VISIBLE (widget)) gtk_widget_map (widget); if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))