4: The Main Window - transcript

Download the MP3

Jessica: The QUILL Cast, episode four. I'm Jessica. Today Liam and I are going to walk you through the main window, and I mean really walk through it, every part of it, because this is the room you will be living in for the next fifty episodes. If the editor is the desk, the main window is the office, and the office has a personality that is worth knowing in advance. We will end with the setup for episode five, which is notebooks and versions.

Liam: I'm Liam, and before we start I owe you a recap of where we just were, because the series is meant to compound. Episode three, your first document, was about files: control N for new, control O for open, control S for save, control shift S for save as, the recovery safety net that lives underneath the autosave, position memory that puts your caret back where you left it, the New from Clipboard trick, and the honest rule that in QUILL the answer to did I just lose my work is meant to always be no. Episode two was the installer and the wizard. Episode one was the introduction. We are now in the orient arc, which runs through episode seven, and the orient arc is the one that gets you to a place where you can do real work without the rest of the series.

Jessica: Today's frame is small and honest. The main window has three permanent regions: the menu bar at the top, the editing area in the middle, and the status bar at the bottom. That is the whole shell. Every feature we will ever cover is a menu item in that bar, a dialog that opens from a menu item, a panel you can pin into the middle, a key chord, or a Quillin you can install. There is no second window competing for your attention, no chat sidebar stealing your cursor, no floating ribbon, no system tray icon humming in the background. The design is open, write, save, close. Everything else is opt in, and the menu bar will reflect that, because the menus are built from the active feature profile, so what is off for you is not on the bar at all.

Liam: A small honest correction before we go further, because we promised at the top of the series that we would verify every claim against the code. The very first version of this episode, and the older help text you may have seen in earlier builds, described the menu bar as having seven top-level menus. The current build of QUILL, the one you would actually download today, has twelve top-level menus. We read the menu builder at quill slash ui slash main frame menu dot py, line twenty-six fifty-five onward, and the order it attaches to the menu bar is, in this order: File, Edit, View, Insert, Format, Navigate, Search, Tools, AI, Window, and Help. That is the actual order, and the AI menu only shows up if your profile has AI enabled, so your bar may be eleven menus, not twelve. Anyone reading older notes who only finds ten should look for the Insert and Search menus, which are the two that did not exist when the design doc was first drafted.


Liam: Let's start with the menu bar itself, because it is the most learnable part. To enter the bar, press alt. That puts focus on the first menu, which is File. Arrow right to move to the next menu, arrow left to move back, up and down to walk the items inside a menu, enter to choose, escape to leave. Every item that has a keyboard shortcut shows it on the right side of the menu, which is also a small gift: every trip through a menu is a shortcut lesson. The order of the menus is deliberate. File is for documents in and out. Edit is for changing text. View is for how the editor displays. Insert is for putting things into the document, dates, snippets, headings, special characters. Format is for structure and styling. Navigate is for moving through a document. Search is for find, replace, and similar tools. Tools is the big one, reading, speech, macros, watch folders, status bar, GLOW, comparisons, the workshop. AI is the assistant surface. Window manages tabs. Help teaches.

Jessica: Two menu behaviors to notice, and they are both important. First, menus respect your profile. A feature that is off for you is not on the menu, which is why your menu bar might differ from a friend's, and why a tutorial you watch online might show an item that is not on your bar. The product is filtering, not hiding, so the underlying command is still reachable through the command palette we will meet in episode six. Second, the menus are keyboard-clean. Open one, arrow through it, hit escape, focus returns to the editor. You will never get stranded inside a menu, and that is the rule, not the exception, because there is a test for it. The dialog inventory and dialog button contract gates in the build process catch the case where a menu or a dialog steals focus or breaks the escape contract, and they fail the build if it happens.

Liam: For the profile-aware part, a quick example helps. If you are in the Essential profile, which is the one that ships turned on by default, the menu bar is File, Edit, View, Insert, Format, Navigate, Search, Tools, Window, and Help. The AI menu is filtered out, so it does not show. If you switch to the Author profile, which unlocks the writing tools, more items show up under Insert and Format. If you switch to a profile with the vault enabled, a new menu appears under Tools. The bar is a live reflection of what you have chosen, which is part of why the orient arc is worth doing in order, because every later episode assumes a feature is on, and the profile picker is the off switch you can reach from Help, Feature Profiles, Switch Profile.


Jessica: The editing area is the part you will spend the most time in, and it is the part that is genuinely simple. Each open document is a tab. Control tab cycles forward, control shift tab cycles backward, and each landing announces the document name. The Window menu lists every open document for direct jumps, and there is a row of accelerator keys, alt one through alt zero, that go to the first through tenth open document in order. That is a screen reader first design, because alt digit is a known comfortable chord, and the discoverability is high: the menu tells you which document is which position.

Liam: One thing the older tutorial videos do not mention, because it is recent, is that the tab strip itself is optional. In the View menu there is a checkbox labelled Show Tab Control. If you turn it off, the editor uses a Simplebook behind the scenes, which is a tab container that has no visible strip at all. The tabs are still there, control tab still cycles them, the Window menu still lists them, but you do not see the strip. Some screen reader users prefer the strip hidden, because the strip and the file name get announced twice on every switch, and the file name alone is enough. Some sighted keyboard users prefer the strip off because the screen is cleaner. The product supports both. The default in the Essential profile is the strip on, but flipping it is a checkbox away, and the change persists in your settings.

Jessica: Tabs are not just files, either, and this is the part of the design that pays off later. Audit reports open as tabs. Compare summaries open as tabs. AI chat sessions open as tabs. Search results, spell check lists, sticky notes, the print preview, all of them open as tabs. One mental model: everything is a readable document. You navigate them all the same way, control tab to move, alt digit to jump, escape from any embedded view, and the status bar tells you what is going on. There is no second window, and there is no "save your work in this other kind of place" surprise, because there is no other kind of place.

Liam: A small but useful detail. The tab host is given a name, Open documents, and you can confirm that by tabbing into the area and listening. The naming is deliberate, because the raw wx widget underneath is a wx Notebook or a wx Simplebook, and without the name a screen reader announces only the class, which is useless. The name is set in the code at quill slash ui slash main frame dot py, in the create tab host method, and the name is one of the small things that makes the tab strip feel like part of the editor instead of part of the chrome.


Liam: Here is a part to do right now. Pause the audio. Open QUILL. If you do not have a second document open, press control N to make one, type a few words, and you now have two tabs. Then press control tab to cycle between them. Notice the name. Now press alt, then the number one, and you jump to the first tab. Press alt, then the number two, and you jump to the second. Then press alt, then the letter W, to open the Window menu, and arrow down to see the list of open documents. Press escape to leave the menu. When you are ready, press play and come back. We will be right here.

Jessica: Welcome back. If you heard the names and felt the jumps, you have just learned the most-used set of shortcuts in the entire product. Everything else in the next fifty episodes sits on top of this. Find a file, it goes in a tab. Compare two files, the summary goes in a tab. Open a vault entry, it goes in a tab. The Window menu is the index, and alt digit is the short form. The control tab and control shift tab pair is the casual form. Either one works, and you will fall into whichever one feels right for the day.


Jessica: Now the status bar, which in QUILL is genuinely a narrator, not a decoration. The bar runs across the bottom of the window and is divided into cells, each cell a small button you can activate. The leftmost cell is the Status Message cell, and it is the one that always shows the last thing that happened. Save a file, the cell reads Saved. Run a search, the cell reads twelve matches found, or no matches, depending. Open a notebook, the cell reads Notebook Whatever opened with however many entries. Every state change in the product routes through this one cell, which is the visual floor of the announcement system.

Liam: The status bar is a button strip, not just a text strip, which is a real design choice. Each cell is keyboard reachable. F6 jumps to the status bar, shift F6 jumps back. Once you are in the bar, left and right arrows move between cells, home and end jump to the ends, escape returns you to the editor, and enter activates the cell. The cell called Word Count activates the document statistics dialog. The cell called Search Term reopens the find dialog with your last query. The cell called File Path opens the folder that contains your document. The cell called Language opens the language profile chooser. The cell called Screen Reader runs a re-detection and announces the result. The cell called Status Message opens the notifications list. We will cover each of these in detail in their own episodes, but the unifying idea is: the bar is not a label, it is a toolbar you can drive with the keyboard.

Jessica: The cells are user-configurable, which is the part that matters once you have used the product for a week. Right-click any cell, and you get a context menu with Activate, Hide this item, and Status bar settings. Hide this item removes the cell from your bar; the change is written to your settings file the moment you choose it. The Status bar settings item opens a dialog that lets you reorder, show, and hide every cell, with a Restore Defaults button if you want to go back to the shipped layout. The shipped layout is a sensible middle, but the product assumes you know your own preferences better than the developers do. There is no wrong answer, and your settings file is the place your answer lives.

Liam: The cells you see depend on what is happening. The Spell Check cell only appears when spellcheck as you type is on. The QUILL Key cell only appears when the QUILL key is active or the prefix is pending. The Read Aloud cell only appears when read aloud is speaking or paused. The Background Tasks cell shows the count of running background work, like a download or a conversion, and goes to Idle when nothing is running. The Notifications cell shows the count of unread notifications, or the words No new messages when the list is empty. The bar is a live status board, not a static label, and the design assumes you will glance at it, or listen to it, the way a pilot glances at a cockpit.


Jessica: The most important thing about the status bar, and the part the visual-first design tries not to break, is the announcement channel. The status bar is the always-on visual floor. If something is saved, the bar reads Saved. If something fails, the bar reads the failure. The bar never goes silent, because the bar is the contract, not the speech. The screen reader speech, the thing you hear, is a second channel on top of the bar, and it is governed by the verbosity system, which lives in quill slash core slash verbosity. The verbosity controller, once you have engaged it, decides whether the speech is suppressed in Quiet mode or Meeting mode, and it keeps a history so you can ask what just happened and get an answer. But the visual floor is always on. If you turn every sound off, if you mute the speech, the bar still tells you what just happened. That is the rule.

Liam: That rule is in the code in a very specific shape. The set status method on the main frame always sets the message attribute and always refreshes the status bar. The announcement path, which is the speech path, is the thing that can be suppressed. There is a method called set status quiet for the cases where the message updates many times a second, like the modified state during typing, which is updated as you type but not spoken on every keystroke. The screen reader already echoes what you type, so the bar updates silently to avoid double announcement. For everything else, the bar is honest and the speech is optional. We will spend a whole episode on the verbosity system later in the series, but the takeaway today is the simple shape: the bar is the floor, the speech is the ceiling, and you control the ceiling.


Jessica: The Spoken Echo is the feature that ties the visual floor and the speech ceiling together, and it is the feature you will use most without planning to. The Echo is a read-only dialog that virtualises the last several announcements into a list you can arrow through, re-read, and copy from. The default key chord, which we verified in quill slash core slash keymap dot py line three fifty-five, is alt shift E. The chord is free, in the sense that alt shift letter is not a screen reader hostile zone, and the E is for echo, which is the verb the dialog uses in its title bar.

Liam: The Echo is a wx Dialog, the sanctioned hardened custom kind, with a multi-line read-only text control inside, sized roughly five hundred sixty by four hundred twenty. The label is set to Spoken Echo, and the read-only control has a Set Name call so the screen reader announces the purpose on focus. The text is rendered newest first, and empty or duplicate consecutive lines are dropped, so the dialog is a clean record, not a noisy one. There is a Close button, and escape also closes, because the dialog contract is applied, which we will get to in a minute. The dialog is also focus-routed, so when it opens, focus lands on the read-only text control, not on the Close button. The reason that matters is that the only reason you opened the dialog is to read the announcements, and a focus park on the Close button would force you to tab once before you could read anything.

Jessica: The Spoken Echo is a read-only control, so you cannot edit the history, but you can copy from it. Put your cursor in the text, control A to select all, control C to copy, escape to leave the dialog, and the clipboard now has the announcements in plain text. The use case is the one we mention in the on-the-go beats of the rest of the series: a screen reader races past an announcement, or you stepped away for a second, or the announcement is too long to hold in working memory. Open the Echo, read it, copy what you need, close. Three seconds, no friction, no surprise.

Liam: A second use of the Echo that is worth naming, because it comes up in the trust arc. When the product makes a state change you want to verify, like a setting flip or a file save, the announcement lands in the Echo with the exact wording the product used. If a support conversation needs the exact text, the Echo is the place to read it. The Spoken Echo is not a new feature, in the sense that the announcement is already happening; the Echo is just a way to look at the announcement after the fact, instead of catching it in flight. It is the audit log for the audio channel, and it lives at alt shift E.


Jessica: Modal dialogs deserve a few minutes on their own, because QUILL holds them to a written contract, and the contract is enforced in the build process, not just in the code review. The contract is a small set of rules. Every modal dialog is reachable by keyboard, including every interactive control inside it. Every modal dialog is escapable with the escape key, full stop, with no exceptions. Initial focus is placed on the content control the user came to interact with, not on the OK button. When the dialog closes, focus is restored to the editor, unless the user opened the dialog from a non-editor surface, in which case focus returns to that surface. There is a test for each of these.

Liam: The enforcement is two parts. The first is the dialog inventory, in quill slash tools slash dialog inventory dot py. That tool walks every Python file under quill slash, finds every dialog construction, and records the dialog kind, the module, and a stable key. Native dialogs, like wx Message Dialog and wx File Dialog, are in the sanctioned set and require no special handling. Hardened custom dialogs, which are the raw wx Dialog constructions, are also sanctioned, but they are the only base allowed, and every custom dialog must be registered. The inventory is committed to a snapshot file, tests slash unit slash ui slash fixtures slash dialog inventory dot json, and the gate fails the build if the snapshot drifts from the source. New dialogs have to be added deliberately, not by accident.

