Repository navigation
test(gui): unified_title_bar_test gates its Alt+F check on mnemonics existing. Principle VIII. - #6359
Conversation
…existing. Principle VIII.
The hamburger block forces setNativeMenuBar(false) so every host runs
the inline-bar path. TitleBar::addAppMenuMnemonic builds its Alt+F
shortcut from QKeySequence::mnemonic(), which is empty on macOS because
Qt has no menu mnemonics there, so the File menu never opened and the
test failed on macOS with two assertions:
FAIL: Alt+F still opens the File menu with the menu bar hidden
FAIL: opening a menu rounds the submenus added to it since
Gate the Alt+F assertion on QKeySequence::mnemonic("&File") being
non-empty, not on Q_OS_MACOS. Where mnemonics exist the original
keyClick and check run unchanged. Where they do not, say so on stderr
and popup() the File menu at the hamburger button, the anchor the real
mnemonic handler uses, so the submenu-rounding check still runs.
Test only: on macOS the real menu bar is native and setMenuBar returns
before any of this is built.
Verified on macOS (Qt 6.12.0): unified_title_bar_test passes in 0.77 s
and prints the skip line; it failed identically on unmodified main.
Fixes aethersdr#6358
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Issue fit
Yes. #6358 asks for exactly three things — gate the Alt+F assertion on the capability rather than on Q_OS_MACOS, keep the submenu-rounding check alive on the gated path, and add the explicit #include <QKeySequence> — and the diff does all three and nothing else. I checked the issue's load-bearing claims against the head checkout rather than taking them on trust, and each one holds:
TitleBar::addAppMenuMnemonic(src/gui/TitleBar.cpp:1149-1155) really does bail on an empty mnemonic:const QKeySequence key = QKeySequence::mnemonic(menuAction->text()); if (key.isEmpty()) return;— so the new gate is the same predicate the production code uses, not a proxy for it.src/gui/TitleBar.cpp:1096-1097—if (mb->isNativeMenuBar()) return; // macOS / a global-menu desktop shows the menus itself— returns before the hamburger or any mnemonic is built, andgrep -rn setNativeMenuBar src/has zero hits. The gated behaviour is genuinely unreachable in the shipping macOS app, so "test-only, no user impact" is correct.AetherSDR::roundMenuTree(src/gui/RoundedMenu.cpp:37-52) sets the two flags, then connects apreparelambda that recurses throughaction->menu()toQMenu::aboutToShow.QMenu::popup()emitsaboutToShowsynchronously on the same thread, so theelsebranch does leaverounded(lateSubmenu)with real teeth instead of quietly dropping it. (Reasoned from code — I ran nothing.)
Scope
| File | What it changes | Claimed by the body? | Verdict |
|---|---|---|---|
tests/unified_title_bar_test.cpp |
#include <QKeySequence>; wraps the Alt+F keyClick/check pair in a QKeySequence::mnemonic gate with a popup() + stderr-note fallback |
Yes | In scope |
git diff --stat b3e0302ea..HEAD is one file, 10 insertions / 3 deletions. Nothing else in the diff, no production code, no build config, no CHANGELOG.md entry (correct — it is a release-prep file and must not be touched here). The body's self-certifications check out. Everything in the diff is explained by #6358.
No socket test added or modified. The target links Qt6::Network, but the file opens nothing: no QTcpSocket/QUdpSocket/QLocalServer/connectToHost/bind/listen, and no Fake* peer. The changed hunk adds only a QKeySequence probe and a QMenu::popup().
Blockers
None.
Nits
All non-blocking.
tests/unified_title_bar_test.cpp:1055— the gate hardcodes a second copy of the menu title:Production derives it from the action (if (!QKeySequence::mnemonic(QStringLiteral("&File")).isEmpty()) {
TitleBar.cpp:1153:QKeySequence::mnemonic(menuAction->text())). Today the literal matches:967'smenuBar->addMenu(QStringLiteral("&File")), but if that title ever loses or moves its&the gate and the menu drift apart silently. Deriving it removes the coupling:if (!QKeySequence::mnemonic(fileMenu->menuAction()->text()).isEmpty()) {
tests/unified_title_bar_test.cpp:1059-1060— the fallback opens the menu but never asserts it opened, so on macOS "the File menu can be shown at all" is no longer checked anywhere; only rounding is. One line restores it without touching the Linux/Windows path:fileMenu->popup(menuBtn ? menuBtn->mapToGlobal(QPoint(0, menuBtn->height())) : QPoint()); check(QApplication::activePopupWidget() == fileMenu, "the File menu opens where mnemonics are unavailable");
tests/unified_title_bar_test.cpp:1008-1010— the minimal-mode "mnemonics inert" check passes vacuously on macOS for the same root cause, and unlike the new gate it says nothing about it. You disclose this in the body and I agree with keeping the assertion; the asymmetry (one skip announced, one silent) is the only reason to mention it.- Context for the maintainer, not a defect in this PR: #6348 and #6353 both cite these two failures as "the #6224 checks". #6224 is the unified-title-bar native-platform tracker (Snap Layouts, #4557 drift, macOS M1 pointer input, xcb move) and never mentions
unified_title_bar_test; it explicitly puts "anything already covered byunified_title_bar_test" out of scope. #6358 is the correct home for this symptom, so those PRs' "pre-existing failure" references resolve here once this lands.
What I tried to break
- Is the gate hiding a real macOS defect? This was my main attack — a capability probe that skips an assertion looks exactly like a test silenced to go green. It isn't: the probe is the production gate verbatim (
TitleBar.cpp:1153-1155),setMenuBarreturns at:1096-1097when the bar is native, and nothing insrc/forcessetNativeMenuBar(false). There is no user-facing Alt+F on macOS to be broken. - Does the
elsebranch leave the next assertion vacuous? No —roundMenuTree'sprepareis wired toaboutToShowwith a direct connection and recurses into submenus, andpopup()emits that signal synchronously, sorounded(lateSubmenu)is evaluated afterprepare()has run. Had the fallback beenshow()or a deferred popup, the check would have become a tautology. - Does it perturb the code after the hunk? Both branches end with exactly one open popup, closed by the existing
fileMenu->close(); app.processEvents();, so the "offscreen does not hand activation back after a popup closes" invariant documented at:1065-1068is unchanged, and the hamburgermouseClickthat follows still runs from the same state.menuBtnis already asserted non-null and visible at:1012-1013, so themenuBtn ?ternary cannot be the live path. - Include hygiene by the PR's own standard.
<QKeySequence>is correctly added. I also checked the newQPoint(0, menuBtn->height())/QPoint()calls:<QPoint>is already present at:51andQPointhas been used since:174, so the hunk introduces no second transitive include. Nothing to fix. - Linux/Windows regression. The first branch is the pre-change code byte for byte, and
mnemonic("&File")is non-empty there, so existing coverage is untouched. If some Qt build ever re-enabled mnemonics on macOS viaqt_set_sequence_auto_mnemonic(true), the gate would take the assertion branch — which is precisely why the capability probe beats aQ_OS_MACOS#ifdef. - Could not verify, and it matters: that
QKeySequence::mnemonic("&File")is actually empty underQT_QPA_PLATFORM=offscreenon macOS. Qt's switch lives inqkeysequence.cpp, not a header, and I have no build or test run here — every finding above is reasoned from source. The only evidence theelsebranch is ever taken is your reportedmnemonics are off on this platform: Alt+F check skippedline; a reviewer on a Mac confirming that line appears would close the loop. - CI, for the record. All five checks on
dbed8a0are green (build,check-macos,check-windows,Static checks,Sanitizer option configures), but none of them runs this test:ci.yml's frozen gate limits macOS tomac_nr_filter_testandasr_gpu_probe_test, andfull-suite.ymlruns the unfiltered suite onubuntu-lateston push to main, i.e. after merge. So green here is not evidence the macOS red is fixed, and the body's "CI's Ubuntu full suite keeps running it" is true only post-merge. Worth stating plainly, since the whole point of the PR is a result nobody's pre-merge lane sees.
Security audit (CodeGuard): all eight leads refuted — every one is pre-existing, outside the changed hunk, and a lexical false positive on test code. CS-VLN-CMDI-AMP at :97, :686, :704 matches the C++ reference declarator in parameter lists and lambda captures (const QString& id, [&requestedId, ...]); the file invokes no shell. CS-VLN-CMDI-BACKTICK at :13, :28, :113 matches Markdown-style backticks inside // comments. CS-VLN-SSRF-PRIV-192 and CS-PII-IP at :437 are the same line — connected.transport = QStringLiteral("192.168.1.21"), an RFC 1918 fixture string assigned to a field the radio tab renders as a display label (the sibling at :444 sets it to "SmartLink"); the file builds no request and opens no socket. No credential, no unsafe C API, no format string under test control.
Recommendation
Approve with nits. The diff is minimal, the gate is the production predicate rather than a platform guess, the follow-on rounding check keeps its teeth on the skipped path, and the skip announces itself instead of passing silently — which is the right call for a red test that was teaching Mac developers to ignore red. I could not break it, and the one thing I'd most like confirmed (that the else branch is actually taken) is a macOS-only observation no lane in this repo makes. Next step: take the two one-line nits at :1055 and :1059 if you agree, or land as-is and let the post-merge Ubuntu full-suite.yml run confirm Linux is unchanged. Thanks for the unusually well-evidenced issue — the root-cause write-up on #6358 made this reviewable from source alone.
🤖 aethersdr-agent · cost: $9.4830 · model: claude-opus-5
|
Cisco CodeGuard — static analysis of this PR (8 finding(s))
Automated static scan by Cisco DefenseClaw CodeGuard on the changed files. Advisory — some may be false positives; the review above verifies them. 🤖 aethersdr-agent · cost: $9.7818 · model: claude-opus-5 |
…the fallback popup opens. Principle VIII. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks for the review. Pushed 9d2188c. Taken
Not taken
🤖 Generated with Claude Code |
ten9876
left a comment
There was a problem hiding this comment.
Issue fit
Yes. #6358 requires an explicit QKeySequence include, a capability-based Alt+F gate, and retained submenu-rounding coverage when mnemonics are unavailable. The current head implements all three, derives the capability from the actual menu action, and additionally asserts that the fallback popup opened. The earlier review's two actionable nits are addressed.
Scope
| File/group | Change | Claimed? | Verdict |
|---|---|---|---|
tests/unified_title_bar_test.cpp:44,1055–1068 |
Explicit include; mnemonic capability gate; fallback popup and assertion | Yes | In scope, test only |
Everything in the diff is explained by #6358. Both commit author dates and messages fit the issue; no production code, default, UX preference, protocol surface, test registration or CHANGELOG change. The body's checklist holds. The illustrative body diff predates the follow-up commit; the current source contains the stronger action-derived gate and popup assertion described above.
Blockers
None.
Nits (non-blocking)
None requiring a source change. The minimal-mode assertion still passes vacuously when mnemonics are disabled, as already disclosed; its coverage remains useful on platforms with mnemonics.
What I tried to break
- Built only
unified_title_bar_testin an isolated head worktree using GCC 16.2.1 and pinned Qt 6.12.0. Its registered offscreen CTest passes on Linux. - Exercised the missing-mnemonic branch by declaring Qt's exported
qt_set_sequence_auto_mnemonic(bool)switch in the scratch test and calling it withfalseimmediately after QApplication construction. The merge-base test fails with exactlyFAIL: Alt+F still opens the File menu with the menu bar hiddenandFAIL: opening a menu rounds the submenus added to it since. The head test, under the identical switch, passes and printsmnemonics are off on this platform: Alt+F check skippedandunified_title_bar_test: all checks passed. - Mutated the head test by removing its fallback
fileMenu->popup(...)while leaving mnemonics disabled. CTest returns failure withFAIL: the File menu opens where mnemonics are unavailableand the submenu-rounding failure. Both retained assertions therefore detect the missing operation. Restored the exact head source and confirmed the registered test passes again. - Read the production mnemonic predicate, native-menu early return, popup anchor, and
roundMenuTreeaboutToShow recursion. The gate matches production; closing the popup preserves the later hamburger click coverage.git merge-treeagainst current main is clean. The file has no socket ownership or synthetic peer; linking Qt Network is not a socket test.
The Linux capability-toggle experiment verifies the failing condition and fallback, not a native macOS runtime. The author's native macOS result was not independently rerun. No application bridge session was launched because only a socket-free GUI test changes; the actual widgets were driven by that test. No operator instance or radio was touched. No separate automated review skill was available; existing bot findings were checked against the latest source rather than adopted.
CI's five reported checks succeeded, but neither the macOS nor Windows PR gate runs this test. Earliest head run creation was 2026-10-11T15:05:59Z, preceding current main 0625d24 at 2026-10-11T15:12:10Z. The pull_request workflow tested an older merge snapshot; non-strict protection does not force refresh. The local test evidence above is separate from those green build checks.
Recommendation
Approve. The original condition fails on the base and succeeds on the head, and a broken fallback fails the retained assertions. Obtain the normal CODEOWNERS decision and refreshed integration checks; no remaining implementation blocker found.
ten9876
left a comment
There was a problem hiding this comment.
Landing approval at verified head 9d2188c.
9d2188c: tests/unified_title_bar_test.cpp derives the mnemonic gate from the menu action and asserts the fallback popup. The prior two actionable nits are fixed. The existing minimal-mode non-event assertion remains valid with mnemonics disabled; the capability-toggle run confirms no popup, while the same test exercises the mnemonic path normally on Linux.
The complete scope, governance, empirical evidence and unverified boundaries are recorded in my preceding review. I re-inventoried reviews, comments, every thread, current signatures and required checks: no unresolved thread, active CHANGES_REQUESTED review, or remaining actionable finding. No additional code push was needed. The manual adversarial pass substitutes for the unavailable automated skill; no operator app or radio was touched.
All four required checks pass on this head and it merges cleanly. Main at arming is 7e080e0, newer than the PR run creation; strict:false deliberately permits this and the post-merge CI is the independent verification. No update solely for CI freshness was made.
Independent test evidence: registered unified_title_bar_test passes; with Qt mnemonics disabled, base fails the exact two issue assertions and head passes; omitting the fallback makes both retained assertions fail. Native macOS was not independently driven.
Summary
Fixes #6358
unified_title_bar_testfailed on macOS because its Alt+F assertion needs a menu mnemonic and Qt has none on macOS. This gates that assertion on whether mnemonics exist, and opens the File menu directly where they do not, so the check that follows it still runs.Only
tests/unified_title_bar_test.cppchanges (one include, one gate):Why
The test forces
setNativeMenuBar(false)so every host exercises the inline-bar path.TitleBar::addAppMenuMnemonic(src/gui/TitleBar.cpp:1149) creates aQShortcutfromQKeySequence::mnemonic(...)and does nothing if it is empty, which it always is on macOS. With no shortcut the File menu never opens, and the second check fails with it because submenus are rounded inaboutToShow(src/gui/RoundedMenu.h:26). It is a test problem only: on macOS the real menu bar is native andsetMenuBarreturns before any of this is built (TitleBar.cpp:1096-1097).Review notes
Q_OS_MACOS#ifdefwould also be wrong on any Qt configuration that turns mnemonics on or off. CheckingQKeySequence::mnemonictests exactly the thing the assertion depends on.mnemonic("&File")is non-empty, so the first branch is the original code, byte for byte. CI's Ubuntu full suite keeps running it.elsebranch opens the menu withpopup()anchored at the hamburger button, the same anchor the real mnemonic handler uses (TitleBar.cpp:1164), soaboutToShowfires androunded(lateSubmenu)is still meaningful.Constitution principle honored
Principle VIII, Evidence Over Assertion. A test that is red for an environmental reason teaches reviewers to ignore red; this makes the macOS result mean something again, and states in the output what it skipped.
Test plan
Run locally on macOS (Apple clang 21.0.0, Qt 6.12.0, RelWithDebInfo,
QT_QPA_PLATFORM=offscreenvia the CTest property):mainfirst: the twoFAIL:lines above, on repeated runs, and with all other changes stashedcmake --build build --target unified_title_bar_test, exit 0ctest -R '^unified_title_bar_test$': passes in 0.77 s, output includesmnemonics are off on this platform: Alt+F check skippedandunified_title_bar_test: all checks passedQ_OS_MACat line 289, tracked in chore(build): migrate deprecated Q_OS_MAC to Q_OS_MACOS (Qt 6.12 clang deprecation warnings) #6354;setActiveWindowat line 983)I only ran this one test; the rest of the suite is untouched by a one-file test edit.
Checklist
docs/COMMIT-SIGNING.md), SSH signing with thew5jwpsigning keyAppSettingscalls (Principle V): noneMeterSmoother: no UI touchedCHANGELOG.mdis not touched🤖 Generated with Claude Code