Skip to content

The textweaver app

textweaver comes in two forms, both parts of one program: the textweaver app, the graphical version, which textweaver starts, and the terminal reader, which tw starts. Both share the same documents, keys, settings, notes, and voices. This page covers only what is specific to the app: its screen, menus, dialogs, panels, and announcements. In this guide "the window" always means the app's own window (its size, its title, closing it), while "the graphical version" and "the app" refer to the program.

The app is written entirely in Rust, using Xilem's Masonry widgets, Vello for drawing, Parley for text, and AccessKit to communicate with screen readers. It both reads and edits; see Editing.

In a release package the program is textweaver (textweaver.exe on Windows, and inside textweaver.app on macOS); see the app. A build from source with cargo build -p textweaver-xilem produces the same program, textweaver. Releases up to beta 2 named the app textweaver-gui.

Starting it

textweaver path/to/document.md

The program opens the app unless it is asked for the terminal program: with --tw or --cli first, when started as tw, or when the first word is one of tw's commands, such as textweaver convert. A document whose name is also a command's name, such as a file called convert, opens in the app as textweaver ./convert.

With no document, the app opens empty and says which key opens one (Ctrl+O), at every announcement level except off.

The first time textweaver runs (when no settings exist yet), the app speaks a short welcome naming the five keys that get you reading: open, play and pause, stop, the command palette, and help. On Windows it also names the keys that show the hidden menu bar (Alt or F10). The hint that no document is open follows. After that come at most three steps, one at a time, each of which Escape skips:

  1. The language list, offered only when the system's language is not one of the six that textweaver speaks; when it is, textweaver uses it without asking.
  2. The screen reader arrangement. If a screen reader is running, textweaver reads documents aloud and leaves its messages to the screen reader. It states this in one sentence, together with the key that changes it, and never asks.
  3. The optional components, with nothing chosen and nothing downloaded unless you choose. The same list holds the single question about checking for updates once a day (Updates).

The terminal reader behaves the same way. Ask again about first-run choices (Tools) brings the last two steps back at the next start. If an earlier run left unsaved work, the app offers it back. The speech engine starts in the background, so the app is ready at once; Restart Speech (Shift+F8) starts it again, and it restarts by itself once if it stops.

Useful options:

  • --read: start reading once the document is open.
  • --theme NAME: use this theme instead of the saved one, for this run.
  • --voice ID and --backend ID: the voice or speech engine for this run (see tw voices and tw backends).
  • --no-speech: run silently.
  • --announce live or --announce uia: how messages reach your screen reader, for this run (see Announcements).
  • --select-spoken: while reading, select the spoken word instead of only moving the cursor to it (see The spoken word).
  • --home FOLDER: keep settings and reading positions in this folder, as TEXTWEAVER_HOME does.
  • --list-menus: show the menus as a list inside the app (F10), as on Linux, instead of the system's menu bar.
  • --graphics API: draw with a single graphics API: vulkan, dx12 (Windows), metal (macOS), or gl. The default, auto, lets the graphics library use every API it finds. On the development machine vulkan used about 26 MB less memory, though the result depends on your graphics driver. To keep a choice, set graphics = "vulkan" in the [gui] section of settings.toml.
  • --log or --log-file PATH: record what the app announces and does, for a bug report. Every 200 frames it also writes a "frame times" line giving the median, the 95th percentile, and the worst time to draw a frame, so that a change to drawing can be measured in a real window. While a prompt for a secret is open (the GitHub token for a private components source), the log is paused: it records "log paused: a secret prompt is open" and then nothing until the prompt closes, so that no keystroke, no resulting command, and not the answer itself can reach the file.
  • --version: the version, then textweaver's copyright line.

textweaver --help lists every option.

On Windows the app opens its window without a console window beside it. Started from a terminal, --help, --version, and errors still appear in that terminal. PowerShell does not wait for a windowed program, so the output may arrive after the next prompt; textweaver --help | Out-Host waits for it. For the terminal reader and the commands, use tw, which a terminal waits for. Started from a shortcut or File Explorer, a startup error appears in a message box, and --log-file PATH keeps it in a file as well.

What is in the app

From top to bottom:

  1. The menu bar (Windows and macOS): File, Edit, View, Reading, Speech, Tools, and Help; see Menus.
  2. The header, a banner with four buttons by default: Open, Font, Settings, and Commands. The document's title is the window's title.
  3. The Contents or Notes panel, only when you show one (Ctrl+1 or Ctrl+2), to the left of the document; see The Contents and Notes panels.
  4. The document, one control your screen reader reads as a document (on macOS, a read-only text area, which VoiceOver reads with its text commands). The cursor keys are your system's own (see Cursor keys), with Shift to select. Ctrl+C (Command+C on macOS) copies the selection, and says what it copied. Every other key goes to textweaver's keymap, so the browse keys of NVDA and JAWS work here too: h for the next heading, t for the next table, k for the next link, and so on.
  5. The RSVP strip, only while RSVP is on (Alt+Shift+R). It shows one word at a time under the document, so it never covers the text or the cursor.
  6. The toolbar, named "Reading": by default Play or Pause, Stop, Previous paragraph, Next paragraph, Edit, Slower, and Faster. Both bars can hold other commands; see Customizing the buttons. Edit (Ctrl+E) enters edit mode; in edit mode the same button is named Done editing, with Ctrl+E and Escape as its keys, and leaves it. Either way the focus moves to the document, and you hear the mode change once, from the app ("Edit mode on." or "Edit mode off."). In beta 3 this button moved from the header to the toolbar; a header or toolbar you customized keeps your choice. If you hide the bar that holds it, Done editing appears on the other bar while you edit, so there is always a button that leaves edit mode. In edit mode a Start dictation button (Ctrl+Shift+F9) stands directly after Done editing, before Slower. While a dictation is under way, it gives way to two buttons: Pause dictation (Alt+Shift+F9), named Resume dictation while the microphone is paused, and Stop dictation (Ctrl+Shift+F9). Start dictation goes when edit mode ends, Pause and Stop when the dictation ends, and the focus moves to the document if it was on a button that went; with the toolbar hidden, they appear on the header. Pausing and resuming are announced ("Dictation paused.", "Dictation resumed."). See Dictating in the reader.
  7. The status bar: the last message, then what the terminal's title line shows: the reading state, "line 3 of 40, 7%", the accessibility mode, the rate, and the speech engine.

Every button has a key, drawn on screen beside its name, for example "Open… (Ctrl+O)". Your screen reader treats it as the button's shortcut key: NVDA and JAWS announce it after the name when their setting for reporting shortcut keys is on (in NVDA, Object Presentation, "Report object shortcut keys"). The accessible name itself is only the label, "Open", so it stays short. The key comes from the keymap, so a key you change in keymap.toml appears here too, and F1 and the command palette list every key. While single-key shortcuts are on, a button shows its single key ("Play (Space)"); press F9 to turn them off, and the buttons show their chords instead ("Play (Ctrl+Shift+Space)").

