Settings and tool windows
Two base classes keep every window consistent with the main window:
| Base | For | File |
|---|---|---|
ChromeWindow |
tool windows: Settings, History, Bookmarks, Passwords, Downloads, Cookies, Permissions, user scripts, developer hosts | ui/chrome_window.py |
JDialog |
small modal prompts: sign-in, bookmark and space editors, the proxy dialog, the screen picker, the update dialog | ui/dialogs/base.py |
ChromeWindow uses the main window's technique: the whole window is client area, it is opaque and paints its own
backdrop (Theme.paint_backdrop(): Frosted or Solid), and a slim custom caption keeps drag, Snap Layouts and the
window buttons. Subclasses fill self.root, optionally with a partly see-through navigation pane.
Opening a tool window#
ui.open_dialog("history") # history, bookmarks, downloads, passwords, cookies, permissions, ...
ui.open_settings("privacy") # a Settings page by key
BrowserController keeps one instance of each tool window in _dialogs and brings it to the front if it is already
open. Dialog modules are imported lazily, the first time they are opened, which keeps start-up fast (the PyInstaller
spec collects them explicitly for the same reason).
The Settings window#
SettingsWindow (ui/dialogs/settings.py)
has a navigation pane in four groups (NAV_GROUPS): Browsing (General, Search, Default apps), Look and feel
(Appearance, Ribbon and sidebar), Privacy and safety (Privacy and security, Clear browsing data, Passwords,
Downloads) and System (Performance, Network and DNS, Advanced, Reset, About). PAGES lists every page in order.
On the right are SettingCards: an icon, a title, a plain-language description and a control.
- Helpers build the common controls:
_toggle(key),_toggle_card(key, glyph, title, description)and_combo(key, options). Each writes straight into the settings store, so changes apply immediately. - The search box filters cards by their title and description text across all pages.
- New in 2.0.1
_section(title)passed to_page()starts a heading; the cards after it belong to it, and the search hides a heading (and a navigation group) when none of its cards match. Esc clears the search first. - New in 2.0.1 Default apps reads the user's choice for
httpsand.pdffrom Windows (win.default_handler():UserChoiceLatest, thenUserChoice) and opens Windows' Default apps page on JBrowser's entry (win.open_default_apps()). It refreshes when the window is activated again. - New in 2.0.3 Pages are built when needed. The window opens with only the page it shows built (the others are
empty placeholders in the stack).
_ensure_page(key)builds a page from_buildersthe first time it is chosen (15–50 ms). Searching builds every page first (_build_all()), because it needs every card. Opening Settings went from about 285 ms to about 100 ms. Fewer widgets also make restyling cheaper (see theming): Qt re-polishes every widget of the app when the style sheet changes. _listen(signal, slot)connects to app-wide signals and disconnects them when the window closes, so a closed Settings window never receives updates.- Every setting also has a command page in the Lazy Toolbar (
Settings: <page>).
Writing a new dialog#
- Subclass
ChromeWindowfor a tool window orJDialogfor a prompt. - Paint with theme tokens and connect to
theme().changed; use the reusable widgets. - Keep the logic in a service; the dialog only shows and edits it.
- Add it to
BrowserController.open_dialog()and give it a command inui/actions.py.