Fix handling of identical consecutive key events
Events generated programmatically may have the same timestamp as the previous event, which caused them to be ignored on the assumption that they were the same event being sent to a parent window. Fix this by detecting when a new event could be generated by the event loop. Closes #15802 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@77074 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -929,10 +929,13 @@ void AdjustCharEventKeyCodes(wxKeyEvent& event)
|
||||
// navigation will work.
|
||||
#define wxPROCESS_EVENT_ONCE(EventType, event) \
|
||||
static EventType eventPrev; \
|
||||
if (memcmp(&eventPrev, event, sizeof(EventType)) == 0) \
|
||||
if (!gs_isNewEvent && memcmp(&eventPrev, event, sizeof(EventType)) == 0) \
|
||||
return false; \
|
||||
gs_isNewEvent = false; \
|
||||
eventPrev = *event
|
||||
|
||||
static bool gs_isNewEvent;
|
||||
|
||||
extern "C" {
|
||||
static gboolean
|
||||
gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
|
||||
@@ -2694,8 +2697,44 @@ wxWindowGTK::GTKConnectWidget(const char *signal, wxGTKCallback callback)
|
||||
return g_signal_connect(m_widget, signal, callback, this);
|
||||
}
|
||||
|
||||
// GSource callback functions for source used to detect new GDK events
|
||||
extern "C" {
|
||||
static gboolean source_prepare(GSource*, int*)
|
||||
{
|
||||
return !gs_isNewEvent;
|
||||
}
|
||||
|
||||
static gboolean source_check(GSource*)
|
||||
{
|
||||
// 'check' will only be called if 'prepare' returned false
|
||||
return false;
|
||||
}
|
||||
|
||||
static gboolean source_dispatch(GSource*, GSourceFunc, void*)
|
||||
{
|
||||
gs_isNewEvent = true;
|
||||
// don't remove this source
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void wxWindowGTK::ConnectWidget( GtkWidget *widget )
|
||||
{
|
||||
static bool isSourceAttached;
|
||||
if (!isSourceAttached)
|
||||
{
|
||||
// attach GSource to detect new GDK events
|
||||
isSourceAttached = true;
|
||||
static GSourceFuncs funcs = {
|
||||
source_prepare, source_check, source_dispatch,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
GSource* source = g_source_new(&funcs, sizeof(GSource));
|
||||
// priority slightly higher than GDK_PRIORITY_EVENTS
|
||||
g_source_set_priority(source, GDK_PRIORITY_EVENTS - 1);
|
||||
g_source_attach(source, NULL);
|
||||
}
|
||||
|
||||
g_signal_connect (widget, "key_press_event",
|
||||
G_CALLBACK (gtk_window_key_press_callback), this);
|
||||
g_signal_connect (widget, "key_release_event",
|
||||
|
Reference in New Issue
Block a user