Skip to content

Gui/Vulkan: viewport and overlay work, context-menu fix, Coin bump - #146

Merged
brianmk merged 8 commits into
sketcher/edit-mode-vulkan-followupsfrom
gui/vulkan-viewport-overlay-coin-bump
Oct 11, 2026
Merged

brianmk merged 8 commits into
sketcher/edit-mode-vulkan-followupsfrom
gui/vulkan-viewport-overlay-coin-bump

Conversation

@brianmk

@brianmk brianmk commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Final part of the series: the 3D-view context menu fix, the in-tree viewport/overlay work, and the Coin bump the retained-IR fix needs.

Gui: parent the 3D-view context menu to a top-level window
With the Vulkan page active, QWidget::createWindowContainer() makes the whole MDI chain native, so QMenu(viewer->getGLWidget()) resolved to a non-top-level native child and Qt warned QWidgetWindow(...) must be a top level window. once per right-click (silently dropping the transient parent). The menu is now parented to the view's top-level widget. Regression test tests/src/Gui/RightClickContextMenu.py drives the real binary under Xvfb, asserts the menu pops with no warning, and includes a control that reproduces the pre-fix parent, so it fails on a revert. Registered as Gui_RightClickContextMenu_Vulkan (skips 77 without a Vulkan device).

Gui/Sketcher: commit in-tree viewport, overlay and tooling work
The remaining work-in-progress that was sitting uncommitted in the tree, committed as-is so it is reviewable and mergeable: overlay/annotation nodes (OverlayManager, OverlayWidgets, So3DAnnotation, SoDatumLabel, SoBrepOverlayHelpers, ToolBarManager), Quarter input and Vulkan surface plumbing (EventFilter hover coalescing, InputDeviceHost, QuarterWidget/QuarterVulkanWidget, VulkanViewportAdapter, View3DInventorViewer, MainWindow), selection/view providers (SoFCUnifiedSelection, ViewProvider*), Sketcher tooling (CommandConstraints, CommandSketcherTools, CommandSketcherBSpline, DrawSketch*, ViewProviderSketch, SketchObjectOperations) and tests/src/Gui/SelectionTest.cpp. No single topic — please review commit by commit.

Coin: bump for the retained-IR staleness fix
Points the submodule at brianmk/coin#84, which keys SoShape's retained-IR cache on the vertex sources it was built from and adds SoGeometryDescriptor::retainedGeneration so the backend detects a rebuild whose stream pointers were recycled by the allocator. Depends on brianmk/coin#84.


Part 5 of a stacked series; base is the edit-mode Vulkan follow-ups branch. Merge after coin#84 so the submodule pointer resolves on the integration branch.

@brianmk

brianmk commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

Five commits appended to this branch (fixes found while exercising this build; each verified with an out-of-tree probe):

  • Gui/Vulkan: engage interaction LOD only on a camera pose change — the camera sensor also fires for the near/far auto-clipping rewrite on ordinary frames, so a plain hover latched the reduced-detail path (and re-armed its idle timer) for as long as frames kept coming; the Sketcher grid's every-nth division lines visibly lost their configured width while the pointer moved. A new FC_VULKAN_LOD_TRACE diagnostic ([LODTRACE] cameraPose / interactionLod) makes the state observable from a probe.
  • Gui: parent dock context menus to a top-level window — fixes QWidgetWindow(0x..., name="Report viewWindow") must be a top level window. when right-clicking the Report view or the Python console.
  • Gui: don't report a filter mismatch when a file dialog is cancelled — Save As → Cancel logged the bogus FileDialog ... Problem cause filter: "" developer error.
  • Gui/Vulkan: wake the display frame on NaviCube hover/pick changes — same change as Gui/Vulkan: wake the display frame on NaviCube hover/pick changes #148 (kept here because this branch is where the hover bug reproduces; drop this commit on rebase if Gui/Vulkan: wake the display frame on NaviCube hover/pick changes #148 lands first).
  • submodules: bump coin for the wide-line interaction-LOD fix — depends on Vulkan: fix stale retained-IR geometry; draw SoText2 on the on-top pass coin#84 (new commit 2253a7de06).

Verification lives in brianmk/FreeCAD-DevTools#5: grid division lines 136 thin / 5 wide draws pre-fix → 0 thin / 141 wide post-fix, nav-cube hover 0 presented frames pre-fix → entry + sweep frames post-fix, file-dialog cancel warning gone, dock-menu warning gone; coin ctest 29/29, integrate/gui-probes/run.sh 6/6, nav-cube click probe PASS.

@brianmk

brianmk commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

Branch rebuilt (force-pushed) to drop the experimental line-midpoint vertex commit that was inherited from #143.

Ubuntu / Build was failing here with three PartDesign tests (TestHelix.testNegativeCone, TestTopologicalProblem chamfer/fillet: 44 != 62). I bisected it to c061658d1c (inherited from #143, now closed — see #143 for the full analysis): the internal P2PSymmetric midpoint rule perturbs the solver on underdetermined sketches, so the inherited commit is gone from this branch's history.

Nothing else on this branch changed — the diff against its base is exactly the commits listed in this PR. Verified locally on the rebuilt tree: FreeCADCmd -t 0 → Ran 3558 tests ... OK (expected failures=5), plus Sketcher_tests_run 111/111, PartDesign_tests_run 28/28, Gui_tests_run 349/349.

@brianmk

brianmk commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

Reopened: a force-push briefly pointed this branch at the same commit as its base branch, which made GitHub treat the PR as empty and auto-close it. The branch has been corrected (it is now rebased onto its (also rebased) base with the experimental line-midpoint commit dropped) and the diff is back to this PR's own commits.

@brianmk brianmk reopened this Oct 11, 2026
Picks up the Coin change that keys SoShape's retained-IR cache on the vertex
sources it was built from and adds SoGeometryDesc::retainedGeneration, so the
Vulkan backend can detect a rebuild whose stream pointers were recycled by the
allocator.  (brianmk/coin#84)
With the Vulkan page active, QWidget::createWindowContainer() makes the whole
MDI chain native (the QWindowContainer detects the QAbstractScrollArea
ancestor that QuarterWidget/QGraphicsView provides), so the 3D viewer gets a
non-top-level native window.  NavigationStyle::openPopupMenu() then created
its QMenu with the GL viewport as parent; QMenu::show derives the transient
parent from that widget's nativeParentWidget(), so Qt handed a non-top-level
QWindow to QWindow::setTransientParent(), which warns

    QWidgetWindow(...) must be a top level window.

once per right-click and silently drops the transient parent.  Parent the menu
to the view's top-level widget instead, which fixes the popup metadata for
every navigation style (they all share openPopupMenu).

Regression test: tests/src/Gui/RightClickContextMenu.py drives the real binary
under Xvfb with the Vulkan renderer, synthesizes a right-click into the Vulkan
QWindowContainer, asserts the menu pops with no warning, and includes a control
that reproduces the pre-fix parent so the test detects a revert.  Registered as
Gui_RightClickContextMenu_Vulkan (skips 77 without a Vulkan device).
Checkpoint of work that was sitting uncommitted in the worktree (no single
topic), so the tree is no longer carrying a mixed staged/unstaged state:

- Overlay and annotation nodes: OverlayManager, OverlayWidgets, So3DAnnotation,
  SoDatumLabel, SoBrepOverlayHelpers, ToolBarManager.
- Quarter input and Vulkan surface plumbing: EventFilter hover coalescing,
  InputDeviceHost, QuarterWidget/QuarterVulkanWidget, VulkanViewportAdapter,
  View3DInventorViewer, MainWindow.
- Selection and view providers: SoFCUnifiedSelection, ViewProvider,
  ViewProviderDocumentObject.
- Sketcher tooling: CommandConstraints, CommandSketcherTools,
  CommandSketcherBSpline, DrawSketch* handlers, ViewProviderSketch,
  SketchObjectOperations.
- Tests: tests/src/Gui/SelectionTest.cpp.

These changes were not authored in this session; they are committed as-is to
preserve them.
The interaction-LOD trigger is the camera-node sensor, and a SoNodeSensor is a
node auditor: it fires for *any* camera field write, including the near/far
auto-clipping rewrite that lands on ordinary frames -- a hover or preselection
redraw, a selection change, a scene edit, a preference push.  A plain hover
moves no camera at all, yet the notification looked identical to a real move, so
the reduced-detail path was latched and its 200 ms idle timer re-armed for as
long as frames kept being produced.  On the desk that keeps wide lines
downgraded indefinitely, which is what made the Sketcher grid's every-nth
division lines lose their configured width while the pointer moved.

Classify each notification with cameraPoseChanged() (position, orientation,
focal distance, orthographic height / perspective height-angle) and propagate
the LOD only for a real pose change.  Any other camera write still requests a
frame, because near/far changes the projection; a camera-node swap counts as a
move, so a projection-type change still engages the LOD once.  Every navigation
path writes one of the pose fields (orbit -> orientation, pan -> position, ortho
zoom -> height, perspective zoom -> focalDistance/heightAngle), so the
optimisation is unchanged for real navigation.

Add an FC_VULKAN_LOD_TRACE diagnostic ([LODTRACE] cameraPose / interactionLod)
so this class of bug is observable from a probe or a log.
Right-clicking the Report view (or the Python console) logged

    QWidgetWindow(0x..., name="Report viewWindow") must be a top level window.

A QMenu is a popup (top level) window, and Qt derives its transient parent from
the parent widget's window in QMenuPrivate::transientParentWindow().  A dock that
owns a native, non-top-level window -- as it does once the viewport made its
ancestors native, or after a float/re-dock cycle -- makes
QWindow::setTransientParent() reject that window and drop the transient parent.

Parent these popups to the containing top level window, the same way the 3D-view
context menu already does (NavigationStyle::openPopupMenu()).
Cancelling Save As (or Open) logged

    FileDialog: Qt-backed nativeFileDialog returned a selected filter that
    wasn't in the original list, defaulting to index 0
    Problem cause filter: ""

QFileDialog::getSaveFileName()/getOpenFileName() return an empty QString when
the user cancels, and appending that to the result list left a one-element list
whose entry was empty.  The cancellation test is selected.isEmpty(), so it never
saw the cancellation and the filter-mismatch failsafe fired instead.  Only
append non-empty results for the single-file modes: a real selection is
unchanged, and a cancel now takes the intended index-0 fallback silently.
setHilite(), the mouseMoved() hovering transition and the movable-cube drag
scheduled only the GL render-manager redraw, which never reaches the
display-only Vulkan widget: the cube lives in the decoration overlay, which the
adapter's scene sensor does not watch.  NaviCube hover highlights therefore never
appeared under the Vulkan renderer (clicking worked because it moves the camera,
which already requests a frame).  Route these through requestRedraw(), which
also calls viewer->requestNaviCubeRedraw() -> naviCubeChanged -> adapter frame.

Note: this is the same fix as the standalone gui/vulkan-navicube-redraw branch
(PR #148); it is repeated here because this branch is where the bug was hit.
@brianmk
brianmk force-pushed the sketcher/edit-mode-vulkan-followups branch from 27e2111 to 7555cff Compare October 11, 2026 05:54
@brianmk
brianmk force-pushed the gui/vulkan-viewport-overlay-coin-bump branch from a6a1306 to 1e1d808 Compare October 11, 2026 05:54
@brianmk

brianmk commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

Rebased again onto the re-rebased #149/#144 (one added test-index commit). This PR's own eight commits are unchanged (verified with git range-diff); local verification on the new tip: FreeCADCmd -t 0 3558 tests OK, plus the grid-lod, navicube-hover, filedialog-cancel and dock-contextmenu probes all PASS.

@brianmk
brianmk merged commit e768b85 into sketcher/edit-mode-vulkan-followups Oct 11, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant