diff --git a/ui/goose2/src/app/App.test.tsx b/ui/goose2/src/app/App.test.tsx
new file mode 100644
index 0000000000..a1e88ecb89
--- /dev/null
+++ b/ui/goose2/src/app/App.test.tsx
@@ -0,0 +1,39 @@
+import { render } from "@testing-library/react";
+import { afterEach, describe, expect, it, vi } from "vitest";
+
+import { App } from "./App";
+
+vi.mock("@/app/AppShell", () => ({
+ AppShell: () =>
,
+}));
+
+describe("App", () => {
+ afterEach(() => {
+ vi.unstubAllGlobals();
+ });
+
+ it("prevents default window navigation when files are dragged into the app", () => {
+ vi.stubGlobal("__TAURI_INTERNALS__", undefined);
+ vi.stubGlobal(
+ "DragEvent",
+ window.DragEvent ?? class DragEvent extends Event {},
+ );
+
+ render();
+
+ const dragOverEvent = new DragEvent("dragover", {
+ bubbles: true,
+ cancelable: true,
+ });
+ const dropEvent = new DragEvent("drop", {
+ bubbles: true,
+ cancelable: true,
+ });
+
+ window.dispatchEvent(dragOverEvent);
+ window.dispatchEvent(dropEvent);
+
+ expect(dragOverEvent.defaultPrevented).toBe(true);
+ expect(dropEvent.defaultPrevented).toBe(true);
+ });
+});
diff --git a/ui/goose2/src/app/App.tsx b/ui/goose2/src/app/App.tsx
index 8769ea4cb3..a496490bbd 100644
--- a/ui/goose2/src/app/App.tsx
+++ b/ui/goose2/src/app/App.tsx
@@ -4,6 +4,13 @@ import { AppShell } from "@/app/AppShell";
export function App() {
useEffect(() => {
+ const preventWindowFileNavigation = (event: DragEvent) => {
+ event.preventDefault();
+ };
+
+ window.addEventListener("dragover", preventWindowFileNavigation);
+ window.addEventListener("drop", preventWindowFileNavigation);
+
// Dynamic import to avoid crash in non-Tauri environments (e.g., Playwright E2E)
if (window.__TAURI_INTERNALS__) {
import("@tauri-apps/api/window").then(({ getCurrentWindow }) => {
@@ -12,6 +19,11 @@ export function App() {
.catch(() => {});
});
}
+
+ return () => {
+ window.removeEventListener("dragover", preventWindowFileNavigation);
+ window.removeEventListener("drop", preventWindowFileNavigation);
+ };
}, []);
return ;