Skip to content

fe-gtk: make image drag-and-drop upload work on Windows - #10

Open
rubinlinux wants to merge 2 commits into
masterfrom
fix/win32-image-drop
Open

fe-gtk: make image drag-and-drop upload work on Windows#10
rubinlinux wants to merge 2 commits into
masterfrom
fix/win32-image-drop

Conversation

@rubinlinux

@rubinlinux rubinlinux commented Aug 24, 2026

Copy link
Copy Markdown
Member

Summary

Image sharing into the input box (upload → insert link) never worked on Windows, in either of its two entry points. This PR fixes both, plus a cross-platform gap in the paste path.

Commit 1: drag and drop

Dragging an image file from Explorer onto the input box never engaged, for two independent reasons:

  1. The drop target never matched. Explorer drags (CF_HDROP) are offered by GDK as a GdkFileList, but the input-box target was typed { GDK_TYPE_TEXTURE, G_TYPE_FILE } only. Same GTK4-rewrite gap that 1e8d217 fixed for the DCC drop targets; the image-upload target was missed.
  2. Image detection would have failed anyway. The handler tested the raw GIO content type for an image/ prefix, but Win32 GIO content types are registry extension strings (.png, not image/png).

Fixes: accept GDK_TYPE_FILE_LIST on the target (multi-file drops upload each image); new mg_file_is_image() resolves the type via g_content_type_get_mime_type() with a known-extension fallback (the registry often has no Content Type for e.g. .webp); per-file work factored into mg_input_upload_image_file().

Commit 2: clipboard paste

Verified against GDK internals (4.14 and current): screenshot paste already works on Windowsgdk_clipboard_claim() augments remote formats with deserializable GTypes, and the win32 backend maps CF_DIB/"PNG"/"JFIF" to image mime types, so the existing GDK_TYPE_TEXTURE check fires. (Runtime requirement — gdk-pixbuf loaders — is satisfied: gvsbuild builds gdk-pixbuf with -Dbuiltin_loaders=all, GTK 4.22.4 as of gvsbuild 2026.8.0.)

What didn't work on any platform was Ctrl+C on an image file (Explorer / Linux file manager) then Ctrl+V in the input box: those clipboards hold a file list (Explorer's CFSTR_SHELLIDLIST → GDK transmutes to text/uri-listGdkFileList), and do_paste() only knew texture-or-text.

Fixes: do_paste() gains a file-list branch (priority: texture → file list → text) emitting a new "file-paste" signal on HexInputEdit; maingui's handler uploads image files via the same mg_input_upload_image_file() path. If none of the pasted files are images, the widget falls back to the old text paste, so copying a non-image file still pastes its path where the source offers a text form.

Testing

  • Both files compile clean (-fsyntax-only -Wall -Wextra) against GTK 4.14 on Linux; no new warnings.
  • Needs manual verification on a Windows build:
    • Drag a .png/.jpg/.webp from Explorer onto the input box → [uploading image…] placeholder → link.
    • Win+Shift+S screenshot → Ctrl+V in the input box → upload (pre-existing path, now confirmed reachable on win32).
    • Ctrl+C an image file in Explorer → Ctrl+V in the input box → upload.
    • Ctrl+C a non-image file → Ctrl+V → falls back to text paste (or nothing), no upload.

🤖 Generated with Claude Code

Dropping an image file onto the input box to upload it never worked on
Windows, for two independent reasons:

1. Explorer drags (CF_HDROP) are offered by GDK as a GdkFileList, but
   the input-box drop target was typed { GDK_TYPE_TEXTURE, G_TYPE_FILE }
   only, so the offer never matched and the shell saw no drop target at
   all.  This is the same gap 1e8d217 closed for the DCC file-drop
   targets; the image-upload target was missed.

2. Even with a matching offer, the "is this an image?" test compared the
   raw GIO content type against an "image/" prefix.  Win32 GIO content
   types are registry extension strings (".png"), not MIME types, so the
   test could never pass on Windows.

Accept GDK_TYPE_FILE_LIST on the target and iterate it (multi-file
drops upload each image).  Resolve the content type through
g_content_type_get_mime_type() before the "image/" test, and fall back
to a known-extension check since the Windows registry frequently has no
"Content Type" for newer formats such as .webp.  The per-file load and
upload is factored into mg_input_upload_image_file() shared by the list
and single-GFile paths; Linux behaviour is unchanged.
Pasting a screenshot (a bitmap on the clipboard) already worked: GDK
augments remote clipboard formats with deserializable GTypes, and the
win32 backend maps CF_DIB / "PNG" / "JFIF" to image mime types, so the
existing GDK_TYPE_TEXTURE check in do_paste() fires on Windows too.

What did not work -- on any platform -- was copying an image *file*
(Explorer or a Linux file manager, Ctrl+C) and pasting it into the
input box.  Those clipboards hold a file list, not a bitmap: Explorer
copies arrive as CFSTR_SHELLIDLIST, which GDK transmutes to
text/uri-list and deserializes to a GdkFileList; Linux file managers
offer text/uri-list directly.  do_paste() only knew texture-or-text,
so the paste degraded to text (or nothing).

Add a file-list branch to do_paste(): when uploading is enabled and
the clipboard offers GDK_TYPE_FILE_LIST, read it and emit the new
"file-paste" signal.  maingui's handler uploads each image file via
the same mg_input_upload_image_file() path the drop target uses and
returns whether it uploaded anything; when it didn't (no images among
the copied files), the widget falls back to the old text paste, so
copying a non-image file still pastes its path wherever the source
app offers a text form.
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