Skip to content

Fix missing native image context menu in media modal - #1575

Merged
cheeaun merged 1 commit into
cheeaun:mainfrom
Alex0007:fix-media-modal-image-context-menu
Aug 2, 2026
Merged

Fix missing native image context menu in media modal#1575
cheeaun merged 1 commit into
cheeaun:mainfrom
Alex0007:fix-media-modal-image-context-menu

Conversation

@Alex0007

Copy link
Copy Markdown
Contributor

Right-clicking an image in the full-screen media modal shows the browser's generic page context menu (Back / Reload / Save Page As…) instead of the image context menu — Copy Image, Copy Image Link and Save Image As… are unavailable.

Root cause

react-zoom-pan-pinch, which powers pinch-zoom in the modal, ships this rule in its bundled stylesheet:

.content img {
  pointer-events: none;
}

so the <img> inside TransformComponent can never be a hit-test target. Right-clicks land on the react-transform-component wrapper div, and the browser has no image element to build the image context menu for. Verified on dev.phanpy.social (2026.07.20.57870e3): document.elementFromPoint() at the image's center returns the wrapper div, and the img's computed pointer-events is none.

Fix

Set inline pointerEvents: 'auto' and draggable={false} on the modal <img> in src/components/media.jsx.

The inline style overrides the library's stylesheet, and draggable={false} keeps native image dragging off — which is what the library rule was guarding against, since a drag ghost would interfere with panning.

Verified

  • Right-click on the modal image now targets the <img> → native image context menu with Copy Image etc.
  • Double-click zoom still works (transform scale changes)
  • Panning while zoomed still works — pointer events bubble up to the library's wrapper, and no native drag ghost appears
  • Tested on macOS against mastodon.social in Chromium and in Zen Browser 1.21.9b (Firefox 153.0, aarch64)

Notes

  • The commit also carries a one-line en.po reference shift regenerated from the media.jsx edit.
  • iOS long-press is likely still suppressed: the library also sets -webkit-touch-callout: none on its wrapper. Left out of scope here — desktop right-click is the common case — but could be a follow-up.

react-zoom-pan-pinch unconditionally sets pointer-events: none on
images inside its TransformComponent (baked into its bundled CSS, no
config to opt out), so right-clicking an image in the media modal
targets the wrapper div instead of the img — the browser never offers
Copy Image / Save Image As.

Re-enable pointer events via inline style on the modal image, and set
draggable=false so native image dragging — what the library rule was
guarding against — stays off. Pan and double-click zoom still work
since pointer events bubble to the wrapper.
@cheeaun

cheeaun commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Question, in case if you remember, was this working before the react-zoom-pan-pinch migration?

@Alex0007

Alex0007 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Yes — this is a regression from that migration. react-quick-pinch-zoom's injected CSS never touched pointer-events (just overflow:hidden; touch-action:none and a transform-origin), so the <img> stayed the hit-test target and the native menu worked. The pointer-events: none on images comes from react-zoom-pan-pinch's bundled stylesheet. Verified by running the parent commit (37b47e35) locally — elementFromPoint() on the modal image returns the <img> there, and Copy Image appears.

@cheeaun
cheeaun merged commit af8e495 into cheeaun:main Aug 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants