Repository navigation
Conversation
… as raw Markdown Found on the phones once their read-open guard shipped (iPhone 1.34.0, Android 1.1.49): a note opened from Home, a list or a zennotes:// link now opens with the keyboard down, as it should, and with its title drawn as a raw `# Garden plan`. Live preview hides the Markdown markers on every line except the ones the selection covers, and a note opened to be read still has a selection: the caret parked on line 1. Nobody was editing that line, but it read as source. Desktop showed the same wherever an editor sits unfocused: a hovered link's preview popover, the pinned reference pane, and the note a window restores at launch. Source is now revealed only on lines the user is editing. A state field (lib/cm-source-reveal.ts) says whether the editor has taken the focus since its note opened. Until it has, every line renders, the caret's too. The first focus turns revealing on, and a blur leaves it on, so a palette, a menu or a dialog over a note being edited redraws nothing (and a phone's keyboard going down is not the end of editing either). A note put into an editor in place of another starts over, unless the editor holds the focus as it arrives: a tab switch or a followed link from the keyboard keeps revealing. Every reveal asks the same question: the line markers, links, ==highlights==, template tokens, callout heads, rules, fences and bullets, and the math, Mermaid/D2 and embed blocks. The editors that share these extensions (the main panes, the reference pane, the link popover, floating and external-file windows) all carry the field; one without it (Quick Capture, the template editor) reveals as before. The focus is taken up in a microtask of the focus event, not on CodeMirror's own focus notice, which comes 10 ms later: by then a frame with the caret's line rendered would already be painted, and every note desktop opens would flicker its first line. A focus a phone shell turns straight back (the read-open guard blurs it in focusin) never reveals. What it deliberately does not change: when anything takes the focus, and the parser (the note grammar's full reparse is untouched). Desktop opens a note and focuses it exactly as before, so the caret's line shows its markers from the first painted frame. Desktop, visible only where an editor is unfocused: the link preview popover and the reference pane draw their first line rendered, a note a split's other pane switched to while unfocused renders its caret line, and a note restored at launch renders its caret line until the editor is clicked or focused. Tests: cm-source-reveal (an unfocused note renders its caret line; an editor without the field reveals; the first focus reveals before any timer runs; a blur keeps revealing; a refused focus never reveals; a note swapped in unfocused is read, swapped in focused reveals; a note left to read renders again; highlights and inline math follow it). In the built app over CDP with isolated stores, sampled once per painted frame on the 2.78.0 build and on this one: opening from Home, the sidebar, Search and Search Text in Vault, Vim gg/j/k and an A edit that reaches disk, a palette over a focused editor, Read to Edit, Split and the find panel paint the same caret-line states on both; the link popover and the launch restore show the change. On the iPhone shell (web build at phone size, rehearsal core from this tree): a note opened from Home, and the one restored at launch, show their heading rendered with no `#`, and a tap into the text focuses it and reveals that line.
…d down The phones' read-open guard keeps the keyboard down for a note opened from Home, the lists and a zennotes:// link, but a pick in Search still raised it: every one of core's searches ends with focusEditorNormalMode, the hand-off desktop wants (the next keystroke edits or moves in the note), and on a phone that focus is the soft keyboard over half the note the user came to read. Traced on the iPhone shell, that one call was the only editor focus after a pick from the note search, from Search in all notes and from the outline, and after cancelling a search too (the shell's Cancel sends the Escape that App's window handler answers the same way). The outline jump also focused the editor itself. The host now says how it wants a pick to land. EditorHostOptions (the editor host the shells already install for native typing and keyboard insets) gains `openNotesToRead`, asked at each pick. Where it returns true, a pick in the note search (notes and tagged blocks), Search in all notes, the outline palette and the buffer switcher opens the note at the pick without taking the focus, and the note is left to read (every line rendered, see the previous commit). If the closing palette gave the focus back to an editor that opened it (an iPhone keeps the focus in the text under a tap on a button), that hand-back is undone a frame later. Closing one of those searches without a pick leaves the focus where the palette returns it, to what had it before. Where it is absent, false or throws, nothing changes: desktop and the web app focus exactly as before. Why the editor host and not a bridge-contract capability: the answer is the phone layout, which a tablet changes at runtime (Split View), so it has to be a question asked at the pick, not a static capability; the shells already register this host; and the bridge is the vault and IO contract, with nothing for desktop or web to say here. The touch media query was not enough either: it is true on tablets in the desktop layout, which keep core's focus as the guard does. What it deliberately does not do: the list openers the shells' guard already covers keep focusing as before (the guard refuses it), and the command, template and drawing palettes keep their hand-off. Creating a note from Search still focuses it, as a new note should be written in. Shells: one line in src/ui-mobile/editor-host.ts, in both phones: `openNotesToRead: isPhoneViewport` in the installEditorHost options (isPhoneViewport from '../viewport'). Without it, a phone that adopts this core behaves as today for Search. Tests: editor-focus (desktop focuses; a host that answers no or throws keeps it; a reading host leaves the editor unfocused and read, undoes a hand-back to the editor, and leaves the focus alone on close); SearchPalette (a pick goes through the pick hand-off, Escape through the close one) and SearchPaletteBlocks (a block pick). On the iPhone shell (web build at phone size, rehearsal core from this tree, the one line above): picks from Search (from a note and from Home), Search in all notes and the outline open the note at the pick with the editor never focused and the caret line rendered; Cancel keeps it unfocused; a tap into the text focuses it and shows that line's `#`. Without the line, the same picks focus as before. On desktop over CDP every search still focuses the editor, painted the same as on 2.78.0.
…and keyboard down The phones shipped 2.78.0's core in Android 1.1.48 and iPhone 1.34.0, and walking those builds found two core-side problems: a note opened to read showed its first-line heading as raw Markdown (live preview revealed the caret line's markers with the editor unfocused, 004619c), and a Search pick raised the keyboard on a phone (0a46efb). The shared packages move to 2.78.1 so Android 1.1.50 and the replacement iPhone 1.34.0 build adopt it. The desktop app stays at 2.78.0 until its next release, which carries both changes.
… command, keyboard down After 0a46efb a Search pick on a phone opened its note to read, but two of core's hand-offs still raised the keyboard there. Closing the command palette, the template palette or the drawing palette without picking anything called focusEditorNormalMode, from the palette's own Escape and from App's window handler that answers the shells' Cancel button. And a command run from the command palette that only goes to a note already there (Go Back, today's daily note) was followed by the same editor focus, twice for the periodic notes: the palette refocuses after every command that lands on the editor, and openDailyNoteForDate and its weekly and monthly twins ask for the focus themselves (#353). Both now go through the editor host's `openNotesToRead`, the question 0a46efb added. The two hand-offs it introduced are renamed for what they now cover: focusEditorAfterReadOpen (a note opened to be read, from a search pick or a command) and focusEditorAfterPaletteClose (any of these palettes closed without a pick). On a host that opens notes to read, a palette closed without a pick leaves the focus where the palette returns it, to whatever had it before the palette opened, so backing out over a note being read keeps the keyboard down and backing out over a note being written keeps it up. Desktop and the web app focus the editor exactly as before, with the same retries. Commands say whether they open to read through a new `Command.opensToRead`, asked just before the command runs (afterwards a daily note exists either way). The rule: a command whose whole effect is to put an existing note on screen opens it to read; a command that creates a note, or works on the note in place, keeps the focus. Open to read (the palette hands over like a search pick): - nav.back, nav.forward, nav.toggle-recent (Go Back, Go Forward, Switch to Previous Note): history only holds notes that exist. - tab.reopen, tab.next, tab.previous (Reopen Closed Tab, Next Tab, Previous Tab): another note that is already open. - tab.close (Close Tab): what remains on screen is the neighboring tab. - note.daily.today, note.weekly.thisWeek, note.monthly.thisMonth: only when that note is there already. When the command has to create it, the note is new and is focused to be written in, as today. The command passes `readIfExisting`, so the opener's own focus request follows the same rule (a `read` detail on zen:focus-editor that App lands like a pick); other callers of those openers (the leader keys, the Calendar, Home, the phones' Daily note row) are unchanged. - note.daily.rollover (Roll Over Unfinished Tasks to Today): the same rule on today's note. Keep the focus, unchanged: every command that creates a note to write in (note.new.quick, note.new.inbox, note.new.here, task.new, task.new.folder, database.new, drawing.new, embed.drawing.new, and the template palette's create and insert); commands that act on the open note in place (format, rename, favorite, cover, archive and restore, copy, export, folds, task state, the editor toggles); nav.focus.editor and ref.focus, whose point is the focus; and split.right/split.down. The command palette has no command that follows a link: Open Link Popover peeks at one over the current note and keeps its own focus. Commands that open another palette or dialog still hand nothing over, and a theme picked in the palette still returns to the editor. What it deliberately does not do: change the commands themselves, Home or the Calendar, or anything on a host without `openNotesToRead`. Tests: commands (exactly those eleven commands answer opensToRead, history and tab commands always, the periodic ones only for an existing note, the writing commands never, and the periodic commands ask their opener for readIfExisting); store (the daily opener requests a read landing only for an existing note opened that way); editor-focus (a read open keeps its caller's retries on desktop); a palette test (the command, template and drawing palettes close through the close hand-off, a read command lands through the read hand-off, a writing one still focuses). app-core 3,624 and shared-domain 2,164 pass; typecheck clean (8/8). In the built app over CDP with isolated stores, on 2.78.0 and on this build: Escape out of the command palette (from its input and from a window Escape like the phones' Cancel), the template palette and the drawing palette, then Open Today's Daily Note creating the note, Go Back, Open Today's Daily Note again, Switch to Previous Note, Close Tab, Reopen Closed Tab and Next Tab each leave the same note on screen with the editor focused on both builds.
Comment on lines
+59
to
+65
| import { | ||
| findDailyNoteForDate, | ||
| findMonthlyNoteForDate, | ||
| findWeeklyNoteForDate, | ||
| isCalendarToggleAvailable, | ||
| noteFolderSubpath | ||
| } from './vault-layout' |
…xcept while Cloud needs you Piotr asked on Discord (2026-10-28), with an Android screenshot: "On android, can we hide the cloud connected / setup bar??" On the phones the bar along the bottom carries only its Cloud half, so a device that is signed in but not linked showed "ZenNotes Cloud · Cloud connected · Set up" under every note for as long as it stayed that way, and on Android the circle was lifted above that row too. There was no way to turn it off, on the phones or on desktop. Settings, Appearance, Chrome gains Status bar, on by default, next to the title bar switch, with the words people search for (cloud, cloud connected, footer, word count). Turned off, the bar is not drawn at all on any surface: desktop gets its 32 px back, and on Android the Cloud row goes and the circle drops back to the bottom, because the shell sizes that row and lifts the circle from the bar's data-cloud-sync-* hooks, which are no longer in the page. It stays off except while Cloud needs the person. cloudSyncNeedsUser (cloud-auto-sync.ts) is the same set the phones already key their Cloud row on: the attention and error phases (a stopped or failed run, including Can't reach Cloud), a Cloud vault that went away and a device Cloud signed out (both drawn as attention, now one cloudSyncShownPhase that the status row uses too), and files or the vault settings question waiting for a decision. Then the bar comes back until that is dealt with, so turning it off never hides the one place that says sync has stopped. Zen mode still clears the bar whatever it says, as before. statusBarVisible (lib/status-bar-visibility.ts) holds the rule. It is a portable preference: showStatusBar in PORTABLE_PREF_KEYS, show_status_bar under [appearance] in config.toml beside show_window_title_bar. The phones keep it with the rest of app-core's preferences (zen:prefs:v2, which both shells mirror into native storage), so it needs no shell code. Keyboard: the command palette's Toggle Status Bar (and so :view_status_bar), and `:set statusbar`, `:set nostatusbar`, `:set statusbar?` (alias `stb`) in Vim mode, the way `:set undofile` works. No single-key binding, so Vim-off gating is untouched. The option is defined without a default value: codemirror-vim applies a truthy default through the callback when the option is defined, and the first desktop relaunch over a saved show_status_bar = false came back with the bar on. Docs: the Appearance entry, the Cloud card and the ex command list in help.ts; the website follows in its own branch. What it deliberately does not do: change the iPhone, whose shell already shows the Cloud row only while Cloud needs the user, so there the switch changes nothing until the shell decides otherwise; or add a global shortcut or leader key, which none of the other chrome switches have. Tests: statusBarVisible (on by default, off until Cloud needs the user, Zen mode wins); cloudSyncNeedsUser (quiet for the everyday phases; needs the user for attention, error, a removed vault, a signed-out device, waiting files even mid-sync, and the settings question); the Settings search finds Status bar by "cloud connected" and its switch turns it off; Toggle Status Bar flips and saves it; `:set statusbar` leaves a saved choice alone when it is defined (fails with a truthy default) and sets, clears and reports it; config.toml round-trips [appearance].show_status_bar; PORTABLE_DEFAULTS still matches DEFAULT_PREFS. app-core 3,636, shared-domain 2,164 and desktop 1,198 pass; typecheck clean (8/8). In the built app over CDP with isolated stores: Toggle Status Bar hides the bar and the editor gains 32 px, config.toml says show_status_bar = false, `:set statusbar` and `:set nostatusbar` bring it back and hide it; with the main process's Cloud handlers swapped for a linked account whose sync fails, the hidden bar comes back as "Sync failed", and goes again once a sync succeeds; a relaunch with a fresh userData and the same config.toml opens with the bar hidden.
…oard down Found while verifying 42865ca: on a phone, Toggle Status Bar from the command palette raised the keyboard. Every command that lands on the editor is followed by focusEditorNormalMode, so any setting or view toggle run from the palette (Light Sidebar, Line Numbers, Word Wrap, Live Preview, a theme) put the soft keyboard over half the note, with nothing to type. Two commands also focused the editor themselves: the four fold commands (runFoldCommand) and Copy Link Under Cursor. The palette now asks where the keyboard should go (lib/command-landing.ts), with the editor host's `openNotesToRead`, the same question the Search picks and palette closes ask. The rule defaults to leaving the focus where it was before the palette opened, and names the commands that should give the editor the keyboard, so a toggle added later cannot raise a phone's keyboard by being forgotten. On desktop every answer focuses the editor, exactly as before. On a phone, after a command run from the palette: - read, the note is left to read, keyboard down (e443b86, unchanged): nav.back, nav.forward, nav.toggle-recent, tab.reopen, tab.next, tab.previous, tab.close, and note.daily.today, note.weekly.thisWeek, note.monthly.thisMonth and note.daily.rollover when that note already exists. - edit, the editor takes the keyboard, because typing or the focus is the point: note.new.quick, note.new.inbox, note.new.here, task.new, task.new.folder, database.new, drawing.new, embed.drawing.new; the four periodic-note commands when they create the note; template.create and template.insert; note.format (Format Markdown), editor.reflow-paragraph and editor.add-comment; nav.focus.editor and ref.focus; split.right, split.down and the four pane.focus commands. - stay, the focus goes back where it was: everything else. That covers every View, UI and App command (sidebar, status bar, line numbers, sort and group, panels, Tasks, Tags, Atlas, zoom, themes, Settings); the Editor toggles (word wrap, live preview, completed-task style, which-key hints, tabs, keep panels, undo history, auto reveal, quick note dates, PDF embeds); task state, folds, copies and exports; archive, trash, rename, favorite and cover; vault, Cloud, CLI and workflow commands. Enable and Disable Vim Mode stay too: the mode applies the next time the editor has the focus, and on a phone that is a tap into the text, with a hardware keyboard or without. The fold commands and Copy Link Under Cursor no longer focus the editor themselves on such a host. What it deliberately does not do: change desktop, the web app, or the commands a phone's own menu runs through runAppCommand (those never handed the focus over). Tests: commandLanding (an existing note is read even for a writing id, the edit list takes the keyboard, toggles and an unknown future command stay); every id on the edit list is a real command; the palette hands a toggle back through the close hand-off and still focuses for a writing command. app-core 3,641, shared-domain 2,164 and desktop 1,198 pass; typecheck clean (8/8). In the built app over CDP with isolated stores, on 2.78.0 and on this build, Light Sidebar, Line Numbers: Relative, Disable Word Wrap, Completed Tasks: Strikethrough, Fold All Headings and Lists, Disable Live Preview and Format Markdown each leave the editor focused on both (Toggle Status Bar too, on this build).
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Core 2.78.1 for the phones: two problems found walking the 2.78.0 phone builds. Only
packages/app-core,bridge-contractandshared-domainmove to 2.78.1 (a3a5c081); the desktop app stays at 2.78.0 until its next release.004619cc). Live preview revealed the Markdown markers of the selection's line with the editor unfocused, so a note opened to read (caret parked on line 1) showed its title as# Title. Newlib/cm-source-reveal.ts: until an editor has taken focus since its note opened, every line renders; the first focus (picked up in a microtask of the focus event, so desktop never paints a frame without the markers) turns revealing on, and a blur leaves it on. The same gate covers all eight reveal sites (live preview markers and links, callouts, rules, fences and bullets, wikilinks, highlights, template tokens, math, diagrams and embeds), in every editor surface.0a46efb4). New editor-host optionopenNotesToRead?: () => boolean(installEditorHost), asked at each pick because a tablet's layout can change at runtime. When it answers true, picks in note search (notes and tagged blocks), Search in all notes, the outline and the buffer switcher open the note at the pick without focusing the editor. The phone shells add one line (openNotesToRead: isPhoneViewport).Desktop: identical in normal use, checked frame by frame against 2.78.0 over CDP (opening from Home, sidebar, Search and Search Text; Vim motions with an edit reaching disk; a palette over a focused editor; Read to Edit; Split; find). The only visible difference is where an editor has no focus: the note restored at launch, a hovered link popover and the pinned reference pane show their first line rendered until focused.
Verification: typecheck 8/8; app-core 3,613 (new: reveal gate 8, pick and close hand-offs 5, palette assertions), shared-domain 2,164. A rehearsal core from
0a46efb4in both shells: shell typecheck and tests pass; iPhone web build at phone size and a native Android API 37 emulator show the title rendered on open, Search picks with the keyboard down, and a tap into the text raising the keyboard and the line's markers.