diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 81e46ad..9575a4d 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -513,18 +513,32 @@ export function App(): React.ReactElement { } function openMenu(e: React.MouseEvent, target: ContextTarget): void { e.preventDefault(); e.stopPropagation() - openMenuAt(e.clientX, e.clientY, target) + // Editor menus open right at the cursor. Tree/git row menus instead anchor to + // the right edge of the whole column (matching the ⌘→ keyboard menu) so the + // opaque menu floats entirely beside the list — it must never reach back over + // the rows, or it hides the file directly under the one you right-clicked. + if (target.kind === 'editor') { openMenuAt(e.clientX, e.clientY, target); return } + openMenuAt(rowAnchorX(e.currentTarget as HTMLElement), e.clientY, target) + } + // Left edge for a tree/git row menu: the right edge of the row's column, so the + // menu sits clear of every row in that column (robust to horizontal scroll and + // narrow columns, where the row's own right edge can fall under the rows). + function rowAnchorX(row: HTMLElement): number { + const col = row.closest('.col') as HTMLElement | null + return (col ?? row).getBoundingClientRect().right } // ⌘→ inside Git/Explorer: open the selected row's menu, anchored to its row. function openPanelMenu(): boolean { if (activePanel === 'git' && gitSelPath) { - const r = document.querySelector('.git-row.kbd')?.getBoundingClientRect() - openMenuAt(r ? r.right - 40 : 220, r ? r.top + 4 : 120, { path: gitSelPath, kind: 'git', staged: proj.staged.has(gitSelPath) }) + const row = document.querySelector('.git-row.kbd') as HTMLElement | null + const r = row?.getBoundingClientRect() + openMenuAt(row ? rowAnchorX(row) : 220, r ? r.top + 4 : 120, { path: gitSelPath, kind: 'git', staged: proj.staged.has(gitSelPath) }) return true } if (activePanel === 'tree' && treeSelItem) { - const r = document.querySelector('.tree-row.kbd')?.getBoundingClientRect() - openMenuAt(r ? r.right - 40 : 220, r ? r.top + 4 : 120, { path: treeSelItem.path, kind: treeSelItem.type }) + const row = document.querySelector('.tree-row.kbd') as HTMLElement | null + const r = row?.getBoundingClientRect() + openMenuAt(row ? rowAnchorX(row) : 220, r ? r.top + 4 : 120, { path: treeSelItem.path, kind: treeSelItem.type }) return true } return false diff --git a/src/renderer/src/overlays.tsx b/src/renderer/src/overlays.tsx index 39a78a8..c46a821 100644 --- a/src/renderer/src/overlays.tsx +++ b/src/renderer/src/overlays.tsx @@ -469,7 +469,7 @@ export function ContextMenu({ menu, onClose }: { menu: Menu | null; onClose: () const x = Math.min(menu.x, window.innerWidth - 270) const y = Math.min(menu.y, window.innerHeight - (menu.items.length * 34 + 60)) return ( -
+
{menu.note &&
{menu.note}
} {menu.items.map((it, i) => it.sep ?
: (