Automation bridge: add contextMenu verb to trigger/inspect custom right-click menus (#3858). Principle VIII.#3883
Merged
Merged
Conversation
…ht-click menus (#3858). Principle VIII. Adds a `contextMenu <target> [x y]` verb to the automation bridge so a driver can trigger and inspect a widget's custom right-click context menu — the kind built on demand in a `customContextMenuRequested` handler (Qt::CustomContextMenu) or an overridden contextMenuEvent (Qt::DefaultContextMenu), which `showMenu` could not reach because it only follows QToolButton/QPushButton::menu(). This unblocks regression-testing context-menu-driven config (the S-meter relocation being the motivating case) through the bridge — the project's UI test harness (Principle VIII: behavior is verified, not asserted). - doContextMenu(target, value): resolveWidget + visibility check, then POST a synthesized QContextMenuEvent onto the GUI loop with the owning window raised+activated first (same Cocoa re-entrancy/segfault reasoning as doShowMenu — the handler pops a QMenu that runs its own event loop). The event is sent through w->event() (not contextMenuEvent() directly) so Qt dispatches by the widget's contextMenuPolicy — sending it is what fires the CustomContextMenu path. Optional "x y" local offset, default widget center. Returns deferred:true; inspection (dumpTree) and invoke reuse the existing visible-QMenu machinery unchanged. - Header rows: describeAction and describeMenuActions now emit {"type":"header","text":<label>} for a disabled QWidgetAction whose defaultWidget is a QLabel (the app's section-title idiom, since QMenu::addSection text doesn't render under the app styling), so titles are assertable instead of serializing as blank rows. - Parse/dispatch + verb-list + header doc + docs/automation-bridge.md entry. Additive only: existing actions have no QLabel default widget so the new serialization branch is skipped, leaving showMenu/dumpTree/menu-list output unchanged. Blast radius: risk_score=0.006, 1 high-risk affected (top: handleLine — the generic dispatcher / TU entry point). describeAction's change is purely additive (new fields only on the QWidgetAction+QLabel header case), so no existing serialization path regresses; below the 0.05 threshold. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ten9876
approved these changes
Jun 28, 2026
ten9876
left a comment
Collaborator
There was a problem hiding this comment.
Approved. Implements #3858 exactly:
- Triggers custom right-click menus by synthesizing a
QContextMenuEventrouted through the widget'sevent(), so Qt dispatches by context policy —CustomContextMenuemitscustomContextMenuRequested,DefaultContextMenuhits the overriddencontextMenuEvent. Reaches the menusshowMenucouldn't (it only follows buttonmenu()). - Deferred + re-entrancy-safe —
singleShot(0, qApp, …)with the owning window raised first, so the popup's own event loop runs on the next GUI turn, not in the socket callback. Returnsdeferred:true;dumpTreeto inspect,invoketo drive — reusing existing serialization. - Header rows handled — disabled
QWidgetAction + QLabelsection titles serialize as"type":"header"+ label text (the exact S-meter case), so titles are assertable. - No TX surface —
contextMenuonly opens; item activation still goes through the guardedinvoke(isTransmitControl/isTransmitAction). Principle VI N/A.
Visibility-checked, standard resolveWidget target, optional x y offset (defaults to center). CI green on all 6. Closes the exact bridge gap that blocked verifying the S-meter context menu earlier.
ten9876
added a commit
that referenced
this pull request
Jun 28, 2026
## Release prep for v26.6.5 Docs + version-string updates for the **50 merges** since v26.6.4. No code change — safe to merge without a rebuild. ### Changes - **CHANGELOG.md** — new `[v26.6.5] — 2026-06-28` section, headlined by **KiwiSDR receive sync** (#3872), **SmartMTR TX meters** (#3776), the **PROF profile-switcher applet** (#3829), and a large **agent automation bridge** expansion (#3851/#3856/#3883/#3842/#3832/#3819); categorized Added/Changed/Fixed/Performance/Removed compiled from the full merge list. Folds in the prior `[Unreleased]` entries and resets `[Unreleased]` to empty. - **CMakeLists.txt / README.md / AGENTS.md** — `26.6.4` → `26.6.5`. - **ROADMAP.md** — current cycle → `post-v26.6.5`; four v26.6.5 highlights added atop *Recently shipped*. ### Not included - Tagging `v26.6.5` is a separate, explicit step (not done here). - The untracked `docs/aetherd-headless-engine-design.md` RFC and `prototypes/` are intentionally left out. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #3858
What was changed
Automation bridge: add contextMenu verb to trigger/inspect custom right-click menus (#3858). Principle VIII.
Files modified
docs/automation-bridge.mdsrc/core/AutomationServer.cppsrc/core/AutomationServer.hGenerated by AetherClaude (automated agent for AetherSDR)
🤖 aethersdr-agent · cost: $7.0425 · model: claude-opus-4-8