From c9d7ba3171c91ae21b9396036a87e63b70c5c032 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 May 2021 12:29:07 +0200 Subject: [PATCH] Fix key events for native GTK controls such as wxDataViewCtrl Connect to key-{press,release}-event on the "focus widget" rather than the main widget, to ensure that we get them before the native control does and so can generate the key events even for the keys handled by the control internally. This allows to get events for the arrow keys in wxDataViewCtrl, for example, while previously these keys were consumed by the control itself, as could be seen with the following patch to the sample ---------------------------------- >8 -------------------------------------- diff --git a/samples/treelist/treelist.cpp b/samples/treelist/treelist.cpp index af6905cecb..74894cc9a9 100644 --- a/samples/treelist/treelist.cpp +++ b/samples/treelist/treelist.cpp @@ -349,6 +349,10 @@ bool MyApp::OnInit() sizer->Add(textLog, wxSizerFlags(1).Expand()); SetSizer(sizer); + m_treelist->GetView()->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& e) { + wxLogMessage("Key in tree: %d", e.GetKeyCode()); + e.Skip(); + }); // Finally show everything. Show(); ---------------------------------- >8 -------------------------------------- Pressing arrow keys didn't generate the expected message before (unless the focus was on the control header and not on the main area itself). This may fix similar issues with other controls setting m_focusWidget as well. --- src/gtk/window.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index d7b2e964af..d891c96423 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -3692,10 +3692,18 @@ void wxWindowGTK::ConnectWidget( GtkWidget *widget ) g_source_unref(source); } - g_signal_connect (widget, "key_press_event", + // When we're called for the main widget itself (but not when connecting + // events for some other widget, such as individual radio buttons in + // wxRadioBox::Create()), connect to m_focusWidget for the keyboard events + // instead, as it should be used for everything keyboard input-related. + GtkWidget* const focusWidget = widget == m_widget && m_focusWidget + ? m_focusWidget + : widget; + g_signal_connect (focusWidget, "key_press_event", G_CALLBACK (gtk_window_key_press_callback), this); - g_signal_connect (widget, "key_release_event", + g_signal_connect (focusWidget, "key_release_event", G_CALLBACK (gtk_window_key_release_callback), this); + g_signal_connect (widget, "button_press_event", G_CALLBACK (gtk_window_button_press_callback), this); g_signal_connect (widget, "button_release_event",