From 18a718fdd2239b6c3dc497f472a85c8612d0115c Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 29 Jun 2026 18:02:47 +0900 Subject: fix: poll drag-and-drop in the main loop (drop events were never read) Root cause: the file-drop check was a flecs system registered with with: [] (zero terms). In this flecs build a zero-term system never iterates its block, so Rl.file_dropped? was never polled and dropped files were silently ignored -- the SDL backend was receiving the Xdnd events fine all along. Moved the IsFileDropped()/LoadDroppedFiles() check into the main loop (before world.progress, so the LoadSystem picks up the file the same frame), matching the original C study-player. Verified end-to-end with a synthetic Xdnd drop: file detected -> loaded as a music stream. --- game/study_player/study_player.rb | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/game/study_player/study_player.rb b/game/study_player/study_player.rb index 82d0606..8b6997b 100644 --- a/game/study_player/study_player.rb +++ b/game/study_player/study_player.rb @@ -1474,21 +1474,11 @@ module StudyPlayer UpdateSystem.build(world, player_entity, runtime, pb) StudySystem.build(world, player_entity, runtime, pb, ss) - # --- File drop check system (drag-and-drop fallback) --- - world.system("CheckFileDrop", with: [], phase: Flecs::PRE_UPDATE) do - if Rl.file_dropped? - files = Rl.load_dropped_files - if files && files.count > 0 - path = files.path_at(0) - if path && !path.empty? - ent = player_entity - ent.set(af, { path: path, duration: 0.0 }) - ent.add(nl) - end - end - Rl.unload_dropped_files(files) - end - end + # NOTE: File-drop polling happens in the main loop below (not a flecs + # system). A system registered with `with: []` (zero terms) never iterates + # its block in this flecs build, so Rl.file_dropped? was never polled and + # drag-and-drop silently did nothing. The original C app polls + # IsFileDropped() directly in its main loop — same pattern here. # --- Audio file from ARGV (Phase 2: opens straight into player view) --- audio_arg = nil @@ -1522,6 +1512,22 @@ module StudyPlayer runtime.settings_visible = !runtime.settings_visible end + # --- Drag-and-drop file loading (polled in the main loop) --- + # Done before world.progress so the LoadSystem (PRE_UPDATE) picks up the + # new file in the same frame. + if Rl.file_dropped? + files = Rl.load_dropped_files + if files && files.count > 0 + path = files.path_at(0) + if path && !path.empty? + player_entity.set(af, { path: path, duration: 0.0 }) + player_entity.add(nl) + puts "[drag-drop] loading: #{path}" + end + end + Rl.unload_dropped_files(files) + end + # Run ECS systems (keyboard input, seek, update, study) world.progress(dt) -- cgit v1.2.3