Jessica: The second part is the dialog button contract, in quill slash tools slash dialog button contract dot py. That tool reads every apply modal ids call, which is the helper that wires the dialog's affirmative id and escape id, and verifies that there is an actual button carrying that id. The reason that test exists is a regression from a long time ago. A dialog in an old build declared escape id equal to wx ID CANCEL, but the dialog had no wx ID CANCEL button, so escape did nothing, and the user was trapped. That is a WCAG 2.1.2 keyboard trap. The fix was a static check that requires every escape id to have a backing button, with a documented pragma to opt out for the rare cases where the button is synthesised at runtime, like the YES and NO buttons in wx Message Dialog. The opt-out pragma is a comment on the apply modal ids line that says dialog button contract colon exempt, and the comment is the only path to skip the check.

Liam: You will feel this contract as an absence. You will never be trapped in a dialog. You will never have to hunt for the close button. You will never have to use the mouse to escape. The product will land focus on the field you came to interact with, and it will return you to the editor when you close. None of that is special-cased for a single user. It is the rule for every dialog in the product, and the build process makes sure no future dialog forgets the rule.

Jessica: One related rule that is worth naming here, because it ties the dialog contract to the editing experience. Nothing steals focus. Background work, downloads, conversions, transcription, spell check, the dialog contract, all of it runs in the background and reports through the status bar and the notifications list. Your cursor is sacred ground. A dialog that pops up uninvited is a bug. A dialog that interrupts you because the product needs to tell you something is the only acceptable case, and even then the dialog is focusable and escapable. The rule is older than the dialog contract test, and the test is the modern way to enforce a rule that has always been part of the design.


Liam: Notifications are the last piece of the main window tour, and they are deliberately quiet. Quieter events, an update available, a watch folder running, a background task finishing, a profile change, a Quillin message, accumulate in a notifications list you can review when you choose. The list is opened from the Status Message cell on the status bar, or from the Tools menu. The dialog shows the most recent two hundred notifications with each row carrying a timestamp, a category, and a message. Selecting a row copies the message to the clipboard, because the most common follow-up to a notification is to paste it into an email, a chat, or a bug report. Notifications are not nagware. They do not pop up, they do not flash, they do not make a sound unless you have turned one on. The Status Message cell shows the current count, so you always know whether the list is empty without opening the dialog. The clear is permanent; the list is not a recycle bin. The point is to be a passive record you can audit, not an inbox you have to manage. The list persists across sessions, so a notification you did not look at yesterday is still in the list today.

Jessica: Homework, four steps, in order. One: open the View menu, find the Show Tab Control checkbox, and toggle it twice. Notice the tab strip disappear and reappear, and notice that control tab still cycles. Two: open the Tools menu, find Status Bar Layout, and reorder one cell. Save the dialog. Notice the change. Right-click the bar and choose Restore Defaults if you want to undo. Three: trigger an announcement, save a file or run a search, then press alt shift E to open the Spoken Echo. Read the announcement back to yourself. Copy it with control A and control C. Four: open the notifications list from the Status Message cell, look at the rows, copy one to the clipboard, then close with escape.

Liam: A small honest caveat. The status bar layout dialog and the notifications list are both modal dialogs, and both pass the dialog contract, but they are not the only dialogs in the product that you will use this way. We are calling out one nuance so you are not surprised. The notifications list is built around a wx List Box, and on some screen reader versions the first row on dialog open is sometimes not announced until you arrow once. That is a known issue tracked in the regression suite, and the workaround is exactly what you would do anyway: arrow once after opening, and the rest of the rows announce cleanly. We mention it because we promised at the top of the series to call out the places where doc and code drift, and the row announcement on first open is one of them. The work to land first-row announcement across all screen readers is on the roadmap.

Jessica: Next episode is the one that changes how you use everything we have shown you so far. Notebooks and versions. A Notebook is one file on disk that remembers which documents belong to your project, which of them are open right now, and which tab you were last looking at. Versions are the named snapshots of the moment, the ones that let you try a structural change without losing where you were. We will meet both, and we will meet the entries panel, the manage versions dialog, the navigate to entry command, and the status bar messages the notebook produces. If you write more than one document at a time, which is most of us, episode five is the one that turns QUILL from a powerful editor into a workshop you can come back to.

Liam: I'm Liam.

Jessica: I'm Jessica. Know your room.

Liam: The QUILL Cast is a fifty-four episode audio course on QUILL. This has been episode four. Thanks for listening.

Back to all episodes