Description
Problem
Priority: P3. While panning time in Logonomic's LOC History graph, holding Ctrl (both axes) or Alt (value axis) partway through the drag unexpectedly shifts the value axis by all vertical movement made before the modifier was enabled. A large earlier movement can push plotted bands out of view. Automatic scaling recovers the view; repository data is unaffected.
Reproduction recipe and expected behavior
This recipe follows deterministic source control flow; it has not been executed in the application.
- In a plot body at least 300 pixels high, press at
(100,100). - Drag to
(150,200)without modifiers. - Keep the mouse held, press Ctrl or Alt, and move to
(151,201).
Expected: the newly enabled value-axis pan consumes only the new one-pixel vertical movement.
Actual source behavior: m_drag_last_y remains 100 after step 2, so step 3 supplies 201 - 100 == 101 pixels to value-axis panning. With a 500-pixel usable height and a 100-unit value span, the translation is 20.2 units rather than 0.2. Releasing and re-engaging the modifier during the same drag repeats the accumulation.
Cause and production integration
- plot_interaction_item.cpp initializes
m_drag_last_yon press. In the move handler, both consuming the y delta and advancing that reference occur only insideif (ctrl_held || alt_held). The x reference advances on every engaged move. - plot_widget.cpp directly translates the supplied delta into a value-range shift and disables autoscaling.
- PlotView.qml uses this interaction item. Logonomic's RepoSizeHistoryPanel.qml instantiates the shared view with interaction enabled.
Correction direction
Advance the vertical pointer reference on every engaged drag move, independently of whether that move pans the value axis. Preserve the initial click tolerance.
Focused regression coverage should exercise unmodified-to-modified movement and modifier release/re-engagement, checking that only the newly consumed delta reaches value-axis panning.
Evidence and duplicate check
Found during the 11 November 2026 routine review. Evidence is source-confirmed control flow and arithmetic; no application UI, build or native runtime test was run.
Rechecked open issues/PRs and modifier history before filing. PR #32 addresses the separate return-through-press-position dead zone: its inspected patch moves the click-tolerance check inside m_click_candidate but leaves the modifier-dependent y-reference update unchanged. The recipe above stays outside that tolerance region.
Activity
imakris commentedon Nov 11, 2026
Validation and work-package assessment — 11 November 2026
Verdict: Supported by current source; the executed checks and remaining native/rendered limits are separated below.
Current snapshot: vnm_plot@cf7dc941769b, with dependency snapshots pinned in the evidence links. Recorded checks retain their stated scope; later source changes were compared rather than represented as rerun native tests.
Validated mechanism
The drag’s vertical reference advances only while Ctrl or Alt is held, unlike its horizontal reference. Enabling a value-axis modifier midway through an ongoing drag therefore replays earlier unmodified vertical movement.
Evidence and verification
Checks and limits: The delta arithmetic was independently replayed; no Qt mouse event sequence or rendered plot was exercised.
Focused evidence: Press at y=100, unmodified move to 200, modified move to 201 supplies 101 instead of 1. This is recorded arithmetic replay, not a rendered native check.
Work package, related tickets and scope
Destination: S18 — Modifier pressed during plot drag (whole validated finding).
Scoped remediation: Advance the vertical pointer reference on every engaged drag while applying value-axis motion only when requested. Coordinate open PR #32 in the same handler: its click-tolerance change is separate and does not fix this modifier reference.
Why independent: This has its own causal implementation/verification boundary; a shared screen or repository alone does not justify a combined fix.
Focused completion checks: Drag vertically without Ctrl/Alt, engage either modifier mid-drag and confirm only the subsequent delta applies; also release/reapply modifiers and preserve click tolerance. Coordinate the adjacent drag-handler PR #32.
Adjacent work: vnm_plot PR #32 remains open at 1a320c4 in the same drag handler. It addresses click tolerance, not the stale vertical reference; preserve both behaviors when integrating.
imakris commentedon Nov 11, 2026
Complexity and remaining work — 11 November 2026
Estimated complexity: 1/5 — Small.
Why this score. The stale vertical reference and the correction are local to the drag handler. Earlier unmodified movement must update the reference even when that move does not pan the value axis; the later modifier should consume only new movement.
Remaining work. Advance the vertical reference on every engaged drag move, leaving value-axis application conditional on Ctrl/Alt. Preserve the initial click-tolerance behavior and existing horizontal movement. Coordinate the adjacent PR #32, whose click-tolerance change addresses a separate condition in the same handler.
Completion check. Drive the production interaction item through unmodified movement, enabling Ctrl and Alt separately, releasing/re-enabling them, and passing back through the original press position. Assert the emitted value delta and retained click behavior. The arithmetic replay already recorded in this issue is useful causal evidence, but it is not a native Qt input or rendered-plot pass.
Scale: 1 small, 2 bounded, 3 moderate, 4 difficult, 5 major. Estimates include implementation and validation, not urgency.
imakris commentedon Nov 11, 2026
Implemented in PR #34: #34
The vertical pointer reference now advances on every engaged drag move, so enabling or re-enabling Ctrl/Alt consumes only the new vertical movement. Initial click tolerance and horizontal routing remain unchanged.
Native verification with Qt 6.12.0 / GCC 14.2 and the maintained
PlotInteractionItemtarget reproduced both modifier failures on the original implementation (v_min=20.2instead of0.2; 39 passed, 2 failed). The fix passes all 41 cases. Composing it with PR #32 merges without conflicts and passes all 43 cases, including that PR's crossing-origin and click regressions.The PR includes the regression tests and closes this issue when merged.