I have been trying to implement a simple drag and drop application in Gtk 4 Rust but I am unable to implement a working version. I can see connect_accept getting triggered, but no matter the result, connect_drop is never triggered when I drag a file from Dolphin to the window. Is there somewhere a working version available?
use gtk::prelude::*; // <- includes Cast, WidgetExt, etc.
use gtk::{Application, ApplicationWindow, Label, DropTarget};
use gtk::glib::Type;
use gtk::gio::prelude::*;
use std::path::PathBuf;
use gtk::gdk::DragAction;
use gtk::glib::clone;
use gtk::glib;
fn main() {
let app = Application::builder()
.application_id("com.example.gtk4-dnd-file")
.build();
app.connect_activate(build_ui);
app.run();
}
fn build_ui(app: &Application) {
let label = Label::builder()
.label("Drag a file onto this window")
.margin_top(20)
.margin_bottom(20)
.margin_start(20)
.margin_end(20)
.build();
let window = ApplicationWindow::builder()
.application(app)
.title("GTK4 Drag & Drop (File)")
.default_width(400)
.default_height(200)
.child(&label)
.build();
let drop_target = DropTarget::new(gtk::gdk::FileList::static_type(), DragAction::COPY);
// Use accept to preview and asynchronously read the value type using read_value_future
let label_weak = label.downgrade();
drop_target.connect_accept(move |_target, drop| {
eprintln!(
"accept: actions = {:?}, formats = {:?}",
drop.actions(),
drop.formats()
);
true
});
//let drop_target = DropTarget::new(gtk::gdk::FileList::static_type(), gtk::gdk::DragAction::COPY);
let label_for_drop = label.clone();
drop_target.connect_drop(move |_target, value, _x, _y| {
println!("Drop target received value type: {:?}", value.type_());
label_for_drop.set_label("Drop did not contain a usable file.");
false
});
window.add_controller(drop_target);
window.show();
}