Skip to content

Route direct file drops through the runtime's QMP event - #133

Closed
btsouth wants to merge 1 commit into
masterfrom
fix/vm-window-file-drops
Closed

btsouth wants to merge 1 commit into
masterfrom
fix/vm-window-file-drops

Conversation

@btsouth

@btsouth btsouth commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Direct file drops onto the VM window never reached the launcher.

app/file_drop_qemu_windows.go accepted drops with DragAcceptFiles and then tried SetWindowSubclass on QEMU's SDL window to see WM_DROPFILES. QEMU runs in another process, and Windows does not allow subclassing a window across processes: SetWindowSubclass rewrites GWLP_WNDPROC, and a window-procedure pointer is only valid in the process that owns the window. The subclass therefore never ran, and WM_DROPFILES went to SDL, which turns it into SDL_DROPFILE, which QEMU ignored. DragAcceptFiles only sets WS_EX_ACCEPTFILES (a style bit that can be set across processes), which is why it looked enabled and logged success.

The runtime already covers this: runtime-build/patches/qemu/0007-report-native-file-drops.patch emits a DISPLAY_FILE_DROP QMP event that main.go already consumes. This change makes that the only path.

Changes

  • Remove the cross-process subclass path (enableVMWindowDrops, vmDropWindowProc, handleVMDrop, dragQueryPoint) and its calls in winapi.go and closeguard.go.
  • droppedFilesEvent now also reads an optional drop point (x, y) from the event.
  • guestDropPoint scales a display-window point to the guest display; when the event carries no point it uses the cursor, which is still over the release point while QEMU reports the completed drop.
  • main.go hands the mapped point to sendDroppedFilesAt, so the guest can deliver into the window under the cursor (guest-side targeting is guest-build/0073).

Notes

  • This needs a runtime built with 0007. The shipped winq-emu-alpha10-portable.zip has it; the older C:\WINQ-EMU runtime used in the last laptop pass did not, which is why drops did nothing there.
  • Optional follow-up: have 0007 include SDL's drop.x/drop.y in the event so the point is authoritative rather than taken from the cursor. SDL_DropEvent has carried x/y since SDL 2.0.14 and the runtime ships 2.32.

Test plan

  • go test ./... (CI: Linux and Windows)
  • Windows: drag a file onto the VM window with a runtime that has 0007; the guest should receive it in the window under the cursor and shell.log should stay free of the old drops: lines.

The launcher tried to see WM_DROPFILES on QEMU's SDL window with DragAcceptFiles plus SetWindowSubclass. QEMU runs in another process, and Windows does not allow subclassing a window across processes (the subclass procedure pointer would only be valid in the caller's address space), so the subclass never fired and drops were silently lost. DragAcceptFiles only set WS_EX_ACCEPTFILES, which is why it looked registered.

The WINQ-EMU runtime already reports drops as the DISPLAY_FILE_DROP QMP event, which main.go consumes. Drop the dead subclass path, and map the reported drop point (or, when the runtime does not send one, the cursor that is still on the release point) from display-window coordinates to the guest display so the guest can deliver into the window under the cursor.
@btsouth

btsouth commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks. The QMP drop path landed in #137, including the drop-point handling. Closing as superseded.

@btsouth btsouth closed this Sep 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant