3.6 KiB
Fix: Drag & drop MIDI file từ Explorer vào track (Windows/Tauri)
Ngày: 2026-08-15 Phạm vi: chỉ ghi đề xuất, chưa sửa code. Pull về Windows rồi sửa.
Triệu chứng
Trên Windows (bản Tauri), kéo file .mid từ Explorer vào timeline:
- Không tạo track, không toast, không console error.
Nguyên nhân gốc
- Tauri default bật
drag_drop_handler_enabled = true; app không gọidisable_drag_drop_handler().tauri-2.11.1/src/webview/mod.rs:973-977— doc ghi rõ: "Disables the drag and drop handler. This is required to use HTML5 drag and drop APIs on the frontend on Windows."
- Khi handler bật,
tauri-runtime-wrybắt sự kiện drop và emitDragDropEventsang Rust (tauri-runtime-wry-2.11.1/src/lib.rs:4861), không đẩy vào DOM. wry-0.55.1/src/webview2/mod.rs:150-155— khi có drag_drop_handler thì gọiSetAllowExternalDrop(false)(comment: "Disable file drops, so our handler can capture it").- Kết quả: drop file OS vào WebView2 → HTML5 DnD không hoạt động →
e.dataTransfer.filesrỗng tạiapp/static/js/app.jsx:29994và:30034→if (!f) return;→ im lặng. - App không xử lý
WindowEvent::DragDropở Rust, không càitauri-plugin-drag-drop→ drop OS file bị nuốt hoàn toàn.
Đã verify
- Logic JS drop đúng: chạy engine + headless chromium, dispatch drop event với
DataTransfer chứa
/static/midi/MIDI_Loop_01.mid→ tạo track + toast "Đã tải MIDI: 1 track(s)" (ROWS 1→2).parseMidiFileOK (1 item, 48 notes). - Drop từ Media Explorer trong app (dùng
window.__mediaExplorerDragFile+resolveMediaExplorerDropFile, app.jsx:24629, 15029) KHÔNG dùngdataTransfer.files→ không bị ảnh hưởng bởiSetAllowExternalDrop(false), vẫn hoạt động trên Windows. - Drop trong browser thường (Linux dev): hoạt động.
- Section-tab/sub-tab timeline (~app.jsx:30600): KHÔNG có onDrop — drop vào section tab không làm gì (bug phụ; wiki.md:1806 tuyên bố hỗ trợ nhưng code không có).
Đề xuất sửa (chọn 1 trong 2; làm trên Windows)
Phương án A — Bật HTML5 DnD (đơn giản nhất)
Gọi disable_drag_drop_handler() khi tạo cửa sổ trong code Rust
(ví dụ src-tauri/src/lib.rs, trong builder WebviewWindow). Không có option
trong tauri.conf.json — phải sửa code.
Sau khi gọi, WebView2 nhận drop như browser bình thường, JS handler tại
app.jsx:29980 (container) và :30024 (track row) tự chạy, không đổi JS.
Lưu ý: mất event WindowEvent::DragDrop ở Rust (hiện không dùng).
Phương án B — Xử lý ở Rust, đẩy path sang JS
Giữ drag_drop_handler default, thêm .on_window_event (hoặc dùng
tauri-plugin-drag-drop) lắng nghe WindowEvent::DragDrop(DragDropEvent::Drop(path)),
emit path sang frontend (vd emit("midi-drop", path)), JS nhận và chạy nhánh
giống resolveMediaExplorerDropFile (dùng mef.path).
Phức tạp hơn A, cần thêm listener + code JS.
Bug phụ (nếu muốn sửa luôn)
Thêm onDrop cho section-tab/sub-tab timeline (~app.jsx:30600) giống handler
container/track row, để drop vào section tab cũng tạo track.
Vị trí file liên quan
app/static/js/app.jsx:29980(onDrop container),:30024(onDrop track row)app/static/js/app.jsx:29994,:30034(điểmdataTransfer.files[0]check)app/static/js/app.jsx:24629resolveMediaExplorerDropFilesrc-tauri/src/lib.rs(nơi cần gọidisable_drag_drop_handler())