In a narrow window the buttons wrap onto additional rows rather than extend past the window's edge. Below 800 pixels wide (at 100 percent; a 1366 by 768 laptop at 200 percent is 683 wide), the header and the toolbar fold into one flat bar above the document and the buttons hide their keys on screen (your screen reader still announces them). Below 600 pixels the panel moves above the document. Header and Toolbar in the View menu hide either bar; their commands keep their keys and menu items, and the settings gui.header and gui.toolbar remember the choice on this computer.

Tab and Shift+Tab move between the document and the buttons, in the order they appear on screen. F6 and Shift+F6 move between the app's regions, as in other Windows programs: the header, the panel (when shown), the document, the preview (when shown, in edit mode), and the toolbar, landing on the first control of each. Dialogs (settings, lists, the command palette) open inside the window and take the focus; Escape closes them and returns you to the document.

Customizing the buttons

The buttons on both bars are a matter of choice rather than a fixed set. Any command that has a short name, meaning any command the command palette and the menus list by name, can be placed on the header or the toolbar, in whatever order suits the way you read. The toolbar's defaults reflect how most readers move through a text: Play and Stop, then steps by paragraph rather than by sentence, then Edit, then Slower and Faster. A reader who prefers sentence steps, heading steps, or Find on the toolbar can have them.

View, Customize buttons (also in the command palette as "Customize buttons") opens a list of every button, the header's first, each named with its bar and its place there, as in "Stop, toolbar 2 of 7". Enter on a button offers Move up, Move down, and Remove; Delete removes the focused button at once. The last three rows add a button to the header, add one to the toolbar, or reset both bars to their defaults. Adding opens a list of the commands that are on neither bar, in alphabetical order, so a first letter jumps through it. Every change is said in words as it happens ("Find added, toolbar 8 of 8"), saved at once, and the list returns to the button that changed. The bars themselves change at the same moment, without restarting the app, and the Tab order through each bar always follows the order in which its buttons are drawn: left to right, then row by row when a bar wraps. In a small window, where a bar shows only the buttons that fit, Commands stays visible wherever you placed it, because it lists every command, including those whose buttons are hidden. The terminal reader offers the same list, and its key hints follow the toolbar's choice.

The rules that keep the bars usable hold for any choice. Each button keeps its real name and its key in its accessible name, the keys are hidden on screen in a narrow window as before, and buttons that do not fit fold into Commands. A command never appears on both bars, nor twice on one.

The choice is kept in the settings gui.header_buttons and gui.toolbar_buttons, as lists of command ids, and like the other window layout settings it stays on this computer rather than syncing. A command id that this version does not recognize, perhaps one written by a newer version, is kept in the setting but not shown, so moving between versions loses nothing.

Focus mode and full screen

Focus mode gives the text the whole window. With it on, the header, the toolbar, the status bar and the Contents or Notes panel fade from view once the mouse has rested for three seconds, and the document widens and lengthens to fill the space they leave. Moving the mouse brings them back at once, and they fade again after the next rest. Turn it on or off with View, Focus mode, with "Focus mode" in the command palette (F2), or in Settings under Window (focus_mode = true in [gui]). It is off by default and stays on this computer, and the delay is fixed rather than configurable.

The keyboard never brings the interface back. Reading keys such as Space, the arrows, the sentence and paragraph keys, and the rate keys leave the screen undisturbed, so a reader who works from the keyboard is not interrupted. The hiding is visual only: every control stays in the accessibility tree with its name, its role and its place, the Tab order and F6's regions are unchanged, and the focus stays where it was. A hidden button still takes the focus and still works; it is simply not drawn until the mouse moves. Nothing is announced when the interface fades or returns, so NVDA, JAWS and a Braille display read the window exactly as they do without focus mode. Turning focus mode on or off is announced, as the result of a command.

Full screen has the same effect while it lasts, whether or not focus mode is on. F11, Alt+Enter, or View, Full screen, makes the textweaver app fill the screen and lets the interface fade when the mouse rests; the same key restores its size. F11 is the usual full-screen key on Windows and Linux, and Alt+Enter is the one many media players and terminals use. On macOS the key is Option+Enter, because macOS keeps F11 for showing the desktop. In the terminal reader F11 remains the next chapter, and the terminal program usually takes it for its own full screen.

The app has the same menus as the terminal reader, built from the same list of commands, so both always offer the same things under the same names: File, Edit, View, Reading, Speech, Tools, and Help. Every command appears in a menu with its key beside it, and because the keys come from the keymap, a key you change in keymap.toml shows in the menus too.

  • Windows: a standard menu bar, which NVDA and JAWS read as any program's. Alt, or F10, enters it; Alt with a menu's underlined letter opens that menu (Alt+F for File); Alt+Space still opens the window's system menu. In a menu, each item is read with its key, for example "Open, Ctrl+O", and a setting you can turn on or off is read as checked or not checked. Escape leaves the menus and puts you back where you were.
  • macOS: the menu bar at the top of the screen, with each command's key as its keyboard shortcut. VoiceOver reaches it with Control+Option+M.
  • Linux: F10 shows the menus as a list inside the app, as the terminal does: "Menus, 1 of 7, File". Enter or Right opens a menu, a letter moves to the item with that letter, Enter runs a command, Left or Backspace goes back up, and Escape closes.

Hiding the menu bar (Windows). The menu bar is hidden by default and occupies no space until you call for it; the first-run welcome says so ("Alt or F10 the menus"). To keep it visible, turn off "Hide the menu bar" in Settings, under Window (auto_hide_menu = false in [gui]); a value you saved earlier is kept. Alt, F10, or Alt with a menu's letter shows the bar and enters it as before, so NVDA and JAWS still announce "menu bar" or the menu's name, and the bar hides again, silently, when the menu closes. Every Alt key the keymap uses still works, and the bar appears briefly when you press Alt for one of those keys. Close any open dialog before using the menus. The setting has no effect on Linux, where the menus are already the F10 list and take no room, or on macOS, whose menu bar is at the top of the screen.

The context menu

The Applications key (beside the right Ctrl key), Shift+F10, or a right-click opens the context menu in the document, while reading and while editing. It offers the commands that fit where the cursor is: Cut, Copy, Paste, Paste as plain text, Select all, Add note, Highlight, Define word, Read from here, and, on a link, Open link. Cut and the two pastes appear only in edit mode. Each item shows its key, so the menu also teaches the shortcut. The items, their names, and their keys come from the same list as the menu bar, so the two never disagree.

