I am trying to add action “Copy image to clipboard” into popup menu on Picture. Although I understand all the pieces (PopoverMenu, MenuModel, actions and clipboard.set_texture), I have trouble to put it all together.
My idea was to pass the image in some form (e. g. Texture) to SimpleAction as a parameter. However, the type of the parameter is required to be convertible into Variant, which none of the image-related types is. Workaround here would be to convert to PNG and into raw bytes and then make Texture out of it again but that sounds like enormous wasting.
Eye of GNOME passes the image to the action inside generic user_data (see eog-window.c). However, in gtk-rs the user_data is not used (see SimpleAction::connect_activate). All the other examples I found perform the clipboard.set_texture as a reaction to pressing a button. But none of them via an action.
Besides passing image via user_data, how could this be achieved?
Hello, the user_data is unnecessary in rust because you can pass arbitrary captured data into any closure you bind to the signal. If this is an unfamiliar pattern to you (or any other readers) about gtk-rs then I suggest reading up on the clone macro.
Popover menus are a bit more complicated though: you just have to make sure that if you clone the texture into the closure, then each time you change the picture, you also unbind and rebind the signal every time the popover is created, because the image will be out-of-date with the underlying widget. Or you can just pass a weak reference to the GtkPicture into the activate signal and then get the texture that way, so you don’t have to rebind the signal. That would probably be the most similar to how EOG does it by passing the window as user_data and getting the current image from there.
(Internally, this is actually implemented by the Rust bindings using the user_data parameter as a pointer to a Box<Fn(...)> that gets called later)
Hello, Jason, and thank you for the response, which pointed me at the right direction.
My mistake was trying to make the action more global (e. g. in win group). In that case, I would have to pass the texture to the action via parameter. However, if I create the action in an action group picture (created fresh for each picture), I can pass the texture via closure, as you suggested.