Search code examples
rustgtkgtk-rsgtk4

How do I use mouse button events with gtk4-rs?


I'm trying to capture up a right click event on a TreeView I have in my application using Rust and gtk4-rs. I don't see a specific EventController for mouse buttons events. I do see EventControllers for things like keyboard presses and motion events. I ended up using the EventControllerLegacy and just detecting the event type inside the closure, but I feel like I'm missing something here. Is there some other way I should be getting button press events from the mouse? Here's my code:

pub fn build_tree_view() -> TreeView {
    let tree_view: TreeView = TreeView::new();
    tree_view.set_headers_visible(false);
    let event_controller = EventControllerLegacy::new();
    event_controller.connect_event(|controller, event| {
        if event.event_type() == ButtonPress {
            let button_event = event.clone().downcast::<ButtonEvent>().unwrap();
            if button_event.button() == GDK_BUTTON_SECONDARY as u32 {
                println!("got mouse button: {}", button_event.button());
            }

        }
        return Inhibit(false);
    });
    tree_view.add_controller(&event_controller);
    return tree_view;
}

The reason I believe I am missing something is that the documentation for EventControllerLegacy states the following:

EventControllerLegacy is an event controller that provides raw access to the event stream. It should only be used as a last resort if none of the other event controllers or gestures do the job.

I am using Rust 1.56.0 and gtk4-rs 0.4.2

Thanks


Solution

  • If you look into the examples, normally in such a case gtk::GestureClick is used. To detect right clicks, you can use it like so:

    pub fn build_tree_view() -> TreeView {
        let tree_view: TreeView = TreeView::new();
        tree_view.set_headers_visible(false);
    
        // Create a click gesture
        let gesture = gtk::GestureClick::new();
    
        // Set the gestures button to the right mouse button (=3)
        gesture.set_button(gtk::gdk::ffi::GDK_BUTTON_SECONDARY as u32);
    
        // Assign your handler to an event of the gesture (e.g. the `pressed` event)
        gesture.connect_pressed(|gesture, _, _, _| {
            gesture.set_state(gtk::EventSequenceState::Claimed);
            println!("TreeView: Right mouse button pressed!");
        });
    
        // Assign the gesture to the treeview
        tree_view.add_controller(&gesture);
        return tree_view;
    }
    

    Note: Example is for Rust 1.58 and gtk4 0.4.4 but the differences should be minor if any.