Gestures require RefPtrs to stay alive / cannot be managed by their Widgets
I propose to override manage()
for Gtk::Gesture
and subclasses - and perhaps also other Gtk::EventController
subclasses. This would exist to tell gtkmm
we should not need to keep a RefPtr
to a gesture, but instead its Widget
should manage its lifetime. Often, a RefPtr<Gesture>
is massively uninteresting once you have set its properties and connected to its signals, and having to keep such a pointer around just means more code (and names used up) for no benefit.
Kjell says this is only applicable to gtkmm-3
, and since we can't add a member m_managed
there to affect how we ref in the implementation, I guess it needs to be done via qdata
as Kjell suggested at the related issue for manage()
ing Binding
s.
discussion and minimal reproducer from glibmm!21 (closed):
me:
I think the same would be needed for
Gtk::Gesture
, as ideally it would be good to be able to say 'you are a gesture for thisWidget
, and all I need from you is to stay around as long as it does, and then go away', without having to keep around aRefPtr<Gesture>
to keep it alive. I don't know if this is so easy though, as I don't know if there's the same kind of trickery going on at the C level to make this kind of lifetime work. For now I'll have to maintain a map of refs anyway
Kjell:
Gtk::Gesture
is handled differently. There is no special ref/unref tricks in EventController (base class of Gesture) or Gesture. Gtk::Widget::set_controller() adds a ref to the controller, because gtk_widget_add_controller does not do that. Doesn't this result in exactly the behaviour you want? The gesture exists until all RefPtrs are deleted and it's removed from the widget (when the widget is deleted). Have you seen that this is not what happens?
me:
That is not what happens. I've been through this already and concluded I must keep
RefPtrs
. That wasGesture
s created by aBuilder
, but it doesn't matter. Here's a demo. The gesture does not work (i.e. no signal on long-press) unless the (leaky)gesture->reference()
is taken. Should I move togtkmm
?#include <gtkmm/application.h> #include <gtkmm/button.h> #include <gtkmm/gesturelongpress.h> #include <gtkmm/window.h> namespace { void on_long_pressed(Gtk::Button& button) { button.get_style_context()->add_class(GTK_STYLE_CLASS_SUGGESTED_ACTION); } void on_activate(Glib::RefPtr<Gtk::Application> const& application) { auto& button = *Gtk::make_managed<Gtk::Button>("long-press me..."); auto const gesture = Gtk::GestureLongPress::create(button); gesture->signal_pressed().connect( [&](double, double){ on_long_pressed(button); } ); #if 0 gesture->reference(); #endif auto window = new Gtk::Window{}; window->add(button); window->show_all(); application->add_window(*window); } } // namespace auto main() -> int { auto const application = Gtk::Application::create("org.djb.test"); application->signal_activate().connect( [=]{ on_activate(application); } ); return application->run(); }
Kjell:
Yes, please. Open a gtkmm issue for Gtk::Gesture. I see now that my comment is valid only for gtkmm-4. It works differently in gtkmm-3 and gtk+-3.