antoyo / relm

Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust
MIT License
2.42k stars 79 forks source link

Impossible to use event system with drag and drop. #228

Closed HackerWithoutACause closed 3 years ago

HackerWithoutACause commented 4 years ago

In GTK in order to use drag events and set data you must connect connect_drag_data_get and set the data using the SelectionData variable passed to the callback ex.

button.connect_drag_data_get(|_, _, s, _, _| {
        let data = "I'm data!";
        s.set_text(data);
});

The only problem is that SelectionData is passed as a reference meaning it would be impossible to pass it as a message, but it does implement the Clone trait however the cloned copy and not longer set the data to be returned so the following does not work:

button.connect_drag_data_get(|_, _, s, _, _| {
        let data = "I'm data!";
        s.clone().set_text(data);
});
antoyo commented 4 years ago

There are some cases like this in gtk that are not asynchronous, so the solution is unfortunately to use a Rc<Cell<T>> or Rc<RefCell<T>>.

Relm provides syntax sugar to clone a Rc<T> inside the event connection.

HackerWithoutACause commented 4 years ago

How do I convert a type of &SelectionData to Rc<RefCell<SelectionData>>? or are you saying to do something else?

antoyo commented 4 years ago

Oh, sorry, I was confused. You actually need to call the code like in your first post, that is, without the relm event system.

You can either do that in the init_view() method or when you receive a specific event in the update() method, depending on your use case. The Rc<RefCell<T>> might not be necessary if you don't need to access the model in the callback.

antoyo commented 3 years ago

Please reopen this issue if you still need help.