Add focus mode (Ctrl+Shift+T) - #17
Conversation
Introduce focusMode property to Backend and paragraph dimming to MarkdownHighlighter. When enabled, non-active text blocks are dimmed using a 30/70 blend of foreground and background that adapts to any theme. Only the old and new cursor blocks are rehighlighted on cursor move for efficiency.
Ctrl+Shift+T toggles focus mode. When active: - ensureCursorVisible() centers the cursor line vertically - Extra top/bottom padding lets the first and last lines reach center - Footer fades out and reappears on hover (250ms animation) - Shortcuts dialog updated with the new keybinding
Add Ctrl+Shift+T to README shortcuts section. Add togglesFocusMode() and focusModeDimsInactiveBlocks() unit tests verifying property toggling, signal emission, and block-level dimming behavior.
Remove anchors.centerIn on the Popup Dialog and provide explicit width and x/y centering to eliminate circular dependency calculations in Qt Quick Controls Material style.
Focus dimming rewrote the foreground of every format run in an inactive block, including the marker runs that `**`, `[` and `](url)` are painted with. Those are made invisible by drawing them in the background colour, so overwriting that with the dimmed colour brought every marker in the document back as a smudge — visual noise in the one mode meant to remove it. Runs already painted in the background colour are now left alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Reviewed this and pushed one fix to the branch ( Fixed: Needs your attention before this lands:
Smaller:
Things I checked that are fine: the search bar is unaffected and still works inside the mode; the footer and word count fade and return on hover as described; the mode can always be exited, including on a fast double press or a window focus change; and it does not persist across launches, since Also worth saying: the Heads up that this overlaps #8 (link URL hover) and #15 (strikethrough) on the same files. #15 is the one to watch: you both rewrite the Tests pass (15 passed, 0 failed). |
…log scaling, and test assertions
|
Updated with the requested fixes:
|
Recentring on `editor.y` fires outside focus mode too, where y just tracks the window height, so any resize dragged a reader who had scrolled away from the caret back to it — including F11, which changes the same height. Driving the real window, a page parked at contentY 6520 with the caret out of sight jumped to 5464 on a resize from 820 to 900. Guarded on `backend.focusMode`, which is the case the handler was added for. The test covers both halves: a resize outside the mode leaves the page where the reader put it, and entering the mode still centres the caret line straight away — with neither handler present that left the caret 599px above the top of the viewport. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re-reviewed the two new commits by driving the real window rather than reading the diff. Both things I blocked on are genuinely fixed, and I pushed one fix for a regression the scroll change brought with it ( Verified fixed
Pushed —
Worth knowing where that fix stops: changing the window width still pulls you back to the caret, through Still open, small The shortcuts dialog. Scaling the 380 fixes it at ordinary window sizes — at 1280px wide it now fits at every text scale. It still clips at the top of the range, because Tests: 16 passed, 0 failed. |
Hiding the window stopped the resize from reaching the layout: after setting the window to 900 its own height property read 900 while the flickable stayed at 820 and editor.y stayed at 42, so onYChanged never fired and the assertion that the page had not moved passed whatever the handler did. With the focusMode guard removed from onYChanged the suite still went green, which is the regression the test exists to catch. bin/test runs offscreen, so no window manager sees this window; a resize that does not land now fails the test instead of quietly emptying it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re-reviewed
On the window-manager problem you were solving: Two things asked about that came back clean, so you do not need to chase them. The keybinding: Focus-mode restoration: leaving the mode puts the editor back through the Still open, unchanged: the shortcuts dialog clips at the top of the text-scale range in a narrow window. Since the last pass #21 has appeared and also adds shortcut lines, so that dialog now has three PRs queued against it — a maintainer call, not yours. Tests: Second opinion from codex at xhigh: it ran and concluded the opposite — that hiding the window "does not [...] prevent the later height assignment from propagating" and that the test still kills both mutations. That is wrong, and the measurement above is what settles it; its remaining sections, on the keybinding and on restoration, agree with what I found, though its independence is not currently guaranteed. |
Greptile SummaryThis PR adds a keyboard-toggleable focus mode that centers the caret, dims inactive text blocks, and auto-hides the footer.
Confidence Score: 5/5The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issues identified. The focus-mode state, highlighting updates, scrolling geometry, footer behavior, and documented shortcut are internally consistent, and the investigated edge cases did not establish an observable changed-code failure.
|
| Filename | Overview |
|---|---|
| src/Main.qml | Adds focus-mode shortcut handling, caret-centering geometry, cursor synchronization, shortcut documentation, and hover-revealed footer behavior without an accepted defect. |
| src/backend.cpp | Adds focus-mode state toggling and forwards cursor positions to the Markdown highlighter. |
| src/backend.h | Exposes focus mode as a QML property and declares the new state, signal, and invokable methods. |
| src/markdownhighlighter.cpp | Implements incremental active-block tracking and theme-aware dimming before search highlighting, while retaining hidden marker colors. |
| src/markdownhighlighter.h | Declares focus-mode highlighting APIs and state. |
| tests/tst_omawrite.cpp | Adds coverage for focus toggling, inactive-block dimming, hidden inline markers, and immediate caret recentering. |
| README.md | Documents the new Ctrl+Shift+T focus-mode shortcut. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Ctrl+Shift+T] --> B[Sync current cursor position]
B --> C[Toggle Backend focusMode]
C --> D[Rehighlight document]
C --> E[Reposition editor and center caret]
C --> F[Hide footer until bottom-edge hover]
G[Cursor moves] --> H[Update focus cursor block]
H --> I[Rehighlight previous and current blocks]
Reviews (1): Last reviewed commit: "Keep the resize half of the focus-mode t..." | Re-trigger Greptile
Focus Mode (
Ctrl+Shift+T)This PR introduces a distraction-free Focus Mode toggled via
Ctrl+Shift+T(and documented inCtrl+?and the README), combining three complementary features:1. Typewriter Scrolling
2. Paragraph Dimming
Ctrl+F) remain prominently visible across dimmed blocks.3. Auto-hiding Footer
Verification & Tests
tests/tst_omawrite.cpp:togglesFocusMode(): Tests property toggling and signal notifications.focusModeDimsInactiveBlocks(): Tests that active block retains normal formatting while inactive blocks are dimmed, and verifies updates when cursor position changes../bin/test)../bin/build.