On Windows the context menu is a standard one, which NVDA and JAWS announce as a menu; each item is read with its key, and its underlined letter chooses it. Opened from the keyboard it appears at the cursor; opened by a right-click it appears at the pointer, and the cursor moves there unless you clicked on the selection, which the menu then acts on. Escape closes it and leaves the focus where it was. On macOS and Linux the same items appear as a list in the window's list dialog, as the terminal reader shows them.

Choosing a command in a menu runs it exactly as its key would, and it joins the recent commands that the command palette lists first (F2 with nothing typed). A few commands that only make sense in a terminal are left out of the app's menus (see What only the terminal reader does). File, Browse files opens textweaver's file browser in the window's list dialog (see Reading); its keys work there as in the terminal, and the Say Status key previews the focused row. Batch conversion, audio export, and dictation are in the menus in the default build.

Opening a document

Open (Ctrl+O) shows your system's own file chooser, which on Windows is the standard Open dialog that NVDA and JAWS already handle well. It lists the documents textweaver reads; choose "All files" in the file type list to see everything. It starts in the folder of the document you have open. When you choose a file, the dialog closes, textweaver says "Opened" and the title, and focus returns to the document. Escape cancels.

To type a path instead, press Ctrl+Shift+G (Open Path): a one-line prompt where Tab completes the path, Up and Down recall earlier ones, and F4 opens textweaver's own file browser, whose choice fills the prompt for Enter to confirm. If the system's file chooser cannot open (on Linux it needs the XDG desktop portal), textweaver says so and shows this prompt instead.

The other commands that ask for a file use the system's file chooser too, each titled for what it does:

  • Save as opens the system's Save dialog in the document's folder, offering the document's name. The system asks before replacing a file.
  • Insert image (while editing) lists images (PNG, JPEG, GIF, SVG, WebP and BMP), starting in the document's folder.
  • Import references lists BibTeX, RIS and CSL-JSON files.
  • Import profiles and Export profiles (in the Profiles list) use TOML and JSON; export offers textweaver-profiles.toml.

Commands that ask for a folder use the system's folder chooser, titled with what the folder is for: audio export's "Another folder", the folders of a batch conversion, and the sync folder (Set up sync). It starts in the document's folder.

When a chooser closes, focus returns to the document, or moves to the next step of the command (the batch's formats, the sync computer's name). Escape cancels and says "Cancelled." If a chooser cannot open, textweaver says so and asks another way: a file's path in the one-line prompt (with F4 for the file browser), or a folder in the file browser's list.

Text size and font

  • Ctrl+Plus (Ctrl+=, or the plus key on the number pad): larger text.
  • Ctrl+Minus: smaller text.
  • Ctrl+0: back to the standard size, 14 points.
  • Ctrl+D, or the Font button: the font list. The fonts that come with textweaver are first, marked "built in": Atkinson Hyperlegible Next, Atkinson Hyperlegible Mono, and OpenDyslexic. Then your installed fonts. It is a list like textweaver's others: a letter moves to the next font starting with it, F1 says the list's name and size again, and Enter uses the font at once.

Each change is announced, for example "Text size 18 points." or "Font: OpenDyslexic.", and saved in [reading_aids.font] (see Settings). The size ranges from 8 to 72 points, stepping one point at a time around the usual sizes and more quickly above 16 points. The Settings dialog changes the same settings under "Reading aids".

Until you choose a size, the document's text follows your system's text size, as the rest of the interface does: with Windows' "Text size" at 150 percent, the standard 14 points is drawn as 21. Ctrl+Plus and Ctrl+Minus step from the size you see, and the size you reach is kept as your own. Ctrl+0 returns to the standard size, which follows the system again.

Cursor keys

The document moves its cursor with your system's keys, and Shift with any of them selects:

  • Windows and Linux: Left and Right by character, Up and Down by line, Ctrl+Left and Ctrl+Right by word, Ctrl+Up and Ctrl+Down by paragraph, Home and End to the start and end of the line, Ctrl+Home and Ctrl+End to the start and end of the document, Page Up and Page Down by screen.
  • macOS: Left and Right by character, Up and Down by line, Option+Left and Option+Right by word, Option+Up and Option+Down by paragraph, Command+Left and Command+Right to the start and end of the line, Command+Up and Command+Down to the start and end of the document (Home and End too), Page Up and Page Down by screen. No cursor key uses Control, so VoiceOver's keys (Control+Option) are never taken.

In browse mode, Home and End go to the ends of the line, as in any document window; in the terminal they go to the ends of the document, a role that Ctrl+Home and Ctrl+End fill here. In Speech Cursor mode (Alt+Shift+S, or Reading, then Speech Cursor, in the menus; Tab moves the focus here, as in any window, and is the terminal's key), Up and Down read the next and previous line and Page Up and Page Down move by paragraph, as in the terminal.

Keys

The app uses the same keymap as the terminal reader, plus a few chords the terminal cannot send. The keyboard reference lists every key, with a column for the app. The keys used most often are:

  • Space (browse) or Ctrl+Shift+Space: play or pause.
  • Escape: stop.
  • Alt+Down and Alt+Up: next and previous sentence.
  • Ctrl+O: open a document with the system's file chooser. Ctrl+Shift+G: type its path instead.
  • Ctrl+Plus, Ctrl+Minus, Ctrl+0: text size. Ctrl+D: the font list.
  • + (or =) and - while reading: faster and slower, as in the terminal reader; the number pad's plus and minus work too. In edit mode these keys type, so use the toolbar's Slower and Faster buttons or the command palette. On macOS Cmd+Option+] and Cmd+Option+[ change the rate in either mode. Ctrl+= and Ctrl+- size the text instead of the rate.
  • F11 or Alt+Enter: full screen (Option+Enter on macOS).
  • Ctrl+Alt+V (Cmd+Option+V on macOS): the voice manager (see Voices).
  • Ctrl+,: settings.
  • F2: the command palette, every command by its short name, with its key at the right edge ("Find next, F3"). Type to filter; Up and Down say each match; Tab or Ctrl+L moves to the list of matches, where your screen reader reads each with its place; F1 says what the selected command does, which is also each row's description; Enter runs one. With nothing typed, the commands you ran last from the palette or the menus come first, marked "recent".
  • The keyboard shortcuts list (? in browse, or the Help menu) has the same rows. Type to filter it by name, key, or menu ("12 of 226 commands match."); Page Down and Page Up move by group; F1 on a row says what it does.
  • F1: help. In a list, F1 repeats the list's introduction. Typing in the help starts Search help, which searches the commands, keys, settings and the bundled guides at once and says how many topics match; in its results, F1 says the selected topic's help without leaving the list, and Enter opens the topic. The Help menu has it too. Help, Documentation opens the bundled guides as documents in the app, following links between guides in place, with Backspace or Alt+Left to go back. The guides that come with an installed textweaver are read only, so the edit key says so instead of entering edit mode, and they stay out of the recent documents and the library, which remain a record of your own reading; Help, Online documentation asks before a browser opens. The reading guide describes both.
  • F3 and Shift+F3: the next and previous match of the last search (Ctrl+F), as in other Windows programs. The list of every key is on ? (browse) and in the Help menu.
  • Alt+Shift+S: Speech Cursor mode on or off. Tab moves the focus, as in any window.
  • Alt+End: say the last message and the status. In a list, it repeats the list's introduction too.
  • Alt+': say the last message again.
  • Alt+O: the outline. Type to filter the headings, Enter jumps to one.
  • Ctrl+Shift+N: the notes list. Space on a note opens its links (see Links between notes and tracked changes).
  • Ctrl+Shift+J: the list of tracked changes and comments in a Word, OpenDocument, or RTF document.
  • Ctrl+1 and Ctrl+2: the Contents and Notes panels beside the document (see The Contents and Notes panels).
  • F6 and Shift+F6: the next and previous region: the header, the panel, the document, the preview, and the toolbar.
  • Alt+F5: the preview pane beside the editor, on or off (see The preview pane).
  • Ctrl+T and Ctrl+Shift+T: next and previous table. Ctrl+Alt+arrows move by cell in a table.
  • k and Shift+K (browse): next and previous link. Alt+Shift+F follows a link.
  • Alt+Shift+A: the app's mode, one of two: "textweaver reads aloud" (documents in textweaver's voice, its messages for your screen reader) or "my screen reader reads" (textweaver is silent, and your screen reader reads the text). The Speak textweaver's messages setting (Settings, Window), off by default, has textweaver say its messages, typing and cursor moves too, for reading by ear without a screen reader; --self-voicing turns it on for one run. The View menu and the Accessibility mode setting show the same two names. In settings.toml the mode keeps the terminal reader's three values: "textweaver reads aloud" is saved as "hybrid", and "my screen reader reads" as "screen-reader".
  • F5: the next color theme.
  • F9: single-key shortcuts off or on.

The Contents and Notes panels

A panel beside the document keeps the document's headings, or its notes, in view while you read. It shows the same list as the outline (Alt+O) and the notes list (Ctrl+Shift+N), with the same names for each row, so the panel and the lists never disagree.

  • Ctrl+1 shows the Contents panel, and Ctrl+2 the Notes panel, and moves the focus to it. Your screen reader says the list and the row with its place, for example "Contents, Methods, level 2, 3 of 12", and textweaver says "Contents open, 12 items." Pressed while you are in the panel, the same key closes it and puts you back in the document ("Contents closed."). Pressed in the document while the panel is shown, it moves the focus to the panel.
  • Up, Down, Home, End, Page Up, Page Down, and a letter move in the list, as in any list.
  • Enter moves the document to that heading or note, says where it is as the outline does, and keeps you in the panel, so you can try the next one. Shift+Enter moves the document there and puts you back in the document. Escape puts you back in the document without moving it.
  • Space, in the Notes panel, opens the selected note's links as a list, exactly as Space does in the notes list. Closing that list returns you to the panel. When the Notes panel opens with notes in it, textweaver mentions this key once, after the count; the Contents panel has no such key.
  • F6 and Shift+F6 move between the header, the panel, the document, the preview pane when it is shown, and the toolbar.
  • The row where the cursor is has a bar beside it, and your screen reader hears ", current" after its name. While you are in the document, the panel's selected row follows the cursor, so going to the panel starts where you are.
  • The panel is a navigation landmark named "Contents" or "Notes".

The panel never takes focus on its own: when the app opens with a panel, or you choose one in the settings, focus stays where it was. The app remembers the panel you showed last (Settings, Window, "Panel beside the document"; sidebar in [gui], one of off, contents, or notes). A document without headings shows "No headings." in the Contents panel; a PDF without headings lists its pages, as the outline does. In edit mode, the Contents follow the headings you type once they are parsed again, as the outline does.

A closed panel costs nothing. While it is open, its rows are rebuilt only when the document, its headings, or its notes change, not as the reading highlight moves.

Two lists expose the structure around a document's text: the links between your notes, which together form a small knowledge graph, and the tracked changes and comments that other authors left in a document. Neither is drawn as a diagram. Each is an ordinary list dialog, identical to the one the terminal reader shows, and each row begins with its meaning, so that the first forty cells of a Braille line, or the first words your screen reader speaks, carry the substance of the row. Where a row is longer than the dialog is wide, the drawn row ends with an ellipsis, but your screen reader still reads the whole row. The terminal reader's guides describe both lists fully: Links between notes and Tracked changes and comments.

A note's links. Press Space on a note, in the notes list (Ctrl+Shift+N) or in the Notes panel (Ctrl+2), to open its links. Each link is a row that names its type before its target, for example "supports: Chapter 3 note". Two rows follow the links: "What links here", which lists the notes that link to this one, from this document and from every library document with notes, and "Add a link". In this list, Enter follows a link, opening the other document if the target lives there; F2 changes a link's type or target; and Delete removes a link after asking "Remove this link?". Adding a link asks first for one of the ten types, then for the target note. Typing in these lists filters them by type, and the dialog's title shows the filter so far; Backspace takes back one letter.

Tracked changes and comments. Ctrl+Shift+J (Command+Shift+J on macOS) lists every insertion, deletion, and move, and every comment thread, in document order, for example "Inserted: 'renal', by Ada Example, Tuesday, March 3, 2026". A date is said in full when the document records one, and "date not recorded" otherwise. Enter goes to the place in the text. On a change, A accepts it and R rejects it; Shift+A and Shift+R accept or reject every change by the same author. On a comment, F2 asks for a reply, Space marks the thread resolved (or open again), and Delete deletes the thread and its replies after a question. N adds a comment where a note would attach: to the selection, or to the text at the cursor. These letters act only with the case you type: a capital comes from Shift alone, so Caps Lock never turns a single acceptance into an acceptance of everything by one author.

Both questions, removing a link and deleting a comment, appear as the app's usual question dialog (see Questions): focus starts on No, the first button says Remove or Delete, and Y and N answer as in the terminal. Answering no keeps the link or the comment and shows the list again.

Editing

Ctrl+E, or the Edit button on the toolbar, turns edit mode on, as in the terminal reader. You edit the document's source: a Markdown file's own Markdown or, for other formats, the Markdown derived from them, which Save stores as a new .md file. Ctrl+E again, Escape when nothing is open or being read, or the Done editing button finishes, asking whether to save if there are changes.

In edit mode the document is a multi-line edit control, so NVDA and JAWS switch to focus mode on their own.

List items keep their indentation by depth while you edit, as in reading, and bulleted items keep their bullet shape (a disc, a ring, then a square), so the nesting remains visible. A numbered item shows the number you typed. These shapes are drawn only; the screen reader reads the source text, with its own dashes and numbers.

  • Typing is inserted at the cursor, replacing the selection if there is one. Enter starts a new line (and continues a list), and Backspace and Delete delete. Input methods and dictation work as well.
  • Your screen reader echoes what you type and reads the cursor and the selection as they move. With Speak textweaver's messages on, textweaver speaks them itself, as the terminal does: typing according to the typing echo setting (Shift+F9 cycles it), the character, word, or line the cursor moves to, and what a Shift key added to the selection or removed from it.
  • Copy, cut, and paste: Ctrl+C copies the selection and Ctrl+X cuts it, each saying what it took; Ctrl+V pastes what is on your system's clipboard at the cursor (on macOS, Command with each). Formatted text copied from a web browser, a word processor, or another editor is pasted as Markdown, keeping its headings, lists, emphasis, links, tables, and code, and textweaver says what came in, for example "Pasted as Markdown: 1 heading, 3 paragraphs, 1 list". Paste as plain text (Ctrl+Shift+V, or Ctrl+Shift+M, or in the context menu) inserts only the clipboard's text. Either paste is one undo step. The app reads the clipboard's HTML on every system (on macOS the pasteboard's HTML, on Linux the Wayland or X11 clipboard's); RTF is read on Windows only, and word processors put HTML beside it elsewhere. When the clipboard has no HTML, the plain text is pasted.
  • Undo is Ctrl+Z and redo is Ctrl+Y or Ctrl+Shift+Z; each announces what it reversed. The editing keys are the terminal's: Ctrl+B bold, Ctrl+I italic, Ctrl+K a link, Ctrl+Alt+1 a heading, and the rest in the keyboard reference. Ctrl+S saves.
  • Tab types a tab, or in a table moves to the next cell (Shift+Tab to the previous one), as in the terminal. Ctrl+Tab moves focus out of the document to the buttons.
  • Markdown lint: Ctrl+F8 moves to the next lint problem (a skipped heading level, a mixed list marker, a bare web address) and says it; Ctrl+Shift+F8 goes back. Ctrl+F7 moves to the next grammar problem and Ctrl+Shift+F7 to the previous one, as in the terminal (Editing).
  • Find and replace: Ctrl+Shift+F opens the Find and replace panel: Find what, Replace with, check boxes for Match case, Whole words, Regular expression, and Across lines, and the Find next, Replace, Replace all, and Close buttons. Enter in Find what finds the next match and Enter in Replace with replaces it; Up and Down recall earlier entries; F3 and Shift+F3 work throughout; Escape returns to the document. An invalid pattern is explained beside Find what, and each match is previewed there before it changes. The panel uses the same search, options, and undo steps as the terminal's replace loop (Editing).
  • Spell check: Alt+M moves to the next misspelled word and selects it, so your screen reader says it and textweaver spells it. Type to replace it, or press Alt+J for suggestions. Alt+Shift+M goes back. Misspelled words are also marked on screen with a dotted underline, shortly after you stop typing (in documents up to a million characters).
  • Citations while writing: Alt+C opens the citation picker. Type part of an author or title to filter, Enter inserts it, and textweaver asks for a page or other locator. Alt+Shift+D adds a reference by DOI or ISBN.
  • Export and preview: the command palette (F2) and File, Export as, offer a web page, PDF, Word, EPUB, braille (BRF), and the other formats of Converting documents. Export asks where to save and under what name, as Save as does. Preview in the browser reloads itself according to the setting "Browser preview follows": never, after each save, or also when typing pauses.
  • Ctrl+Tab and Ctrl+Shift+Tab move between the document and the buttons, so you are never trapped in the editor; Ctrl+E is always the way out of edit mode.

The preview pane

While you edit, the window can show the document beside the editor as it will read: headings at their sizes, lists with their bullets and numbers, tables, code, callouts, math, and images by their captions, all drawn by the same view that shows a document you are reading. The pane is off by default because it takes half of the window and most writers want the room. Turn it on with Alt+F5, with Show preview in the View menu, or by typing show preview in the command palette; textweaver says "Preview shown beside the editor. F6 moves to it." and remembers the choice (Settings, Preview, "Preview pane"; pane in [preview]). The same key turns it off. Turned on outside edit mode, it waits, and appears the next time you edit.

The preview follows your writing without getting in its way. It is rebuilt only after you pause typing, 300 milliseconds by default ("Preview pause", pane_delay_ms, from 100 to 3000), and the work happens away from the keyboard, so typing is never slowed. It tracks the cursor: the block you are writing in scrolls into view and is marked as the spoken sentence is marked while reading, with a band and a line under it, so the mark never depends on color alone. Nothing is announced when the preview changes, and focus and the cursor stay in the editor.

To read the preview, press F6 from the editor; Shift+F6, or F6 again past the toolbar, returns. The preview is a region named "Preview" that holds a read-only document, so your screen reader reads it like any other document, with the usual reading keys, while the editor keeps its cursor where you left it. The word "Preview" is drawn in its corner, as "Editing" is in the editor's.

In a wide window the preview stands to the right of the editor. In a narrower one (below 800 pixels beside the panel) it goes under the editor instead, and in a window too short for both, it is hidden so the editor keeps its lines; Alt+F5 then shows it and moves you into it, and it hides again when you go back to the editor.

The spoken word

While textweaver reads, the spoken word has its own background color and the cursor sits at its start, so that your screen reader and Braille display follow the reading. This default was chosen after the first screen reader session; --select-spoken selects the word instead, for anyone who prefers that.

A very long document is shown a few hundred pages at a time, around where you are. When reading reaches the edge of that span, the app moves on by itself, and the text that remains keeps its place so that your screen reader does not lose it.

Questions

When textweaver asks a yes-or-no question (a voice to download, after its size and license; a voice to remove; a file changed on disk), the app shows it as a small dialog. The question is the dialog's name, without the "y or n" that the buttons already show, so your screen reader speaks it, and focus starts on Yes. Press Y or N, as in the terminal, or Tab to No and press Enter. Escape answers no, and any other letter asks the question again.

A question that deletes, removes, or replaces something (a note, a highlight, a link between notes, a comment, a profile, a voice, a downloaded component, a file that already exists) starts on No instead, so that pressing Enter keeps things as they are. Its first button names the action, Delete, Remove, or Replace, rather than "Yes". The keys are the same: Y goes ahead, while N and Escape keep things.

Closing the window

