GNOME Bugzilla – Bug 156259
Document that GtkSpinButton "key_release_event" handler prevents further handling.
Last modified: 2014-03-24 03:01:21 UTC
The attached C++ file reproduces the bug, at least on my Gentoo system with gtkmm-2.4.5. The expected behaviour would be to get both a key press and key release event. You can get that by commenting out the line that adds the spin button. If you leave in the spin button, the handling function for the key release event never gets called. ******** #include <gtkmm.h> #include <iostream> #include <sigc++/object_slot.h> class Test : public SigC::Object{ public: Gtk::Window *window; bool on_key_press(GdkEventKey *event){ std::cout << "In on_key_press: event->keyval = " << event->keyval << std::endl; } bool on_key_release(GdkEventKey *event){ std::cout << "In on_key_release: event->keyval = " << event->keyval << std::endl; } Test(){ window = new Gtk::Window(); window->signal_key_press_event().connect(sigc::mem_fun(*this, &Test::on_key_press)); window->signal_key_release_event().connect(sigc::mem_fun(*this, &Test::on_key_release)); Gtk::Adjustment *p_ad = new Gtk::Adjustment(100, 0, 100, 1, 10, 0.0); Gtk::SpinButton *p_spin = new Gtk::SpinButton(*Gtk::manage(p_ad), 1.0, 0); Gtk::VBox *p_box = new Gtk::VBox(); p_box->pack_start(*Gtk::manage(p_spin), Gtk::PACK_SHRINK); window->add(*Gtk::manage(p_box)); window->show_all(); } ~Test(){ delete window; } }; int main(int argc, char *argv[]) { Gtk::Main m(argc, argv); Test test; m.run(*test.window); return 0; }
Created attachment 33013 [details] Code demo of the bug
Bug confirmed on gtkmm-2.4.5 built against gtk+ 2.4.13 on Fedora Core 3 rc1.
In your example, your signal handlers do not return values. I recommend using warnings-as-errors when compiling. You might also want to investigate connect_before(). Please reopen this if this is still a bug.
Created attachment 33023 [details] cleaned up code demo of the bug While it compiles without warnings now, it still shows the bug
When connect()ing with the value of "after" set to true, the bug still shows, when the value is set to false, everything works. The same behaviour is reproduceable with connect_notify() with the value of after set to true and the handler switched to a void return type. To me, this looks like the default handler is the culprit.
Please provide an updated test case.
Created attachment 33045 [details] test case using connect_notify() instead of connect I hope this is what you wanted. Same code as #33023, this time using connect_notify() instead of connect(). If connect_notify() is set up to connect after the default handler, the same beahviour is displayed.
The whole point of connect_notify is that it calls your handler _before_ the default handler. There isn't much point in using it if you pass true to it. If you want to call the default handler before your signal handler then call the default handler at the start of your signal handler. I guess that you would then want to prevent the default handler from running, so you would return true, which would involve using connect(the_slot, false /* after=false */). Yes, handling of X events in GTK+ is annoying. This page might be helpful, but maybe it should make more suggestions: http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/apbs06.html Does this help?
That's actually not why I'm reporting the problem. I just think it doesn't make sense that the key_pressed and key_released signals behave differently if they're connected after the default handler, and the two test cases I submitted were designed to show this weird behaviour. If this is the desired way for signals to behave, perhaps it should be documented why key_press is different from key_release.
Yes the default handlers often return true to prevent further signal handlers from being called. Yes, whether they do this or not is probably not well documented. If it concerns you then you might start the documentation by listing the X event signal handlers in the various widgets, in a table with a column saying whether they allow further handling. But this is a GTK+ issue, so I'm reassigning it.
closing out ancient bugs