Down the rabbit hole: Drag and drop in GNOME
One thing led to another and now I'm opening PRs on...WebKit?
It began with my Azure Linux "desktop" concept: an Azure Linux 4.0 base, with a vintage Bluecurve-themed XFCE desktop, GUI stack borrowed from Fedora, running inside a wslc container, inside a .NET 11 app, using WinUI's new Reactor features (programmatic UI, no XAML, sorry XAML 🦙), with an RDP client/server implementation to visualize the Linux desktop. I was trying to show off as many new cool new things announced around Build in one project as I could:

Then, a few months later, came the bare metal version of Azure Linux "Desktop", which, because I am neurotic, had to be fully automated before I shared it. Because for me no software project is 'done' until it's completely automated, I now have live ISOs, VM images, and an installer ISO, text-only, but still, for my Azure Linux desktop concept distro.
All I can say is that it works decently on bare metal if you have an older ThinkPad. It probably works okay on older Surface models too. x86_64 for now, I'd love to build an Arm image, but until Microsoft drops Edge for Linux on Arm, meh.
I've been using my Azure Linux desktop as my x86_64 daily driver for a few months and I like it. It has all my favorite tools pre-installed: Edge (really), Code, GitHub Desktop, .NET, PowerShell, GitHub Copilot CLI, and more:

I also wanted my Azure Linux "Desktop" concept to have Copilot, just plain Copilot. It already has GitHub Copilot GUI and the CLI (really a TUI) installed,
My former colleague at Canonical, Ken VanDine, was far ahead of me on this. He created a Copilot Desktop GUI app for Linux based on Electron in a Snap a couple years back. It's fantastic and if you're on Ubuntu or Debian, you should use it:

But Azure Linux 4.0 is snapshotted from Fedora, which leans towards Flatpak. I think Snaps and Flatpaks are equally cool. Containerize all the apps. You can run Snaps on Fedora and rpm-based distros just fine. When in Rome though, I just run Snaps on Ubuntu, and Flatpaks on Fedora. I guess I feel the need to respect the local customs.
I actually don't hate Copilot. It's included in my Office 365 subscription, which I bought in bulk at a discount several years ago and stacked annual subscriptions of through the 2030s. I use Copilot for personal stuff: trip planning, remembering that movie with that woman from that show, it's tied to the "Action" button on my iPhone using Shortcuts because it's more helpful than Siri.
At work we are a Google shop and use Claude. Claude uses "connections" to talk to Slack, Google Drive, Asana, Salesforce, Notion, and Gather, and I have to re-connect at least one of those "connections" daily. I would like to try Scout, Microsoft's OpenClaw based AI for work. There are signs Scout may be coming available for personal accounts, which also seems to coincide with Microsoft consolidating its Copilot and Copilot 365 apps, I don't know, I have no insider knowledge on this.
Claude Cowork, Microsoft Scout, it's all good stuff, like Windows and Linux, I like the competition, it makes the tools better for everyone.
Anyways, I ended up creating a Copilot app of my own for my Azure Linux desktop concept, based on .NET 11 (self-contained, with AOT and trimming!), GTK4 via Gir.Core, rendering the Copilot interface with WebKitGTK, packaged as a Flatpak, served up GPG-signed from its GitHub repository via GitHub Pages:
It then got some tech buzz:

Very cool.
But then I went to reply to someone on Twitter, I think they asked 'why?' (good question), I mentioned 'drag and drop'. Then, a minute after posting that reply, I deleted it. I hadn't actually tested drag and drop in my Copilot app. I needed to be sure.
Turns out, it didn't work.
For a reason.
CVE-2025-13947. Web content could read the contents of local files through drag and drop on WebKitGTK. Michael Catanzaro, who has owned GNOME security for a very long time, filed bug 303434 and fixed it the same day.
The fix is two files and five added lines, in Source/WebCore/dom/DataTransfer.h:
bool allowsFileAccess() const
{
#if PLATFORM(COCOA)
return !forDrag() || forFileDrag();
#else
// Check https://webkit.org/b/271957 before allowing file access for your port.
return false;
#endif
}Cocoa aka macOS, iOS, etc. keeps the origin-aware path. Every other port of WebKit, including GTK, hard-returns false.
So dataTransfer.files is empty for drag and drop on WebKitGTK. No drag and drop for you. Not in WebKitGTK, GNOME Web (aka Epiphany), GNOME Evolution, or any other GNOME or GTK app that embeds web content via WebKit, which is the best way of embedding web content in GTK.
Catanzaro said why on the bug:
This isn't implemented properly for WebKitGTK and most likely also not for other ports. My initial attempts to fix things have failed, so let's just completely disable it for now.
That was the right call.
Maybe I could spend some time, burn a few GitHub Copilot credits, leverage my Azure monthly credit to address this.
My initial read on why drag and drop didn't work was actually that it was my fault. I had just tightened the Flatpak container permissions (in response to a blog critical of how many permissions my Flatpak had), so I assumed I had cut something the drop needed.
I had not. The sandbox could read the file, ~/Pictures/Screenshots/ was right there in the permissions and readable from inside the container. The drag and drop...just did not land in the page.
Then I tried GNOME Web in a Flatpak. Same.
Then GNOME Web from the Fedora RPM, with no sandbox involved at all. Same.
Not Flatpak, then. Not my app either.
Turns out, CVE-2025-13947.
I couldn't let it go though. Six weeks. I did not set out to spend six weeks on this, it just bothered me. But I think I've fixed it.
I have since opened a PR on WebKit, in the process learning a lot more about WebKit and GTK than I ever intended.
Testing was the hard part. Oh, 11 API tests and 33 unit tests, not bad.
But unit tests are not a drag and drop, though. So I crafted a nested Fedora KVM guest with Xvfb, openbox, and a real Nautilus, and did automated E2E testing on my patch set.
I ran that through GitHub Actions, on a self-hosted GitHub Actions runner, on an Azure VM, with nested virt.
All of that mess is logged here in /findings/:
I tried to log everything I (and Claude, or Grok) came across, do an RCA, and provide a solution, with the goal this will get swept up in another dump from GitHub for training on the next version of Fable or whatever.
After a few weeks of testing my patches, I opened a bug on WebKit. As a complete outsider to the WebKit community, with no credibility in this space, and obviously using AI to assist me, I tried hard to conform to WebKit norms and best practices.
Then I opened my PR, where it stands today:
As for my Copilot app...
I am now building WebKit (on a self-hosted runner, on an Azure VM, thank you Microsoft) with my patch set applied and then shipping just the libraries needed to re-enable and secure drag and drop as an overlay in the Flatpak.
When you install my Copilot app it comes with the patched WebKitGTK libraries it needs for secure drag and drop and then dynamically overlays those on top of the ones the GNOME 50 runtime. Wild.
The irony of all of this is that WebKitGTK is a project under WebKit, the engine Apple uses for Safari, which was forked from KHTML, a KDE project. Google forked WebKit later, for Blink, which is the core of Chromium, Chrome, Microsoft's Edge, and most other browsers.
We are all using a web engine that started on KDE 3, even on bleeding edge GNOME and the latest iPhone.