Closing the window with its close button or Alt+F4 quits exactly as Quit (Ctrl+Q) does, without asking "Quit textweaver?". If you have unsaved edits, it first asks the same question Ctrl+Q asks: save, discard, or cancel. Cancel keeps the window open with your edits. An open dialog closes first, as Escape would, so that the question you see is the one in front.

Voices

Press Ctrl+Alt+V (Cmd+Option+V on macOS), or choose Speech, then Choose a voice, from the menus, to open the voice manager. It is a dialog named "Choose a voice" that lists every voice of every engine on this computer: Eloquence, SAPI 5 (with the OneCore voices), DECtalk, eSpeak NG, Piper, and, on macOS, Apple's voices. The voices are the terminal's, with the same names, filters, and favorites. Focus starts in the list, named "Voices", on the voice in use.

From top to bottom, Tab moves through:

  • Language and Engine, two buttons that filter the list. Each press restricts the list to the next language or engine, and eventually returns to all of them, announcing what is shown, for example "3 voices: English, all engines." The button's name states the filter: "Language: English".
  • The list of voices. Each says its name, language, engine, and tags; "favorite" for a favorite and "current" for the voice in use. Favorites come first. A Piper voice you can download says its size and license. A favorite from another computer that no engine here has is listed last as "not on this computer". The other engines' voices are listed in the background when the manager first opens; they join the list as they arrive, and you hear how many came.
  • Use voice (Enter in the list): uses the voice and speaks a sample. On a voice of another engine, textweaver switches engine. On a voice you can download, textweaver reads its license and size, then asks before downloading.
  • Preview (Alt+End in the list, the Say Status key): speaks a sample in the voice without choosing it, starting with the voice's name. A voice of another engine is previewed by starting that engine for the sample and closing it again. A voice you have not downloaded, or one not on this computer, says why it cannot be heard.
  • Favorite (Space in the list): adds the voice to your favorites or removes it.
  • Remove (Delete in the list): removes a downloaded Piper voice, after a yes. On a voice that cannot be removed, the button is unavailable: it says "Remove, unavailable", your screen reader says "unavailable", and its description gives the reason, "Only downloaded Piper voices can be removed." It stays in the Tab order, so you can land on it and hear why.
  • Fetch the Piper voice list from the internet, when it can be fetched: asks first, then downloads the list of Piper voices, about 250 KB.
  • Close (Escape).

Every button carries its key as its shortcut and a short description, which NVDA and JAWS read as for any button. Enter or Space presses the focused button. The Help key and the Say Status key (Alt+End) also work with focus on a button, as they do in the list; Alt+End previews the voice focused in the list.

Language

The app's own labels (the buttons, the settings dialog, the hints) follow the interface language, [interface] language in settings.toml, as textweaver's messages do. Change it in Settings, under "Interface", and the app relabels itself immediately.

Announcements

textweaver's messages ("Paused.", "Reading at 300 words per minute.") reach your screen reader in one of two ways:

  • A live region (the default). NVDA and JAWS both speak it.
  • UI Automation notifications (Windows only). Choose it in Settings, under "Window", or with --announce uia for one run.

The setting is announce in the [gui] section of settings.toml; see Settings.

Messages spoken while the app starts ("Opened", the title, "Reading at") wait until your screen reader has asked for the window's contents and are then spoken once; previously they could be lost when the app was quicker than the screen reader.

When the window takes focus (Alt+Tab, a click), your screen reader announces the window's title, which is the document's title and "textweaver", and then the document. With Speak textweaver's messages on, textweaver says the document's title and its own name in its own voice.

How much textweaver says about its own interface is your choice: set [accessibility] interface_announcements, or press Ctrl+F9 to step through off, minimal, normal, and full. The app's messages follow it as the terminal's do. Errors and the answers to what you asked (a count, the font you chose) are always spoken; a dialog closing, the hint that no document is open, and the first run's welcome are spoken from normal upward. In the screen reader and hybrid modes the level starts at minimal, since your screen reader already announces what opens and closes.

Reading aids

The app draws the same reading aids as the terminal, with the same keys:

  • Text spacing: line height, paragraph spacing, and letter and word spacing, in [reading_aids.spacing]. The app uses the exact values; the terminal rounds them to whole rows and spaces.
  • The reading ruler (Alt+Shift+U): off, the current line, or the ruler. The reading line gets a band with a bar at its start, the lines around it a paler band, and with mask_outside the rest is dimmed. It follows the cursor, and the spoken word while reading.
  • Bionic reading (Alt+Shift+B): the start of each word in bold.
  • Difficult words (Alt+Shift+J): underlined with a thick line, never marked by color alone.
  • Syllables (Alt+Shift+Z): long words drawn split into syllables with a middle dot, "read·a·bil·i·ty", as in the terminal. The dot is only drawn: the words keep their letters, so your screen reader and Braille display read "readability", and the cursor and the spoken word stay where they were. The separator and when words are split are in [reading_aids.syllable_options].
  • RSVP (Alt+Shift+R, then Alt+Shift+P to play): one word at a time in its own strip under the document. The word before and after sit to its left and right. The marked letter is bold and underlined as well as colored. RSVP's nine places move the word left, center, or right in the strip.

Notes, highlights, bookmarks, and search matches are drawn too, each with a shape as well as a color, so no color carries it alone: each of your highlight names has its own color and shape, as in the terminal reader (a line under the text, a double line, bold text, a dotted line, brackets, or a small square at the start; see Highlight colors), text with a note a dashed line, a bookmark a bar before it, a search match a box around it, and the match at the cursor a heavier box. While you listen, the spoken sentence is underlined and the spoken word is bold, on top of their bands, as in the terminal. The bold is drawn in place, so the line never shifts as the word moves. Marks inside the sentence stay visible while it is read. The spoken word's and sentence's colors follow [highlight] color and sentence_color, as in the terminal.

Exploring a formula (Alt+Shift+X) works as in the terminal: Right and Left move to the next and previous part, Down goes into a part and Up out of it, Home and End go to the first and last, Space or Enter says it again, and Escape leaves. Any other key leaves the formula and does what it usually does.

All of these change only how text looks; your screen reader reads the same text either way. The RSVP word is hidden from screen readers, so it is never spoken by itself. Beside it is a quiet status ("RSVP paused, word 120 of 900") that you can find with your screen reader's review or object navigation.

After an update

The first time the app starts after textweaver has been updated, it says "Updated to" and the new version number, for example "Updated to 0.1.0-beta.1", followed by where to read about the changes. The notice is spoken once, after the opening message, and only when the version differs from the one that last ran on this computer. That version is then remembered as a machine setting ([gui] last_version) that never syncs, so another computer gives its own notice. A first run has its welcome instead, and background runs say nothing.

Colors and high contrast

