GtkGesture in a Rust app not working

Hi,
I am trying to monitor a gesture in a gtk-rs app and running into an issue getting any of the callbacks to run. Does anyone have an example where a GtkGesure is used in a Rust app? Below is the code that is not working. I am attempting to monitor both mouse and touch drags over a generic area. Am I missing something with how the GtkGesure classes are supposed to operate?

fn main() {
    let application = Application::new(Some("org.epic.overlay.dragtest"), Default::default())
        .expect("failed to initialize GTK application");
    application.connect_activate(|app| {
        let glade_src = include_str!("gest_test_layout.glade"); // glade set up
        let builder = gtk::Builder::from_string(glade_src); // builder set up
        let window: gtk::ApplicationWindow = builder.get_object("main_window").unwrap(); // main window upwrap from glade
        let area: gtk::DrawingArea = builder.get_object("drawing_area").unwrap();
        let area_drag_ges: gtk::GestureDrag = gtk::GestureDrag::new(&area);

        //back_image_long_p.set_propagation_phase(gtk::PropagationPhase::Bubble);
        //area_drag_ges.set_touch_only(false);

        area_drag_ges.connect_drag_begin(move |gest, x, y| {
            println!("X Begin {:?}", x);
            println!("Y Begin {:?}", y);
        });
        area_drag_ges.connect_drag_update(move |gest, x, y| {
            println!("X up {:?}", x);
            println!("Y up {:?}", y);
        });
        area_drag_ges.connect_drag_end(move |gest, x, y| {
            println!("X End {:?}", x);
            println!("Y End {:?}", y);
        });
        window.set_application(Some(app));
        window.show_all();
    });
    application.run(&args().collect::<Vec<_>>());
}

1 Like

You need to keep a reference to the gtk::GestureDrag—typically in the widget that uses it—otherwise they’ll just be dropped when the scope ends.

2 Likes

I am a little confused about how to accomplish this in Rust. I would think there is a cleaner option than going directly to the external function.

Create a struct that holds the window and the gesture instances, and then keep it around? I mean: how to structure a Rust code base is entirely up to you.

All you need to do is to ensure that objects exist outside of the inner scope of your callback.

That’s a very bad idea; that function is really just for C convenience, and should never be used by anything else.

Store the gesture somewhere in your application state next to other things you have to keep around.

Thank you for the help. As a quick fix I was able to just run the “gtk::main()” loop at the end of the closure to keep everything in scope.

No, please, that’s a terrible solution. You’re literally running a main loop inside another main loop. Don’t ever do that.

1 Like

I should have referred to it as a temporary dirty quick fix. I have always just used the glade builder object within the scope of the connect_activate callback. Would I want to declare the builder, window and widgets on the same level as the application and then just attach the window and show it within the callback?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.