Boozle documentation
Everything you need to run auto-advancing PDF slideshows from the command line.
Quick Start
Install Boozle (see the install guide), then run:
boozle slides.pdf --auto 30sThis opens your PDF fullscreen and advances every 30 seconds. Press q or Esc to quit.
boozle slides.pdf --auto 30s --loop --progressWhat’s New in 1.4.0
LatestBoozle 1.4.0 adopts the new Boozle design system, the same identity you see on this site. Flags, sidecars and keyboard shortcuts are unchanged, so existing decks and commands work as before. Every release is listed on GitHub Releases.
1.3.1
Presenter view: room for speaker notes
Notes get a dedicated band across the bottom of the presenter window, at least a third of its height, next to a compact clock / slide / elapsed / progress panel; current and next slide sit side by side above it. Notes are drawn as large as they fit (bigger on HiDPI and 4K screens) and only fall back to the old size for long notes.
1.3.0
Speed and dependable multi-display setups: Boozle starts almost instantly, uses far less memory, lets you pick displays by name, and reads PDF Presenter Console files.
Monitors by name
--monitor and --presenter-monitor (and monitor / presenter_monitor in sidecars) accept a display name, or any unique part of one, as well as an index, e.g. --monitor HDMI-1. --list-monitors now prints each display’s name, size and scale, and marks the primary.
pdfpc sidecars
Boozle reads .pdfpc files from PDF Presenter Console. Their page order, hidden slides and notes carry over, so existing pdfpc decks work as-is. See pdfpc Sidecars.
Overview opens in presenter view
With presenter view on, Tab opens the slide grid on the presenter screen only. The audience keeps seeing the current slide until you pick a new one with Enter or a click.
Near-instant startup and much lower memory
The compiled PDF engine is cached on disk, so opening a PDF drops from about a second to a few tens of milliseconds after the first run. A new render scheduler keeps navigation off the UI thread and coalesces held arrow keys into one render. The GPU cache now counts real texture sizes. On a 300-page deck the audience window settles around 155 MB instead of ~355 MB in a 1280×720 window, and around 340 MB instead of ~850 MB full-screen on a Retina display. Overview thumbnails are cached across launches. See Performance & Memory.
More platforms
Every release now ships native binaries for macOS Intel and Linux ARM64, alongside macOS Apple Silicon, Linux x86_64 and Windows x86_64. The curl installer also clears the macOS quarantine flag itself.
Linux window-manager rules and reliable placement
Fullscreen windows now land on the requested monitor on Linux: Boozle waits for the window manager, verifies the placement and retries once. Windows carry the X11 class boozle with instance audience or presenter, so tiling window managers can match them. See Platform Notes.
Reliability fixes
Flags on the command line now always override the sidecar, even when they repeat a default (--monitor 0, --loop=false, -P -1). l returns to the right slide after any jump, including Home, End and page numbers. Numpad digits work in the audience window. Without --loop, navigation simply stops at the first and last slide. Unknown --transition values are now an error, and PDFs on drive-letter paths open correctly on Windows.
Common Commands
Loop a PDF slideshow
Show a progress overlay
Start from page 10
Present selected pages
Use a second monitor
Use presenter view on another monitor
Pick displays by name
Names are matched case-insensitively, and any unique part works (--monitor hdmi). They stay stable across reboots on macOS and Linux, which makes them the better choice for sidecars.
Present with a pdfpc file
Uses the page order and notes from PDF Presenter Console. A talk.pdfpc next to talk.pdf is picked up automatically, so --config is only needed for other paths.
Fade between slides
Play once and quit
Custom background color
Use a sidecar config
List connected displays
Prints the index, name, size, and scale of every connected display, marks the primary, then exits. Pass the index or the name to --monitor or --presenter-monitor.
Import PowerPoint speaker notes
Generates a sidecar with one [[page]] entry per slide that has real speaker notes. The PowerPoint file is no longer needed at presentation time.
Trim memory on big decks
Rasterises at 75% of native pixels and hard-caps the GPU page cache at 64 MB. See Performance & Memory.
Debug monitor placement
Every two seconds, prints memory, render and monitor-placement diagnostics to stderr. Attach this log to bug reports about windows landing on the wrong display.
CLI Reference
All available flags for boozle. Flags given on the command line always override the sidecar, even when they repeat a default.
| Flag | Argument | Description |
|---|---|---|
| -a, --auto | <duration> | Auto-advance interval. Accepts Go duration strings: 30s, 2m, 500ms. |
| -l, --loop | Loop back to the first slide after the last page. | |
| -s, --start | <N> | Start at page N (1-indexed). |
| --pages | <range> | Restrict playback to a page range. Supports comma-separated ranges: 1-5,8,10-12. |
| -m, --monitor | <N|name> | Open the audience presentation on a display, given by index or by name (case-insensitive; any unique part works, e.g. HDMI-1). Display 0 is the primary screen. |
| -P, --presenter-monitor | <N|name> | Open presenter view on a display, given by index or name. -1 or empty disables it, which also turns off a sidecar’s presenter view. Must be different from --monitor unless paired with --no-fullscreen for local testing. |
| -M, --list-monitors | Print the index, name, size, and scale of every connected display, marking the primary, then exit. | |
| --bg | <hex> | Background color behind slides. Accepts #RGB, #RRGGBB, or #RRGGBBAA (default: #000000). |
| --progress | Show segmented page-position progress and countdown overlay. | |
| --transition | <style> | Page transition: slide (default), fade, or none. Non-directional jumps always fade. Any other value is an error. |
| --autoquit | Quit automatically after the last slide. | |
| --no-fullscreen | Run in windowed mode instead of fullscreen. | |
| --cache-mb | <N> | Hard-cap the GPU page cache at N MB. 0 auto-sizes from the active display. |
| --render-scale | <F> | Rasterise pages at fraction F of native pixels (0.5..1.0). 0 keeps native. Trades sharpness for less RAM on big decks. |
| --config | <path> | Load a specific sidecar, either .boozle.toml or .pdfpc (default: auto-detected next to the PDF). |
| --debug-stats | Print memory, render and monitor-placement diagnostics to stderr every two seconds. Not listed in --help. | |
| -h, --help | Show help and exit. | |
| -v, --version | Print the Boozle version and exit. |
PowerPoint Notes Import
Boozle’s presenter view shows per-slide notes from your TOML sidecar. To avoid retyping notes you already have in PowerPoint, run the boozle notes import subcommand once as a preparation step. From then on you only need the PDF plus the generated sidecar — the .pptx file is no longer required at presentation time.
# Default: writes deck.boozle.toml next to the .pptx
boozle notes import deck.pptx
# Choose the output sidecar path explicitly
boozle notes import deck.pptx --out deck.boozle.toml
# --config is accepted as an alias for --out
boozle notes import deck.pptx --config deck.boozle.toml
# Replace an existing generated sidecar
boozle notes import deck.pptx --out deck.boozle.toml --forceThe importer supports modern .pptx files. Old binary .ppt files should be converted to .pptx first. Slides without real speaker notes are omitted, and PowerPoint notes-page slide-number placeholders such as notes = "17" are ignored.
Generated entries look like this in the sidecar:
[[page]]
n = 6
notes = "Schnelle Antworten. Wenig Reibung. Hohe Zuversicht."Once the sidecar exists, present as usual and add a presenter monitor to surface the notes:
.pdfpc notes work directly, with no import step needed. See pdfpc Sidecars.Keyboard Shortcuts
Controls available during a presentation. When presenter view is enabled, the same navigation keys work when the presenter window has focus.
| Key | Action |
|---|---|
| → Page Down Space | Next slide |
| ← Page Up | Previous slide |
| mouse wheel down / up | Next or previous slide |
| Backspace | Previous slide, or delete a typed page digit |
| Home | First slide |
| End | Last slide |
| 0–9 + Enter | Jump to page number (top-row or numpad digits) |
| l | Return to the previously viewed page, after any jump including Home, End and page numbers |
| p | Pause or resume auto-advance |
| b | Blackout screen (toggle) |
| w | Whiteout screen (toggle) |
| f | Toggle fullscreen of the audience window |
| Tab | Open slide overview: arrows select (Up / Down by a whole row), Enter or click jumps, Tab or Esc closes without jumping. With presenter view on, it opens on the presenter screen only. |
| q Esc | Quit |
Without --loop or --autoquit, navigation stops at the first and last slide. The mouse cursor hides itself after three seconds without movement.
Sidecar Config
Boozle automatically looks for a sidecar with the same base name as your PDF in the same directory. Place deck.boozle.toml next to deck.pdf and it loads automatically. If there is no Boozle TOML sidecar, deck.pdfpc is loaded instead (see pdfpc Sidecars). Use --config to specify a different path.
Presentation settings that travel with your PDF. Command-line flags always take precedence over sidecar values, even when they repeat a default, so --monitor 0 or -P -1 overrides a sidecar’s monitor or presenter_monitor.
# Global defaults apply to all slides
auto = "30s" # advance every 30 seconds
loop = true # restart after last slide
progress = true # show countdown HUD
start = 1 # first page to show (1-indexed)
monitor = 0 # audience display: index or name
pages = "1-5,8,10-12" # optional page range
bg = "#0a0a0a" # background color
autoquit = false # don't quit at end (looping)
transition = "fade" # slide, fade, or none
# presenter_monitor = "HDMI-1" # optional speaker display: index or name
# cache_mb = 64 # hard-cap GPU page cache
# render_scale = 0.75 # render at 75% of native pixels
# Override timing for specific slides
[[page]]
n = 3
auto = "1m" # complex diagram — hold for 1 minute
[[page]]
n = 8
auto = "5s" # transition slide — move quickly
# Speaker notes — shown in presenter view
[[page]]
n = 5
notes = """
Mention the rollout date.
Pause for questions before moving on.
"""Sidecar config keys
| Key | Type | Description |
|---|---|---|
| auto | string | Default auto-advance duration (e.g. "30s", "2m") |
| loop | bool | Loop after the last slide |
| progress | bool | Show the countdown HUD overlay |
| start | int | Page to start on (1-indexed); if pages excludes it, playback starts at the next included page |
| monitor | int or string | Audience display: index (0 is primary) or name, e.g. "HDMI-1" |
| pages | string | Page range to present (e.g. "1-5,8,10-12") |
| bg | string | Background color hex (e.g. "#000000") |
| autoquit | bool | Quit after the last slide |
| transition | string | Transition style: "slide", "fade", or "none" |
| presenter_monitor | int or string | Presenter view display: index or name (-1 or "" disables it). Must differ from the audience monitor unless running --no-fullscreen |
| cache_mb | int | Hard-cap the GPU page cache at N MB (0 auto-sizes from the active display) |
| render_scale | float | Rasterise pages at fraction of native pixels (0.5..1.0); 0 keeps native |
| [[page]].n | int | Page number to override (1-indexed) |
| [[page]].auto | string | Duration override for that page |
| [[page]].notes | string | Speaker notes shown in presenter view (multi-line via """…""") |
pdfpc Sidecars
.pdfpc files are the JSON sidecars written by PDF Presenter Console. Boozle loads deck.pdfpc automatically when there is no deck.boozle.toml, or you can pass one explicitly with --config.
boozle talk.pdf --presenter-monitor 0 # auto-loads talk.pdfpc
boozle talk.pdf --config slides/talk.pdfpc --presenter-monitor 0Boozle reads the following from the file:
- Page order becomes the playback order, including duplicate entries used for overlays. If you also pass
--pages, only pages in both are played. - Pages marked
hiddenare skipped. notevalues are shown as plain text in presenter view.
Only pdfpcFormat 2 is supported. pdfpc-specific features such as movies, drawing state, timers, transition metadata and Markdown formatting of notes are ignored. Playback settings such as --auto, --loop or --transition come from command-line flags when a pdfpc file is used.
{
"pdfpcFormat": 2,
"pages": [
{ "idx": 0, "note": "Welcome, introduce the team." },
{ "idx": 1, "hidden": true },
{ "idx": 2, "note": "Demo time." }
]
}Performance & Memory
Boozle renders slides on a background worker and keeps the current slide and its neighbours in a GPU cache, so turning a page is usually instant. Memory use is bounded by that cache, not by the length of the deck. On a 300-page deck, the audience window settles around 155 MB in a 1280×720 window and around 340 MB full-screen on a Retina display.
boozle deck.pdf --cache-mb 64
boozle deck.pdf --render-scale 0.75 --cache-mb 64- Automatic budget: sized from the display at about four full-screen slides, between 32 MB and 192 MB. It counts the GPU memory slides really occupy.
--cache-mb <N>replaces the automatic budget with a hard cap. Prefetching adapts so prefetched slides are not evicted before they are shown.--render-scale <F>rasterises pages at a fraction of native pixels (0.5..1.0). Memory per slide falls with the square of the factor (0.75uses about 56%), at the cost of some sharpness. It is the strongest lever on 4K and Retina displays.- Presenter view runs as a second process with its own renderer and cache, sized for its smaller panes, so expect it to add to the total.
--debug-statsprints GPU and heap usage, cache occupancy and render timings to stderr every two seconds, for both windows.
Disk caches
Boozle keeps two caches in your user cache directory: the compiled PDF engine, which makes every launch after the first start in a fraction of a second, and overview thumbnails, which are pruned automatically after 30 days or beyond 200 MB.
| Platform | Location |
|---|---|
| macOS | ~/Library/Caches/boozle |
| Linux | ~/.cache/boozle |
| Windows | %LocalAppData%\boozle |
Set BOOZLE_CACHE_DIR to use a different location. Deleting the directory is always safe.
Platform Notes
curl downloads are not quarantined, and the script clears the attribute anyway. If you downloaded the archive with a browser instead, Gatekeeper may block the first launch. Right-click (or Control-click) the file in Finder and choose Open, then confirm in the dialog. Subsequent launches work normally. Alternatively, clear the quarantine attribute once (prefix with sudo if the binary is in a root-owned directory such as /usr/local/bin):boozle --list-monitors with --monitor and --presenter-monitor. Windows builds are x86_64 only.checksums.txt, installs to /usr/local/bin when possible, and falls back to ~/.local/bin. Make sure the fallback directory is on your $PATH:# Add to ~/.bashrc or ~/.zshrc
export PATH="$HOME/.local/bin:$PATH"Multi-monitor fullscreen depends on XRandR and Xinerama (libxrandr2, libxinerama1). Without them, only one monitor is listed or fullscreen may land on the wrong display.
--debug-stats to log each placement step. That log is the most useful thing to attach to a bug report.X11 reports a single scale factor for all monitors, so on mixed-DPI setups slides render at the global scale. Use --render-scale or your desktop’s scaling settings if that is too sharp or too soft.
boozle with instance audience or presenter, so tiling window managers (i3, sway via XWayland, KWin rules) can match them. For example, in i3:# ~/.config/i3/config
for_window [class="^boozle$" instance="^audience$"] move container to output HDMI-1
for_window [class="^boozle$" instance="^presenter$"] move container to output eDP-1