Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions apps/web/src/wsNativeApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ describe("wsNativeApi", () => {
});
});

it("forwards context menu metadata to desktop bridge", async () => {
it("forwards context menu items to desktop bridge without position", async () => {
const showContextMenu = vi.fn().mockResolvedValue("delete");
Object.defineProperty(getWindowForTest(), "desktopBridge", {
configurable: true,
Expand All @@ -411,13 +411,13 @@ describe("wsNativeApi", () => {
{ x: 200, y: 300 },
);

expect(showContextMenu).toHaveBeenCalledWith(
[
{ id: "rename", label: "Rename thread" },
{ id: "delete", label: "Delete", destructive: true },
],
{ x: 200, y: 300 },
);
// Position is intentionally not forwarded to the desktop bridge;
// Electron's Menu.popup() uses the current mouse cursor position
// which avoids coordinate-space mismatches.
expect(showContextMenu).toHaveBeenCalledWith([
{ id: "rename", label: "Rename thread" },
{ id: "delete", label: "Delete", destructive: true },
]);
});

it("uses fallback context menu when desktop bridge is unavailable", async () => {
Expand Down
8 changes: 7 additions & 1 deletion apps/web/src/wsNativeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,13 @@ export function createWsNativeApi(): NativeApi {
position?: { x: number; y: number },
): Promise<T | null> => {
if (window.desktopBridge) {
return window.desktopBridge.showContextMenu(items, position) as Promise<T | null>;
// Don't pass explicit coordinates to the native Electron menu.
// Let Menu.popup() use the current mouse cursor position, which
// Electron resolves correctly regardless of title-bar style or
// display scaling. Passing CSS clientX/clientY can mis-position
// the menu when the sidebar content is scrolled or when the
// window uses titleBarStyle "hiddenInset".
return window.desktopBridge.showContextMenu(items) as Promise<T | null>;
}
return showContextMenuFallback(items, position);
},
Expand Down
Loading