The app starts in the theme your settings choose and follows your system's light or dark setting as the terminal reader does (display.follow_os_theme, on unless you picked a theme). The system's setting is read while the rest of the app starts, and not at all with --theme or a theme you picked. F5 moves to the next theme.

With Windows High Contrast on (Contrast themes in Windows 11), the app draws with your contrast theme's own colors for its page and text, its highlight for the spoken word, the selection, the focus ring, and links. Turning it on or off applies immediately. Marks that have a tint of their own in textweaver's themes (the reading ruler's band, notes, bookmarks, search matches) keep their shapes instead: the ruler's bar, the lines and boxes. The spoken sentence has no band then; its underline, in your contrast theme's text color, marks it. The focus ring stays visible: when the highlight color is too close to the page, the ring is drawn in the text color. --theme, or follow_os_theme = false in [display], keeps textweaver's own colors.

On macOS and Linux, the system's increased-contrast setting chooses textweaver's high-contrast theme when the app starts.

The title bar and the menus follow the theme too: a dark theme such as Galaxy gets a dark title bar, and on Windows a dark menu bar and dark drop-down menus, whatever Windows' own light or dark setting; a light theme gets light ones. The theme's page color decides. Changing the theme (F5, or Settings) changes them at once. With Windows High Contrast on, Windows draws them in your contrast theme's colors instead. Dark menus need Windows 10 version 1809 or later; on older versions they stay light.

The Colors dialog

View, then Colors (or File, Settings, Colors) opens every color textweaver lets you choose in one list: the spoken word's and sentence's highlights first, then the reading ruler, difficult words, syllable marks, misspellings, lint marks, search matches, the selection, the focus outline, links, headings, the status bar, notes, and bookmarks.

  • Left and Right choose from named colors, said in words ("dark blue", "gold"). Blue and orange come first: a pair that stays distinct for red-green color blindness.
  • Enter types a color name or a #rrggbb value.
  • Delete puts the theme's own color back for that part. The Reset all colors button puts it back for every part.

Each row states its color and how well it stands out where it is drawn, as a ratio and a word, for example "blue, contrast 4.8 to 1, good". A ratio of at least 4.5 to 1 is good, at least 3 to 1 is fair, and anything lower is low. Every row is measured, including a part left at the theme's own color, which is measured as the theme draws it: a band against the text drawn on it, and text or a mark against the page. Below 3 to 1 the change is still made, and you are told it will be hard to see. A small sample of the color is drawn beside the value, but the words always say it. Changes apply at once, and every mark keeps its underline, weight, or symbol whatever its color, so color never carries meaning alone.

After the colors come your highlight names, one row each, in palette order: "Highlight name important: yellow, underline, contrast 1.2 to 1 with the text and 14 to 1 with the page, low". A highlight is a band behind text, so both ratios matter, and the word that ends the row describes the lower of the two. When either is under 3 to 1, the row's description, which a screen reader reads after its value, is the same warning a low color gets. These rows are read only, because the palette is a table in settings.toml ([[highlight.palette]]); Enter on one says so. Notes and highlights explains the palette and its shapes.

With Windows High Contrast on, the system's colors take precedence. The app draws your contrast theme's colors instead of these settings, so the dialog stops measuring them: its help says that the system's colors are on, each color row says it is not drawn while they are, and no sample is shown. Your choices are kept and apply again when High Contrast is turned off. Each highlight name still says its color and shape, and the shapes still differ from one name to the next, so the names remain distinct without any color at all.

Settings

Settings (Ctrl+,) opens a dialog with the sections on the left and the chosen section's settings on the right. Every change takes effect and is saved immediately. A switch shows its value in words beside it ("on", "off"), and with a mouse the arrows beside a number or a choice step it in the direction they point. The dialog is built from the same list as the terminal's settings screen, so every setting appears in both; Settings describes each one.

The Reading settings dialog

View, then Reading settings (or Tools, Reading settings) opens the settings you change most while reading, in one list with the same rows as the Settings dialog: the rate; the font, its size and weight; line height, paragraph spacing, word spacing and letter spacing; the line length; the theme; what the highlight covers and its word and sentence colors; the reading ruler and its mask; bionic reading; and syllables. Below the list:

  • Voices closes the dialog and opens the voice manager.
  • WCAG spacing sets the four spacings to the values WCAG names (line height 1.5, paragraph spacing 2, letter spacing 0.12, word spacing 0.16), and Generous spacing to wider ones (2, 2.5, 0.15, 0.3). It says which, once, and the rows show the new values.
  • Close (Escape) closes it.

In the terminal, the same command shows the settings screen with only these settings, as View, Colors does for the colors. The line length is the app's own, so the terminal lists the other sixteen.

Export settings and Import settings are under File, then Settings (Alt+Shift+E and Alt+Shift+I). Export opens your system's Save dialog, offering textweaver-settings.toml; a name ending in .json writes JSON instead. It writes every setting and your key changes. Import opens the system's Open dialog for a TOML or JSON file, checks it, and then asks before changing anything, naming the first changes: "Import 12 changed settings from home.toml: Rate, Theme, Link color, and 9 more? y or n". Yes applies them at once and says what changed; no leaves everything as it was. If the system's file chooser cannot open, a prompt asks for the file's path instead.

Size, place, and when something goes wrong

  • The window remembers its size and position on this computer. It opens where it was closed, maximized if it was maximized. A position on a screen that is no longer connected is ignored, so the window never opens where you cannot see it. This is kept per computer and is not synced.
  • Text follows the system's text size. Interface text grows with the Windows "Text size" setting or the GNOME text scaling factor, and the document's text does too until you choose a size for it (see Text size and font).
  • The app is idle when nothing changes. It checks for work four times a second while you read or pause, and twenty times a second only while an edit waits to be parsed or the status line is reading; a check that finds nothing new does not redraw.
  • The caret blinks as the system's does, or not at all when the system is set that way.
  • The app draws opaque on every graphics API. It requests an opaque drawing surface, never one that blends with what is behind the window. Up to alpha.9, with auto on Windows (which picks Vulkan on an NVIDIA card), the menu bar was see-through because the driver offered a blended surface and the app accepted it; --graphics dx12 hid the problem, since Direct3D 12 offers only opaque surfaces for a window. --log names the surface on the "graphics adapter" line ("surface opaque").
  • The icon is the loom, textweaver's logo, in the title bar, the taskbar, and on the programs in Explorer and their shortcuts (textweaver.exe and tw.exe carry it). In Windows High Contrast the app uses the one-color loom, white on black. The Linux menu entry uses the same drawing.
  • The app requests the integrated graphics adapter when the computer has one, because it draws text just as fast and saves battery. To use the discrete adapter instead, set the environment variable WGPU_POWER_PREF to high.
  • A log file. The app writes warnings and errors to textweaver.log in the state folder, as the terminal reader does. Troubleshooting says where it is.
  • After a failure, the app saves your unsaved edits as a recovery copy, along with your place and settings, and offers the work back at the next start (see Recovering unsaved work). Signing out, shutting down, or restarting does the same. On Linux and macOS, so does a termination signal: closing the terminal the app was started from, Ctrl+C in that terminal, or the system ending the program (SIGHUP, SIGINT, or SIGTERM). The app saves, then closes.
  • If graphics cannot start, the app says so in words, with a message box when it was started from a shortcut. See The app does not open, or it is blank.

Study, marks, and files in the app

The study and marking commands are the same in the app as in the terminal reader, with the same lists and messages. Their guides give the app's keys where they differ.

  • Highlight names. Alt+1 to Alt+5 highlight with the first five names in your palette, and the highlights list (Shift+Y) says each highlight's name. The app draws each name in its own color and shape, as the terminal reader does, and gives a screen reader the name in words on the text it covers (Highlight colors). The Colors dialog lists each name with its measured contrast (The Colors dialog).
  • Study cards and the self-test. The Bookmarks and notes menu has a Study cards submenu, and the notes list (Ctrl+Shift+N) and highlights list make a card with C. Cards, grades, and due dates are described in Study with cards. After you press Enter in the self-test, the revealed answer is said once.
  • Links between notes and tracked changes and comments are lists; see Links between notes and tracked changes. Accepting or rejecting a change, and saving your own edits to a Word file as tracked changes, work as described in Reading and Editing.
  • Files. Browse files in the File menu walks folders and archives as one list (Reading). The formats added in beta 1 (Org, reStructuredText, MediaWiki, DokuWiki, and Jira markup; braille files; DAISY books with their recorded narration) open in the app as in the terminal reader.
  • Help. Help, then Documentation, opens the full guides inside the app, and Search help searches commands, keys, settings, and the guides together (Reading).

What only the terminal reader does

Every command works in the app as in the terminal reader, from the same keys, the menus, and the command palette (F2), with the same lists, questions, and messages. A few commands are meaningful only in a terminal, and the app's menus and command palette omit them. If a key for one is pressed in the app (j or Shift+J, say), the app says "This command works in the terminal reader." and does nothing else:

  • scroll_down and scroll_up: the terminal scrolls its screen by lines. The app scrolls with the mouse wheel and keeps the cursor in view.
  • toggle_line_numbers: line numbers are the terminal's margin, on F6 there. In the app, the status bar says the line, and Say Position (Shift+W) says it too; F6 moves between the app's regions instead.

The command-line tools (tw vault, tw convert, tw library, and the rest) are the same for both readers.

For testers

  • --background starts the app without taking focus, off screen, with no taskbar button, for automated checks. On Windows the app is marked as one that accessibility tools must not activate (WS_EX_NOACTIVATE). UI Automation still activates it on the first control pressed through it; the app then hands the foreground straight back to the app that had it, and --log records this. Expect a brief flicker of focus, not a lost one.
  • A debug build writes Masonry's full trace log only when MASONRY_DENSE_LOG_DIR names a folder for it (for example target\masonry-logs); otherwise it writes none. It never goes to the system's temporary folder.
  • --backend paced reads silently, timing words like a real engine.
  • crates/textweaver-xilem/tools/uia-report.ps1 reports what UI Automation sees (Windows), including the menu bar's seven menus and access keys and every menu item's text and key as the app's menu holds them; -WindowEdge reads past the document window's edge; -Menus also opens the first menu to read its items through UI Automation (opening a menu may bring the app to the front, so use it on a test machine). tools/atspi-check.sh does the same with AT-SPI on Linux.
  • --log lists the menu items the app built, one per line, with each key after a tab.
  • --review-screenshots FOLDER draws the review screenshots without a window: four themes at 100% and 200%, the dialogs, the reading aids, the reading ruler on its own, edit mode, the app with no document, the Contents and Notes panels, and the app at 960 by 540, 683 by 384 at 200%, and 420 by 320. Give it a folder outside docs/, such as target/review-screenshots; the full set is for review and is not kept in the repository. A curated set of eight, each picture with a description, is in the app in pictures. It, --screenshot, and --measure-frames need the screenshot feature (in the default build); a build without it ends with an error that names the option, and no window opens.
  • --log also says how the title bar and menus are drawn: "frame: dark", "frame: light", or "frame: system" (high contrast), and how the drop-down menus are drawn ("drop-down menus: dark", "light", or "light, because dark drop-down menus are unavailable" on a Windows that lacks a call dark menus need), at startup on the "menus: native" line and again on each change; and "menu bar shown" and "menu bar hidden" while auto_hide_menu is on.

Checking the title bar and menus by hand

Colors cannot be heard, so the color steps need a sighted helper, a screenshot read by a color tool, or the --log lines above. Use a throwaway state folder (--home %TEMP%\tw-frame) and run the steps once with NVDA and once with JAWS.

  1. Dark theme, Windows light. In Windows Settings, Personalization, Colors, choose Light. Start textweaver --log --home %TEMP%\tw-frame. Expected: the log says "frame: dark"; the title bar, the menu bar, and an opened File menu are dark, with light text.
  2. Dark theme, Windows dark. Choose Dark in Windows and start again. Expected: the same, dark.
  3. Light theme, Windows dark. Press F5 until a light theme is chosen, such as Galaxy Light. Expected: "frame: light" in the log at once, and a light title bar, menu bar, and menus, though Windows is dark.
  4. Light theme, Windows light. Expected: light, as in step 3.
  5. High contrast. Turn on a Contrast theme (Left Alt+Left Shift+Print Screen). Expected: "frame: system", and the title bar and menus in the contrast theme's colors, whatever textweaver's theme. Turn it off: the frame follows the theme again.
  6. Menus still read. In each step, Alt, then Down: NVDA and JAWS say "menu bar", then "File" and the first item with its key, as before. Escape twice leaves.
  7. Hiding the menu bar. The bar is hidden by default. If you turned it off before, turn "Hide the menu bar" on in Settings, under Window. Expected: the bar disappears and nothing is said beyond the setting's own message. Then:
  8. Alt alone: "menu bar" is said, as before, and the bar is shown. Escape: the bar hides again, silently.
  9. F10: the same.
  10. Alt+F, Alt+E, Alt+V, and each other menu's letter: that menu opens and is read.
  11. Alt+Space: the window's system menu, as before.
  12. A key the keymap gives Alt with another key (see the keyboard reference) still does its command; the bar may appear for a moment and hides again.
  13. Choose a command from a menu: it runs, and the bar hides.
  14. Turn it off. Expected: the bar is back at once, and stays. Turn it on again if you want the default back.

Please note which steps did not behave as expected, with the screen reader and its version, and the Windows version.

See also