MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 85.7% 6 / 0 / 7
Functions: 85.7% 6 / 0 / 7
Branches: 100.0% 6 / 0 / 6

presentation/AltHoldDetector.h
Line Branch Exec Source
1 #pragma once
2 #include <QChar>
3 #include <Qt>
4
5 // Sprint 105 S105.7.5: the "hold Alt to see the keys" state model of
6 // docs/design/sprint-105/ux.md §2, as a pure unit. Input: key presses and
7 // releases with timestamps, pointer presses, window changes and timer ticks;
8 // output: what the overlay must do. The router owns the timer and calls
9 // tick() at nextDeadline().
10 //
11 // Invariants:
12 // - AltGr (Key_AltGr, or Alt reported together with Ctrl) never starts a hold
13 // and never activates a letter.
14 // - Autorepeat presses never restart the delay or count as another key.
15 // - A key pressed while Alt is down before the overlay shows (Alt+Up,
16 // Alt+Tab) suppresses the overlay until Alt is released.
17 class AltHoldDetector {
18 public:
19 enum class State { Idle, Holding, Keys, Explained, Acting, Suppressed };
20 enum class Action {
21 None,
22 HoldStarted, // Alt went down alone: show the hold ring
23 HoldCancelled, // the ring goes away, nothing else
24 Show, // stage 1 (keys)
25 ShowExplained, // stage 2 directly (setting "at once")
26 Explain, // stage 1 -> stage 2
27 Hide,
28 Activate, // press the element whose tip letter is `letter`
29 Recompute // after an action with Alt still held (D-21)
30 };
31 enum class ExplainMode { AfterHold, AtOnce, Never };
32 struct Settings {
33 bool holdEnabled = true;
34 int delayMs = 300; // 0..1000; 0 = show at once
35 int explainAfterMs = 700; // after the overlay showed
36 ExplainMode explain = ExplainMode::AfterHold;
37 };
38 struct Result {
39 Action action = Action::None;
40 QChar letter;
41 // True when the key event must not reach the application (a tip
42 // letter that activates an element).
43 bool consume = false;
44 };
45
46 878 void setSettings(const Settings &settings) { m_settings = settings; }
47 1790 const Settings &settings() const { return m_settings; }
48 16664 State state() const { return m_state; }
49
6/6
✓ Branch 2 → 3 taken 1199 times.
✓ Branch 2 → 5 taken 9 times.
✓ Branch 3 → 4 taken 1132 times.
✓ Branch 3 → 5 taken 67 times.
✓ Branch 4 → 5 taken 8 times.
✓ Branch 4 → 6 taken 1124 times.
1208 bool shown() const { return m_state == State::Keys || m_state == State::Explained || m_state == State::Acting; }
50 ✗ bool explained() const { return m_explained; }
51 // Opened with Ctrl+? (D-12): letters work without Alt, Esc closes.
52 72 bool toggled() const { return m_toggled; }
53 // -1 when no timer is needed.
54 16644 qint64 nextDeadline() const { return m_deadline; }
55
56 // `tipLetter`: the caller's answer to "is this key's letter shown on a
57 // badge now" (only asked while the overlay is shown).
58 Result keyPress(int key, Qt::KeyboardModifiers modifiers, bool autoRepeat, qint64 now, QChar letter = {},
59 bool tipLetter = false);
60 Result keyRelease(int key, Qt::KeyboardModifiers modifiers, bool autoRepeat, qint64 now);
61 Result pointerPress();
62 Result windowDeactivated();
63 // The window was resized, a modal opened, the IME started a pre-edit …
64 Result cancel();
65 Result tick(qint64 now);
66 // Ctrl+?: open in stage 2 without holding, or close.
67 Result toggle();
68 // The caller ran the activated element; Alt may still be held.
69 Result actionDone();
70
71 private:
72 Result hide();
73 Result enterKeys(qint64 now);
74 Settings m_settings;
75 State m_state = State::Idle;
76 qint64 m_deadline = -1;
77 bool m_altDown = false;
78 bool m_explained = false;
79 bool m_toggled = false;
80 };
81