From 9e873fa2509854eb9a51f636a9afdea67e93f1d6 Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Fri, 21 Aug 2026 00:09:59 +0200 Subject: [PATCH] fix(downloads): keep the column menu open on right click Stop the header context event before it reaches the newly mounted outside-click listener, preventing the column menu from closing in the same native event. --- .../views/downloads/DownloadsTable.tsx | 2 +- tests/downloads-view.test.tsx | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/renderer/views/downloads/DownloadsTable.tsx b/src/renderer/views/downloads/DownloadsTable.tsx index 030d9c1..eeb1c46 100644 --- a/src/renderer/views/downloads/DownloadsTable.tsx +++ b/src/renderer/views/downloads/DownloadsTable.tsx @@ -549,7 +549,7 @@ export function DownloadsTableHeader({ actions, columnOrder, gridTemplate, sortC className="downloads-column-header" data-download-column={column} key={column} - onContextMenu={(event) => { event.preventDefault(); actions.onColumnContextMenu(column, event.clientX, event.clientY); }} + onContextMenu={(event) => { event.preventDefault(); event.stopPropagation(); actions.onColumnContextMenu(column, event.clientX, event.clientY); }} onPointerCancel={(event) => actions.onColumnPointerCancel(column, event)} onPointerDown={(event) => { if (event.button !== 0 || !event.isPrimary) return; diff --git a/tests/downloads-view.test.tsx b/tests/downloads-view.test.tsx index 82b567f..d88eefa 100644 --- a/tests/downloads-view.test.tsx +++ b/tests/downloads-view.test.tsx @@ -1572,6 +1572,28 @@ describe("download table row contracts", () => { ]); }); + it("opens the column menu without letting the same context event close it again", () => { + const calls: Array<[string, number, number]> = []; + const header = DownloadsTableHeader({ + actions: createActions({ onColumnContextMenu: (column, x, y) => calls.push([column, x, y]) }), + columnOrder: ["name", "size"], + gridTemplate: "200px 100px", + selectedCount: 0, + sortColumn: "name", + sortDirection: "asc", + visibleIds: [] + }); + const nameHeader = findElement(header, (element) => element.props["data-download-column"] === "name"); + const preventDefault = vi.fn(); + const stopPropagation = vi.fn(); + + nameHeader.props.onContextMenu({ clientX: 320, clientY: 140, preventDefault, stopPropagation }); + + expect(preventDefault).toHaveBeenCalledTimes(1); + expect(stopPropagation).toHaveBeenCalledTimes(1); + expect(calls).toEqual([["name", 320, 140]]); + }); + it("ignores another column move while the previous move is settling", () => { const calls: string[] = []; const header = DownloadsTableHeader({