Created
March 19, 2026 07:35
-
-
Save VerteDinde/81c2e1de58350893627d736b3b038b91 to your computer and use it in GitHub Desktop.
AXMenuOpened-40794596
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <title>AXMenuOpened Repro — crbug.com/40794596</title> | |
| <style> | |
| body { font-family: system-ui; padding: 20px; } | |
| button { margin: 8px 4px; padding: 8px 16px; font-size: 14px; } | |
| [role="menu"] { | |
| border: 1px solid #999; | |
| padding: 4px 0; | |
| width: 200px; | |
| background: #fff; | |
| margin-top: 8px; | |
| } | |
| [role="menuitem"] { | |
| padding: 6px 16px; | |
| cursor: default; | |
| } | |
| [role="menuitem"]:hover { background: #0078d4; color: #fff; } | |
| #status { margin-top: 16px; color: #666; font-size: 13px; } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- | |
| Repro for crbug.com/40794596 — AXMenuOpened not firing for dynamically | |
| created ARIA menus. | |
| HOW TO TEST: | |
| 1. Open Accessibility Inspector (Xcode > Open Developer Tool > Accessibility Inspector) | |
| 2. Select this Electron window from the target dropdown | |
| 3. Open Window > Show Notifications | |
| 4. Click "Show Menu" and watch for an AXMenuOpened notification | |
| EXPECTED (with patch): | |
| AXMenuOpened fires when the menu is added to the DOM. | |
| AXMenuClosed fires when the menu is removed. | |
| ACTUAL (without patch): | |
| No AXMenuOpened or AXMenuClosed events fire. | |
| Menus shown via visibility toggle (the other button) DO fire correctly | |
| because that path goes through OnIgnoredChanged. | |
| --> | |
| <h2>AXMenuOpened Repro</h2> | |
| <p>Test dynamically created/removed ARIA menus vs. visibility-toggled menus.</p> | |
| <h3>Dynamic creation (the bug)</h3> | |
| <button id="show-dynamic">Show Menu (appendChild)</button> | |
| <button id="hide-dynamic">Hide Menu (removeChild)</button> | |
| <div id="dynamic-container"></div> | |
| <h3>Visibility toggle (works without patch)</h3> | |
| <button id="toggle-visibility">Toggle Menu (aria-hidden)</button> | |
| <div id="visibility-menu" role="menu" aria-label="Visibility Menu" aria-hidden="true" style="display:none;"> | |
| <div role="menuitem">Alpha</div> | |
| <div role="menuitem">Beta</div> | |
| <div role="menuitem">Gamma</div> | |
| </div> | |
| <div id="status"></div> | |
| <script src="./renderer.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { app, BrowserWindow } = require('electron'); | |
| const path = require('path'); | |
| function createWindow () { | |
| const win = new BrowserWindow({ | |
| width: 600, | |
| height: 400, | |
| webPreferences: { | |
| preload: path.join(__dirname, 'preload.js') | |
| } | |
| }); | |
| win.loadFile(path.join(__dirname, 'index.html')); | |
| } | |
| app.whenReady().then(createWindow); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "graceful-camp-bless-hwv6i", | |
| "productName": "graceful-camp-bless-hwv6i", | |
| "description": "My Electron application description", | |
| "keywords": [], | |
| "main": "./main.js", | |
| "version": "1.0.0", | |
| "author": "khammond", | |
| "scripts": { | |
| "start": "electron ." | |
| }, | |
| "dependencies": {}, | |
| "devDependencies": { | |
| "electron": "999.999.999" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // No preload logic needed for this repro. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const container = document.getElementById('dynamic-container'); | |
| const status = document.getElementById('status'); | |
| function log (msg) { | |
| status.textContent = msg; | |
| console.log(msg); | |
| } | |
| // --- Dynamic creation / removal (the buggy path) --- | |
| document.getElementById('show-dynamic').addEventListener('click', () => { | |
| if (container.querySelector('[role="menu"]')) { | |
| log('Menu already shown.'); | |
| return; | |
| } | |
| const menu = document.createElement('div'); | |
| menu.setAttribute('role', 'menu'); | |
| menu.setAttribute('aria-label', 'Dynamic Menu'); | |
| const items = ['Cut', 'Copy', 'Paste']; | |
| for (const label of items) { | |
| const item = document.createElement('div'); | |
| item.setAttribute('role', 'menuitem'); | |
| item.textContent = label; | |
| menu.appendChild(item); | |
| } | |
| container.appendChild(menu); | |
| log('Dynamic menu added via appendChild. AXMenuOpened should fire.'); | |
| }); | |
| document.getElementById('hide-dynamic').addEventListener('click', () => { | |
| const menu = container.querySelector('[role="menu"]'); | |
| if (menu) { | |
| container.removeChild(menu); | |
| log('Dynamic menu removed via removeChild. AXMenuClosed should fire.'); | |
| } else { | |
| log('No dynamic menu to remove.'); | |
| } | |
| }); | |
| // --- Visibility toggle (the working path) --- | |
| const visMenu = document.getElementById('visibility-menu'); | |
| document.getElementById('toggle-visibility').addEventListener('click', () => { | |
| const hidden = visMenu.getAttribute('aria-hidden') === 'true'; | |
| visMenu.setAttribute('aria-hidden', String(!hidden)); | |
| visMenu.style.display = hidden ? '' : 'none'; | |
| log(hidden | |
| ? 'Visibility menu shown (aria-hidden=false). AXMenuOpened should fire.' | |
| : 'Visibility menu hidden (aria-hidden=true). AXMenuClosed should fire.'); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment