Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
G
gtkmm
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 27
    • Issues 27
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 4
    • Merge Requests 4
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • GNOME
  • gtkmm
  • Issues
  • #60

Closed
Open
Opened Nov 20, 2019 by Daniel Boles@dbolesDeveloper

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 Bindings.

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 this Widget, and all I need from you is to stay around as long as it does, and then go away', without having to keep around a RefPtr<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 was Gestures created by a Builder, 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 to gtkmm?

#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.

Edited Nov 21, 2019 by Daniel Boles
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: GNOME/gtkmm#60