47 KiB
Configuration Guide
Overview
wayscriber supports customization through a TOML configuration file located at:
~/.config/wayscriber/config.toml
All settings are optional. If the configuration file doesn't exist or settings are missing, sensible defaults will be used.
Configuration File Location
The configuration file should be placed at:
- Linux:
~/.config/wayscriber/config.toml - The directory will be created automatically when you first create the config file
Example Configuration
See config.example.toml in the repository root for a complete example with documentation.
Configuration Sections
[drawing] - Drawing Defaults
Controls the default appearance of annotations.
[drawing]
# Default pen color
# Options: "red", "green", "blue", "yellow", "orange", "pink", "white", "black"
# Or RGB array: [255, 0, 0]
default_color = "red"
# Default pen thickness in pixels (1.0 - 50.0)
default_thickness = 3.0
# Default eraser size in pixels (1.0 - 50.0)
default_eraser_size = 12.0
# Default eraser mode ("brush" or "stroke")
default_eraser_mode = "brush"
# Default marker opacity multiplier (0.05 - 0.90). Multiplies the current color alpha.
marker_opacity = 0.32
# Default fill state for fill-capable shape tools
default_fill_enabled = false
# Default side count for the Regular Polygon tool (3 - 12)
polygon_sides = 5
# Default font size for text mode (8.0 - 72.0)
# Can be adjusted at runtime with <kbd>Ctrl+Shift++</kbd>/<kbd>Ctrl+Shift+-</kbd> or <kbd>Shift</kbd> + scroll
default_font_size = 32.0
# Font rendering defaults
font_family = "Sans"
font_weight = "bold"
font_style = "normal"
text_background_enabled = false
# Hit-test tuning + undo retention
hit_test_tolerance = 6.0
hit_test_linear_threshold = 400
undo_stack_limit = 100
# Drag gesture tool mapping
# Flat drag fields accept only drag-bindable tools. Freeform polygon is
# selectable from the toolbar picker but is not valid here.
drag_tool = "pen"
shift_drag_tool = "line"
ctrl_drag_tool = "rect"
ctrl_shift_drag_tool = "arrow"
tab_drag_tool = "ellipse"
# Optional per-button override. Right/middle keep their built-in behavior
# unless configured. Use "default" for a button's built-in behavior.
[drawing.drag_tools.left]
drag_tool = "pen"
shift_drag_tool = "pen"
shift_drag_color = "red"
[drawing.drag_tools.right]
drag_tool = "pen"
drag_color = "blue"
[drawing.drag_tools.middle]
drag_tool = "default"
Color Options:
- Named colors:
"red","green","blue","yellow","orange","pink","white","black" - RGB arrays:
[255, 0, 0]for red,[0, 255, 0]for green, etc.
Runtime Adjustments:
- Pen thickness: Use +/- keys or scroll wheel (range: 1-50px)
- Eraser size: Use +/- keys or scroll wheel when eraser tool is active (range: 1-50px)
- Eraser mode: Use Ctrl+Shift+E to toggle brush vs stroke erasing
- Marker opacity: Use Ctrl+Alt + ↑/↓
- Regular polygon sides: Use the side toolbar Sides control (range: 3-12)
- Font size: Use Ctrl+Shift++/Ctrl+Shift+- or Shift + scroll (range: 8-72px)
Defaults:
- Color: Red
- Thickness: 3.0px
- Eraser size: 12.0px
- Eraser mode: Brush
- Marker opacity: 0.32
- Fill enabled: false
- Polygon sides: 5
- Font size: 32.0px
- Font family/weight/style: Sans / bold / normal
- Text background: false
- Hit-test tolerance: 6.0px (linear threshold: 400)
- Undo stack limit: 100
- Drag mapping: Drag=Pen, Shift+Drag=Line, Ctrl+Drag=Rect, Ctrl+Shift+Drag=Arrow, Tab+Drag=Ellipse
[arrow] - Arrow Geometry
Controls the appearance of arrow annotations.
[arrow]
# Arrowhead length in pixels
length = 20.0
# Arrowhead angle in degrees (15-60)
# 30 degrees gives a nice balanced arrow
angle_degrees = 30.0
# Place the arrowhead at the end of the line instead of the start
head_at_end = false
Defaults:
- Length: 20.0px
- Angle: 30.0°
- Head at end: false (head at the start)
[presets] - Quick Tool Slots
Configure 3-5 tool presets that you can apply or update via hotkeys or the toolbar strip.
[presets]
slot_count = 5
[presets.slot_1]
name = "Red pen"
tool = "pen"
color = "red"
size = 3.0
marker_opacity = 0.32
fill_enabled = false
font_size = 32.0
text_background_enabled = false
arrow_length = 20.0
arrow_angle = 30.0
arrow_head_at_end = true
show_status_bar = true
# Optional full per-tool profile captured by newly saved presets.
[presets.slot_1.tool_settings]
eraser_size = 18.0
[presets.slot_1.tool_settings.pen]
color = "red"
size = 3.0
[presets.slot_1.tool_settings.line]
color = "green"
size = 6.0
[presets.slot_1.tool_settings.rect]
color = "blue"
size = 4.0
[presets.slot_1.tool_settings.ellipse]
color = "orange"
size = 4.0
[presets.slot_1.tool_settings.arrow]
color = "yellow"
size = 5.0
[presets.slot_1.tool_settings.blur]
color = "black"
size = 12.0
[presets.slot_1.tool_settings.marker]
color = "yellow"
size = 20.0
[presets.slot_1.tool_settings.step_marker]
color = "white"
size = 28.0
Required fields: tool, color, size
Optional fields: tool_settings, eraser_kind, eraser_mode, marker_opacity, fill_enabled, font_size, text_background_enabled, arrow_length, arrow_angle, arrow_head_at_end, polygon_sides, show_status_bar, drag_tools
When tool_settings is present, applying the preset restores the full drawing profile for all
tools, including StepMarker size and Eraser size, then activates tool. Legacy presets without
tool_settings keep the old behavior and apply only color/size to the selected tool.
The top-level color and size are retained for compatibility, readability, and toolbar previews.
[history] - Undo/Redo Playback
Controls delayed undo/redo playback and the optional Step section in the toolbar.
[history]
# Delay between steps for undo-all/redo-all (50 - 5000 ms)
undo_all_delay_ms = 1000
redo_all_delay_ms = 1000
# Show the Step section in the toolbar
custom_section_enabled = false
# Delay between steps for custom undo/redo (50 - 5000 ms)
custom_undo_delay_ms = 1000
custom_redo_delay_ms = 1000
# Number of steps to run in custom undo/redo (1 - 500)
custom_undo_steps = 5
custom_redo_steps = 5
Notes:
undo_all_delay_ms/redo_all_delay_msdrive the "Undo all (delay)" and "Redo all (delay)" toolbar actions.custom_section_enabledreveals the Step controls in the side toolbar; those controls use the custom delays and step counts above.
[performance] - Performance Tuning
Controls rendering performance and smoothness.
[performance]
# Number of buffers for rendering (2, 3, or 4)
# 2 = double buffering (low memory)
# 3 = triple buffering (recommended, smooth)
# 4 = quad buffering (ultra-smooth on high refresh displays)
buffer_count = 3
# Enable vsync frame synchronization
# Prevents tearing and limits rendering to display refresh rate
enable_vsync = true
# Max FPS when VSync is disabled (0 = unlimited)
# Prevents CPU spinning at very high FPS; set to match your monitor
max_fps_no_vsync = 60
# UI animation frame rate (0 = unlimited)
# Higher values smooth UI effects at the cost of more redraws
ui_animation_fps = 30
Buffer Count:
- 2: Double buffering - minimal memory usage, may flicker on fast drawing
- 3: Triple buffering - recommended default, smooth drawing
- 4: Quad buffering - for high-refresh displays (144Hz+), ultra-smooth
VSync:
- true (default): Synchronizes with display refresh rate, no tearing
- false: Capped by
max_fps_no_vsync(set to 0 for uncapped); may cause tearing but lower latency
Max FPS (VSync off):
- 60 (default): Suitable for most displays
- 0: Unlimited (uncapped; higher CPU usage)
- Set to your monitor refresh (60/120/144/240) for best balance
UI Animation FPS:
- 30 (default): Smooth enough for most effects
- 0: Unlimited (renders every frame while animations are active)
- Higher values improve smoothness at the cost of extra redraws
Defaults:
- Buffer count: 3 (triple buffering)
- VSync: true
- Max FPS (VSync off): 60
- UI animation FPS: 30
[ui] - User Interface
Controls visual indicators, overlays, and UI styling.
[ui]
# Show status bar with current color/thickness/tool
show_status_bar = true
# Show board label in the status bar
show_status_board_badge = true
# Show page counter in the status bar
show_status_page_badge = true
# Show the board/page badge even when the status bar is visible
show_page_badge_with_status_bar = false
# Show a small "FROZEN" badge when frozen mode is active
show_frozen_badge = false
# Filter help overlay sections based on enabled features
help_overlay_context_filter = true
# Command palette action toast duration (ms)
command_palette_toast_duration_ms = 1500
# Status bar position
# Options: "top-left", "top-right", "bottom-left", "bottom-right"
status_bar_position = "bottom-left"
# Preferred output name for GNOME fallback (xdg-shell) overlays
#preferred_output = "eDP-1"
# Enable output-cycling shortcuts on layer-shell compositors
multi_monitor_enabled = true
# Show active output label in the status bar
active_output_badge = true
# Request fullscreen for the GNOME fallback overlay (disable if opaque)
#xdg_fullscreen = false
# Behavior when GNOME fallback (xdg-shell) loses keyboard focus
# Options: "exit", "stay" (default on Ubuntu/GNOME)
#xdg_focus_loss_behavior = "exit"
# Mouse button that toggles radial menu
# Options: "middle", "right", "disabled"
radial_menu_mouse_binding = "middle"
# Status bar styling
[ui.status_bar_style]
font_size = 21.0
padding = 15.0
bg_color = [0.0, 0.0, 0.0, 0.85] # Semi-transparent black [R, G, B, A]
text_color = [1.0, 1.0, 1.0, 1.0] # White
dot_radius = 6.0
# Help overlay styling
[ui.help_overlay_style]
font_size = 14.0
font_family = "Noto Sans, DejaVu Sans, Liberation Sans, Sans"
line_height = 22.0
padding = 32.0
bg_color = [0.09, 0.1, 0.13, 0.92] # Deep slate background
border_color = [0.33, 0.39, 0.52, 0.88] # Muted steel border
border_width = 2.0
text_color = [0.95, 0.96, 0.98, 1.0] # Near-white
# Click highlight styling (visual feedback for mouse clicks)
[ui.click_highlight]
enabled = false
show_on_highlight_tool = false
radius = 24.0
outline_thickness = 4.0
duration_ms = 750
fill_color = [1.0, 0.8, 0.0, 0.35]
outline_color = [1.0, 0.6, 0.0, 0.9]
use_pen_color = true # Existing highlights update immediately when you change pen color
force_in_light_mode = true # Force-enable click highlights when entering light mode
# Context menu visibility
[ui.context_menu]
enabled = true
Status Bar:
- Shows current color, pen thickness, and active tool
- Press F1/F10 to toggle help overlay
- Fully customizable styling (fonts, colors, sizes)
Position Options:
"top-left": Upper left corner"top-right": Upper right corner"bottom-left": Lower left corner (default)"bottom-right": Lower right corner
UI Styling:
- Font sizes: Customize text size for status bar and help overlay
- Colors: All RGBA values (0.0-1.0 range) with transparency control
- Layout: Padding, line height, dot size, border width all configurable
- Click highlight: Enable presenter-style click halos with adjustable radius, colors, and duration; by default the halo follows your current pen color (set
use_pen_color = falseto keep a fixed color) - Highlight tool ring:
show_on_highlight_tool = truekeeps a persistent halo visible while the highlight tool is active - Light mode:
force_in_light_mode = truepreserves the default behavior of enabling click highlights on light mode entry; set it tofalseto keep the current click highlight state - Context menu:
ui.context_menu.enabledtoggles right-click / keyboard menus - Output focus:
multi_monitor_enabledcontrols output-cycling shortcuts;active_output_badgeshows the current monitor in the status bar - GNOME fallback:
preferred_outputpins the xdg-shell overlay to a specific monitor;xdg_fullscreenrequests fullscreen instead of maximized;xdg_focus_loss_behaviorcontrols whether losing focus closes (exit) or keeps (stay) the overlay - Radial menu trigger:
radial_menu_mouse_bindingselects which mouse button opens radial menu (middledefault,right, ordisabled)
Multi-monitor behavior:
- Use
focus_prev_output/focus_next_output(default: Ctrl+Alt+Shift+←/Ctrl+Alt+Shift+→) to move overlay focus between outputs. - Toolbar surfaces and status bar follow the active output when focus changes.
- Output switching is blocked while capture, frozen, or zoom is active/in progress; finish or exit those modes first.
- Command palette (
Ctrl+K) includes hidden aliases, so searchingmonitorordisplayfinds output actions. - For GNOME/xdg fallback, set
preferred_output(or env overrideWAYSCRIBER_XDG_OUTPUT) to pin the overlay to a specific monitor.
Defaults:
- Show status bar: true
- Show frozen badge: false
- Position: bottom-left
- Radial menu mouse trigger: middle
- Status bar font: 21px
- Help overlay font: 14px
- Semi-transparent dark backgrounds with muted borders
[presenter_mode] - Presenter Mode
Control which UI elements presenter mode hides and how tools behave when it is active.
[presenter_mode]
hide_status_bar = true
hide_toolbars = true
hide_tool_preview = true
close_help_overlay = true
enable_click_highlight = true
tool_behavior = "force-highlight"
show_toast = true
Tool behavior options:
"keep": Leave the active tool unchanged"force-highlight": Switch to highlight on entry, allow tool changes"force-highlight-locked": Switch to highlight and lock tools while presenting
Light Passthrough Mode
Light mode hides UI chrome and sets the overlay to click-through passthrough until drawing is explicitly enabled. toggle_light_mode defaults to Ctrl+Shift+L, but that is a Wayscriber in-overlay shortcut: it works while the overlay still has focus. Once passthrough is active, normal keyboard and pointer input goes to the app underneath, so compositor/global shortcuts should call the daemon commands below for reliable control.
This mode requires layer-shell support; it is disabled on the xdg fallback because keyboard input cannot be passed through reliably there.
For compositor/global shortcuts while passthrough is active, run:
wayscriber --light-toggle
wayscriber --light-draw-toggle
wayscriber --light-draw-on
wayscriber --light-draw-off
Use --light-draw-on on key/button press and --light-draw-off on release for a non-sticky draw-while-held shortcut. The raw --daemon-action form remains available for scripts.
[ui.toolbar] - Floating Toolbars
Controls the top and side toolbars (toggle with F2/F9).
[ui.toolbar]
# Toolbar layout preset: "simple" or "full"
# Legacy values: "regular" and "advanced" (both map to Full UI label)
layout_mode = "full"
# Optional per-mode overrides for toolbar sections
# Use true/false to override a section; omit to use the mode default.
#
# [ui.toolbar.mode_overrides.simple]
# show_presets = false
# show_actions_section = true
# show_actions_advanced = false
# show_zoom_actions = true
# show_pages_section = true
# show_boards_section = true
# show_step_section = false
# show_text_controls = true
# show_settings_section = false
#
# [ui.toolbar.mode_overrides.regular] # Full mode overrides
# show_presets = true
# show_actions_section = true
# show_actions_advanced = false
# show_zoom_actions = true
# show_pages_section = true
# show_boards_section = true
# show_step_section = false
# show_text_controls = true
# show_settings_section = true
#
# [ui.toolbar.mode_overrides.advanced] # Legacy mode overrides
# show_presets = true
# show_actions_section = true
# show_actions_advanced = true
# show_zoom_actions = true
# show_pages_section = true
# show_boards_section = true
# show_step_section = true
# show_text_controls = true
# show_settings_section = true
# Show top toolbar on startup (pinned)
top_pinned = true
# Show side toolbar on startup (pinned)
side_pinned = true
# Use icons instead of text labels in toolbars
use_icons = true
# Scale factor for toolbar UI (icons + layout)
scale = 1.0
# Show extended color palette in the top toolbar
show_more_colors = false
# Show basic actions (undo/redo/clear) in the side toolbar
show_actions_section = true
# Show advanced actions (undo all, delay, freeze, etc.)
show_actions_advanced = false
# Show zoom actions (zoom in/out/reset/lock)
show_zoom_actions = true
# Show page controls section (prev/next/new/dup/del)
show_pages_section = true
# Show board controls section (prev/next/new/del)
show_boards_section = true
# Show presets section in the side toolbar
show_presets = true
# Show Step Undo/Redo section
show_step_section = false
# Keep text controls visible even when text is inactive
show_text_controls = true
# Show Settings section (config shortcuts + advanced toggles)
show_settings_section = true
# Show delayed undo/redo sliders in the side toolbar
show_delay_sliders = false
# Show the marker opacity slider at the bottom of the side toolbar even when the marker tool isn't selected
show_marker_opacity_section = false
# Enable context-aware UI that shows/hides controls based on the active tool
context_aware_ui = true
# Show preset action toast notifications on apply/save/clear
show_preset_toasts = true
# Show cursor tool preview bubble
show_tool_preview = false
# Initial toolbar offsets (layer-shell/inline)
top_offset = 0.0
top_offset_y = 0.0
side_offset = 0.0
side_offset_x = 0.0
# Force inline toolbars even when layer-shell is available
force_inline = false
Behavior:
- Icon/text mode:
use_iconsswitches between compact icons and labeled buttons. - Scale:
scalemultiplies toolbar UI sizing (useful for HiDPI when output scale=1). - Colors:
show_more_colorstoggles the extended palette row. - Layout:
layout_modepicks a preset complexity level;mode_overrideslets you customize each mode. - Actions:
show_actions_sectionshows the basic actions row;show_actions_advancedreveals the extended actions. - Zoom actions:
show_zoom_actionstoggles the zoom controls in the Canvas drawer. - Pages:
show_pages_sectiontoggles the page navigation block. - Boards:
show_boards_sectiontoggles the board navigation block. - Presets:
show_presetshides/shows the preset slots section. - Text controls:
show_text_controlskeeps font size/family visible even when text isn’t active. - Step controls:
show_step_sectionhides/shows the Step Undo/Redo section. - Settings:
show_settings_sectionhides/shows the settings footer (config buttons and toggles). - Delays:
show_delay_slidersshows the timed undo/redo-all sliders in the side panel. - Marker opacity: the marker opacity slider appears when the marker tool is active;
show_marker_opacity_sectionkeeps it visible even when using other tools. - Polygon tools: Full mode shows Triangle, Parallelogram, Rhombus, Regular Polygon, and Freeform Polygon under the compact Polygons picker. Simple mode exposes them in the Shapes picker.
- Context-aware UI:
context_aware_uishows/hides tool-specific controls (colors, thickness, arrow labels, etc.) based on the active tool; disable to always show all controls. - Preset toasts:
show_preset_toastsenables toast confirmations for preset apply/save/clear. - Tool preview:
show_tool_previewtoggles the cursor bubble. - Offsets:
top_offset,top_offset_y,side_offset,side_offset_xstore toolbar positions. - Force inline:
force_inline(orWAYSCRIBER_FORCE_INLINE_TOOLBARS) skips layer-shell toolbars. - Pinned:
top_pinned/side_pinnedcontrol whether each toolbar opens on startup.
Defaults: all set as above.
[boards] - Boards (Backgrounds + Names)
Configure multiple boards (each with its own pages) plus the special transparent overlay.
[boards]
max_count = 9
auto_create = true
show_board_badge = true
pan_enabled = true
show_pan_badge = true
persist_customizations = true
default_board = "transparent"
[[boards.items]]
id = "transparent"
name = "Overlay"
background = "transparent"
persist = true
[[boards.items]]
id = "whiteboard"
name = "Whiteboard"
background = { rgb = [0.992, 0.992, 0.992] }
default_pen_color = { rgb = [0.0, 0.0, 0.0] }
auto_adjust_pen = true
[[boards.items]]
id = "blackboard"
name = "Blackboard"
background = { rgb = [0.067, 0.067, 0.067] }
default_pen_color = { rgb = [1.0, 1.0, 1.0] }
auto_adjust_pen = true
[[boards.items]]
id = "blueprint"
name = "Blueprint"
background = { rgb = [0.063, 0.125, 0.251] }
default_pen_color = { rgb = [0.902, 0.945, 1.0] }
[[boards.items]]
id = "corkboard"
name = "Corkboard"
background = { rgb = [0.420, 0.294, 0.165] }
default_pen_color = { rgb = [0.969, 0.890, 0.784] }
Fields:
max_count— hard cap on total boards.auto_create— create a board when switching to an empty slot.show_board_badge— show board name/slot in the status bar.pan_enabled— allow panning on solid-color boards with Space + left-drag.show_pan_badge— show the pan hint in the status bar or as a floating badge.persist_customizations— runtime edits (rename/background) are written back to config.default_board— board id to activate on startup.items— ordered list of boards; each board has:id— stable identifier (used by keybindings and persistence).name— display name in the UI.background—"transparent"or{ rgb = [..] }.default_pen_color— optional; if omitted andauto_adjust_pen = true, pen color is auto-contrasted.auto_adjust_pen— auto-switch pen color on entry.persist— include this board in session saves.
Keybindings:
- Ctrl+Shift+1..9: Switch board slots
- Ctrl+Shift+Left/Right: Previous/next board
- Ctrl+Shift+N: New board
- Ctrl+Shift+Delete: Delete board
- Ctrl+Shift+B: Board picker (inline rename/color)
- Aliases (configurable): Ctrl+W = whiteboard, Ctrl+B = blackboard, Ctrl+Shift+T = transparent
Board Picker:
- Modal list for switching, renaming, and recoloring boards.
- Inline edits persist immediately when
persist_customizations = true.
Solid-board pan:
- Hold Space and drag with the left mouse button to pan whiteboards and other solid-color boards.
- Transparent overlay does not pan; it stays anchored to the live screen.
- The canvas context menu includes Reset Canvas Position when board panning is enabled.
- The same right-click menu exposes Zoom → Zoom In, Zoom Out, and Reset Zoom.
- Right-click menus expose Paste; shape menus also expose Copy for the selected annotations.
- Pan offsets are stored per page, so each page keeps its own position.
CLI Override:
Use a board id with --mode:
wayscriber --active --mode whiteboard
wayscriber --active --mode blueprint
wayscriber --daemon --mode transparent
[board] - Legacy Board Modes
This section is still recognized for backward compatibility. If [boards] is missing,
wayscriber will synthesize boards from [board]. New configurations should prefer [boards].
[render_profiles] - Render Color Profiles
Render profiles preview an alternate final color mapping without changing saved shapes or board data. They are useful for print, projectors, grayscale-ish previews, and light/dark sharing workflows.
[render_profiles]
# Optional profile id to preview on startup
# active = "print"
apply_to_canvas = true
apply_to_ui = true
export = "off"
# export_profile = "print"
[[render_profiles.profiles]]
id = "print"
name = "Print"
mappings = [
{ from = "#000000", to = "#FFFFFF" },
{ from = "#FFFFFF", to = "#000000" },
{ from = "#FFFF00", to = "#8B4513" },
{ from = "#00FF00", to = "#006400" },
]
Behavior:
idis the stable identifier used byactiveand runtime profile switching.- Profile entries are stored under
profiles. apply_to_canvascontrols board backgrounds, annotations, and canvas-space editor previews such as selections, hover rings, provisional strokes, text-edit previews, and click highlights.apply_to_uicontrols screen-space Wayscriber UI chrome, status text, popups, command palette, and toolbars.exportcontrols explicit canvas PNG export remapping:off,active, orprofile.export_profileis used only whenexport = "profile".mappingsuse exact RGB matches. Accepted input forms are#RRGGBB,RRGGBB, and0xRRGGBB; validation normalizes to#RRGGBB.- Pixel alpha is preserved. Unmapped colors are unchanged.
- With both targets enabled, profiles apply to Wayscriber-rendered pixels: annotations, board backgrounds, UI chrome, toolbars, popups, embedded images, and frozen/zoom backgrounds when Wayscriber paints them.
- Set
apply_to_ui = falseto preview remapped canvas content while keeping screen-space UI text and controls in the normal theme. - Profiles do not recolor the compositor-owned live desktop seen through a transparent overlay.
- Explicit canvas PNG export applies its resolved export profile to persisted Wayscriber canvas content only, uses the current panned board viewport, respects output scale, and excludes frozen/zoom desktop pixels.
- Board PDF export writes the active board or every board to a file with one PDF page per Wayscriber page. PDF export preserves board/page order and solid board backgrounds, but does not apply export render profiles.
[export.pdf]controls PDF filename fallback, page size, orientation, fit mode, and optional page labels.- Explicit canvas export and its clipboard-failure fallback save PNG data as
.png; screenshot clipboard fallback still uses[capture].format. [capture].enableddisables compositor screenshot capture actions, not explicit export actions.- Board PDF export is file-only; clipboard PDF export is not supported yet.
Runtime actions:
render_profile_nextrender_profile_previousrender_profile_off
Canvas export actions:
export_canvas_fileexport_canvas_clipboardexport_canvas_clipboard_and_fileexport_board_pdf_fileexport_all_boards_pdf_file
[capture] - Screenshot Capture
Configures how screenshots are stored and shared.
[capture]
# Enable/disable capture shortcuts entirely
enabled = true
# Directory for saved screenshots (supports ~ expansion)
save_directory = "~/Pictures/Wayscriber"
# Filename template (strftime-like subset: %Y, %m, %d, %H, %M, %S)
filename_template = "screenshot_%Y-%m-%d_%H%M%S"
# Image format (currently "png")
format = "png"
# Copy captures to clipboard in addition to saving files
copy_to_clipboard = true
# Exit the overlay after any capture completes (forces exit for all capture types)
# When false, clipboard-only captures still auto-exit by default.
# Use --no-exit-after-capture to keep the overlay open for a run.
exit_after_capture = false
Tips:
- Set
copy_to_clipboard = falseif you prefer file-only captures. - Clipboard-only shortcuts ignore the save directory automatically.
wl-clipboard,grim, andslurpare installed automatically by deb/rpm/AUR packages. For source/tarball installs, add them manually; otherwise wayscriber falls back toxdg-desktop-portal.- Use
--exit-after-capture/--no-exit-after-captureto override exit behavior per run.
[export.pdf] - PDF Export
Configures explicit PDF exports. If filename_template is omitted or blank, active-board PDF
exports reuse [capture].filename_template and save with a .pdf extension. All-board PDF exports
use all_boards_filename_template, then filename_template, then [capture].filename_template.
[export.pdf]
# filename_template = "board_%Y-%m-%d_%H%M%S"
# all_boards_filename_template = "boards_%Y-%m-%d_%H%M%S"
page_size = "viewport" # viewport, a4, letter, custom
orientation = "auto" # auto, portrait, landscape
fit = "viewport" # viewport, fit-viewport-to-page, fit-content-to-page
transparent_background = "none" # none, desktop
custom_width = 800.0 # PDF points, used with page_size = "custom"
custom_height = 600.0
content_source_padding = 24.0 # source units, used with fit-content-to-page
[export.pdf.labels]
enabled = false
position = "bottom-center" # top-left, top-right, bottom-left, bottom-right, bottom-center
content = "custom-template" # custom-template, board-and-page, document-page, board-name, page-name
template = "{board_name} - {page_name} ({document_page}/{document_pages})"
font_family = "Sans"
font_size = 10.0
margin = 12.0
padding_x = 6.0
padding_y = 3.0
text_color = [0.1, 0.1, 0.1, 1.0]
background_enabled = true
background_color = [1.0, 1.0, 1.0, 0.85]
fit = "viewport" draws the viewport 1:1 without scaling. With the default
page_size = "viewport", this preserves the legacy export. fit-viewport-to-page scales the
viewport into the configured page size. fit-content-to-page scales the page's padded annotation
bounds into the configured page size, falling back to the viewport for blank pages.
transparent_background = "desktop" is opt-in. It hides the overlay, captures the live desktop
visible on the active output, and uses that image behind transparent PDF pages. Solid boards keep
their configured background. If the desktop capture is denied or the active output cannot be
isolated, the PDF export fails and no file is saved.
Label templates support {app_board}, {app_boards}, {export_board}, {export_boards},
{page}, {pages}, {document_page}, {document_pages}, {board_name}, and {page_name}.
Use {{ and }} for literal braces. content = "custom-template" uses template; the other
content modes ignore it. Labels are drawn after canvas content, ellipsized to one line, and omitted
if the page is too small.
[tablet] - Tablet/Stylus Input
Runtime toggles for tablet/stylus input (Wayland zwp_tablet_v2).
[tablet]
enabled = true
pressure_enabled = true
min_thickness = 1.0
max_thickness = 8.0
auto_eraser_switch = true
pressure_variation_threshold = 0.1
pressure_thickness_edit_mode = "disabled"
pressure_thickness_entry_mode = "pressure_only"
pressure_thickness_scale_step = 0.1
[tablet.stylus_button]
action = "toggle_radial_menu"
[tablet.stylus_button2]
# action = "undo"
Notes:
- Requires the
tablet-inputfeature at build time (enabled in default release builds). - Tablet input is enabled by default when the feature is compiled in; set
enabled = falseto opt out. stylus_buttonis the primary barrel button (BTN_STYLUS/ 331);stylus_button2is the secondary barrel button (BTN_STYLUS2/ 332).- Barrel button
actionvalues use normal action names, such astoggle_radial_menu,undo, andredo. Omitactionto leave a button unbound.
[session] - Session Persistence
Optional on-disk persistence for your drawings. Enabled by default so sessions resume automatically.
[session]
persist_transparent = true
persist_whiteboard = true
persist_blackboard = true
persist_history = true
restore_tool_state = true
storage = "auto"
# custom_directory = "/absolute/path"
per_output = true
max_shapes_per_frame = 10000
max_file_size_mb = 50
compress = "auto"
auto_compress_threshold_kb = 100
backup_retention = 1
# max_persisted_undo_depth = 200
persist_*— choose which boards survive restarts (persist_transparentfor overlay,persist_whiteboard/persist_blackboardgate non-transparent boards for legacy compatibility)persist_history— whentrue, persist undo/redo stacks so that history survives restarts; set tofalseto save only visible drawingsrestore_tool_state— save pen colour, thickness, font size, arrow settings (including head placement), and status bar visibility; whentrue, the last-used tool state overrides config defaults at startupstorage—auto(XDG data dir, e.g.~/.local/share/wayscriber),config(same directory asconfig.toml), orcustomcustom_directory— absolute path used whenstorage = "custom"; supports~per_output— whentrue(default) keep a separate session file for each monitor; set tofalseto share one file per Wayland display as in earlier releasesmax_shapes_per_frame— trims older shapes if a frame grows beyond this count when loading/savingmax_file_size_mb— skips loading and writing session files beyond this size cap; image paste and autosave warn near the capcompress—auto(gzip files above the threshold),on, oroffauto_compress_threshold_kb— size threshold forcompress = "auto"backup_retention— how many rotated.bakfiles to keep (set to 0 to disable backups)max_persisted_undo_depth— optional cap for serialized history; default follows the runtime undo limit (setpersist_history = falseto skip history entirely)
Privacy note: Session files are stored unencrypted. Clear the session directory or disable persistence when working with sensitive material.
Use the CLI helpers for quick maintenance:
wayscriber --session-infoprints the active storage path, file details, and shape counts.wayscriber --clear-sessionremoves the session file, backup, and lock.
Session overrides and recovery:
- CLI flags:
--resume-sessionforces persistence on,--no-resume-sessionforces it off for the current run. The environment variableWAYSCRIBER_RESUME_SESSION=1/0does the same. - Size fallback: if visible drawings fit but persisted undo/redo history would exceed save or restore safety limits, autosave saves the drawings and warns once per run that history was trimmed or omitted.
- Image paste guard: when a pasted image would push visible session data over
max_file_size_mb, Wayscriber blocks the paste and points you to[session] max_file_size_mb; when only undo history is at risk, the paste is allowed with a warning. - Load safety: compressed session files are checked against an internal expanded-size cap while saving and loading. If an existing file expands beyond that cap, wayscriber refuses to load it, leaves the primary session file unchanged, and avoids overwriting it until session data changes.
- Recovery: if a session file is corrupt or cannot be parsed/decompressed, wayscriber logs a warning, writes a
.bakcopy of the bad file, removes the corrupt file, and continues with defaults. Overrides above still apply after recovery.
[keybindings] - Custom Keybindings
Customize keyboard shortcuts for all actions. Each action can have multiple keybindings.
For multi-monitor, customize focus_prev_output and focus_next_output in this section.
[keybindings]
# Exit overlay (or cancel current action)
exit = ["Escape", "Ctrl+Q"]
# Enter text mode
enter_text_mode = ["T"]
# Enter sticky note mode
enter_sticky_note_mode = ["N"]
# Clear all annotations on current canvas
clear_canvas = ["E"]
# Undo last annotation
undo = ["Ctrl+Z"]
# Redo last undone annotation
redo = ["Ctrl+Shift+Z", "Ctrl+Y"]
# Duplicate current selection
duplicate_selection = ["Ctrl+D"]
# Copy/paste selection
copy_selection = ["Ctrl+Alt+C"]
paste_selection = ["Ctrl+Alt+V"]
# Select all annotations
select_all = ["Ctrl+A"]
# Reorder selected annotations within the stack
move_selection_to_front = ["]"]
move_selection_to_back = ["["]
# Nudge selection (hold Shift for a larger step)
nudge_selection_up = ["ArrowUp"]
nudge_selection_down = ["ArrowDown"]
nudge_selection_left = ["ArrowLeft", "Shift+PageUp"]
nudge_selection_right = ["ArrowRight", "Shift+PageDown"]
# Nudge selection (large step)
nudge_selection_up_large = ["PageUp"]
nudge_selection_down_large = ["PageDown"]
# Move selection to horizontal edges (left/right)
move_selection_to_start = ["Home"]
move_selection_to_end = ["End"]
# Move selection to vertical edges
move_selection_to_top = ["Ctrl+Home"]
move_selection_to_bottom = ["Ctrl+End"]
# Delete selection
delete_selection = ["Delete"]
# Adjust pen thickness
increase_thickness = ["+", "="]
decrease_thickness = ["-", "_"]
# Adjust marker opacity (when using the marker tool)
increase_marker_opacity = ["Ctrl+Alt+ArrowUp"]
decrease_marker_opacity = ["Ctrl+Alt+ArrowDown"]
# Tool selection shortcuts (optional; keep empty to rely on modifiers)
select_selection_tool = ["V"]
select_pen_tool = ["F"]
select_marker_tool = ["H"]
select_step_marker_tool = []
select_eraser_tool = ["D"]
toggle_eraser_mode = ["Ctrl+Shift+E"]
select_line_tool = []
select_rect_tool = []
select_ellipse_tool = []
select_triangle_tool = []
select_parallelogram_tool = []
select_rhombus_tool = []
select_regular_polygon_tool = []
select_freeform_polygon_tool = []
select_arrow_tool = []
select_blur_tool = []
select_highlight_tool = []
toggle_highlight_tool = ["Ctrl+Alt+H"]
# Reset label counters
reset_arrow_labels = ["Ctrl+Shift+R"]
reset_step_markers = []
# Adjust font size
increase_font_size = ["Ctrl+Shift++", "Ctrl+Shift+="]
decrease_font_size = ["Ctrl+Shift+-", "Ctrl+Shift+_"]
# Boards
toggle_whiteboard = ["Ctrl+W"]
toggle_blackboard = ["Ctrl+B"]
return_to_transparent = ["Ctrl+Shift+T"]
focus_prev_output = ["Ctrl+Alt+Shift+ArrowLeft"]
focus_next_output = ["Ctrl+Alt+Shift+ArrowRight"]
board_1 = ["Ctrl+Shift+1"]
board_2 = ["Ctrl+Shift+2"]
board_3 = ["Ctrl+Shift+3"]
board_4 = ["Ctrl+Shift+4"]
board_5 = ["Ctrl+Shift+5"]
board_6 = ["Ctrl+Shift+6"]
board_7 = ["Ctrl+Shift+7"]
board_8 = ["Ctrl+Shift+8"]
board_9 = ["Ctrl+Shift+9"]
board_prev = ["Ctrl+Shift+ArrowLeft"]
board_next = ["Ctrl+Shift+ArrowRight"]
board_new = ["Ctrl+Shift+N"]
board_delete = ["Ctrl+Shift+Delete"]
board_picker = ["Ctrl+Shift+B"]
# Page navigation
# Ubuntu/GNOME defaults avoid Ctrl+Alt workspace shortcuts (Ctrl+ArrowLeft/Right, Ctrl+PageUp/PageDown).
page_prev = ["Ctrl+Alt+ArrowLeft", "Ctrl+Alt+PageUp"]
page_next = ["Ctrl+Alt+ArrowRight", "Ctrl+Alt+PageDown"]
page_new = ["Ctrl+Alt+N"]
page_duplicate = ["Ctrl+Alt+D"]
page_delete = ["Ctrl+Alt+Delete"]
# Toggle help overlay
toggle_help = ["F10", "F1"]
# Toggle status bar visibility
toggle_status_bar = ["F12", "F4"]
# Toggle toolbars
toggle_toolbar = ["F2", "F9"]
# Toggle presenter mode
toggle_presenter_mode = ["Ctrl+Shift+M"]
# Toggle light passthrough mode while the overlay has focus
toggle_light_mode = ["Ctrl+Shift+L"]
# Optional in-overlay toggle between light drawing and passthrough.
# Once passthrough is active, use compositor/global shortcuts that call
# `wayscriber --light-draw-toggle`, `--light-draw-on`, or `--light-draw-off`.
toggle_light_mode_drawing = []
# Optional render color profile preview controls
render_profile_next = []
render_profile_previous = []
render_profile_off = []
# Toggle click highlight (visual mouse halo)
toggle_click_highlight = ["Ctrl+Shift+H"]
# Toggle fill for fill-capable shapes
toggle_fill = []
# Optional keyboard binding to toggle radial menu at cursor
toggle_radial_menu = []
# Toggle selection properties panel
toggle_selection_properties = ["Ctrl+Alt+P"]
# Toggle context menu (keyboard alternative to right-click)
open_context_menu = ["Shift+F10", "Menu"]
# Launch the desktop configurator (requires wayscriber-configurator)
open_configurator = ["F11"]
# Color selection shortcuts
set_color_red = ["R"]
set_color_green = ["G"]
set_color_blue = ["B"]
set_color_yellow = ["Y"]
set_color_orange = ["O"]
set_color_pink = ["P"]
set_color_white = ["W"]
set_color_black = ["K"]
# Screenshot shortcuts
capture_full_screen = ["Ctrl+Shift+P"]
capture_active_window = ["Ctrl+Shift+O"]
capture_selection = ["Ctrl+Shift+I"]
# Clipboard/File specific captures
capture_clipboard_full = ["Ctrl+C"]
capture_file_full = ["Ctrl+S"]
capture_clipboard_selection = ["Ctrl+Shift+C"]
capture_file_selection = ["Ctrl+Shift+S"]
capture_clipboard_region = ["Ctrl+6"]
capture_file_region = ["Ctrl+Alt+6"]
export_canvas_file = []
export_canvas_clipboard = []
export_canvas_clipboard_and_file = []
export_board_pdf_file = []
export_all_boards_pdf_file = []
# Open the most recent capture folder
open_capture_folder = ["Ctrl+Alt+O"]
# Toggle frozen mode
toggle_frozen_mode = ["Ctrl+Shift+F"]
# Zoom controls
zoom_in = ["Ctrl+Alt++", "Ctrl+Alt+="]
zoom_out = ["Ctrl+Alt+-", "Ctrl+Alt+_"]
reset_zoom = ["Ctrl+Alt+0"]
toggle_zoom_lock = ["Ctrl+Alt+L"]
refresh_zoom_capture = ["Ctrl+Alt+R"]
# Preset slots
apply_preset_1 = ["1"]
apply_preset_2 = ["2"]
apply_preset_3 = ["3"]
apply_preset_4 = ["4"]
apply_preset_5 = ["5"]
save_preset_1 = ["Shift+1"]
save_preset_2 = ["Shift+2"]
save_preset_3 = ["Shift+3"]
save_preset_4 = ["Shift+4"]
save_preset_5 = ["Shift+5"]
clear_preset_1 = []
clear_preset_2 = []
clear_preset_3 = []
clear_preset_4 = []
clear_preset_5 = []
# Help overlay (press F10 while drawing for a full reference)
Keybinding Format:
Keybindings are specified as strings with modifiers and keys separated by +:
- Simple keys:
"E","T","Escape","F10" - With modifiers:
"Ctrl+Z","Shift+T","Ctrl+Shift+W" - Special keys:
"Escape","Return","Backspace","Space","F10","F11","Home","End","PageUp","PageDown","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","+","-","=","_"
Supported Modifiers:
Ctrl(orControl)ShiftAlt
Modifier Order:
Modifiers can appear in any order - "Ctrl+Shift+W", "Shift+Ctrl+W", and "Shift+W+Ctrl" are all equivalent.
Multiple Bindings:
Each action supports multiple keybindings (e.g., both + and = for increase thickness).
Duplicate Detection: The system will detect and report duplicate keybindings at startup. If two actions share the same key combination, the application will log an error and use default keybindings.
Case Insensitive: Key names are case-insensitive in the config file, but will match the actual key case at runtime.
Examples:
Vim-style navigation keys:
[keybindings]
exit = ["Escape", "Q"]
clear_canvas = ["D"]
undo = ["U"]
Emacs-style modifiers:
[keybindings]
exit = ["Ctrl+G"]
undo = ["Ctrl+/"]
clear_canvas = ["Ctrl+K"]
Gaming-friendly (WASD area):
[keybindings]
exit = ["Q"]
toggle_help = ["H"]
undo = ["Z"]
clear_canvas = ["X"]
Notes:
- Modifiers (Shift, Ctrl, Alt, Tab) are always captured for drawing tools
- In text input mode, configured keybindings (like Ctrl+Q for exit) work before keys are consumed as text
- Color keys only work when not holding Ctrl (to avoid conflicts with other actions)
- Invalid keybinding strings will be logged and fall back to defaults
- Duplicate keybindings across actions will be detected and reported at startup
Defaults: Defaults match the original hardcoded keybindings where possible. Copy/paste selection uses Ctrl+Alt+C/Ctrl+Alt+V, so the clipboard-selection capture shortcut defaults to Ctrl+Shift+C to avoid conflicts. The paste action also accepts PNG/JPEG image data and local image files copied from a file manager.
Creating Your Configuration
-
Create the directory:
mkdir -p ~/.config/wayscriber -
Copy the example config:
cp config.example.toml ~/.config/wayscriber/config.toml -
Edit to your preferences:
nano ~/.config/wayscriber/config.toml
Configuration Priority
Settings are loaded in this order:
- Built-in defaults (hardcoded)
- Configuration file values (override defaults)
- Runtime changes via keybindings (temporary, not saved)
Note: Changes to the config file require restarting wayscriber daemon to take effect.
To reload config changes:
# Use the reload script
./reload-daemon.sh
# Or manually
pkill wayscriber
wayscriber --daemon &
Environment Variables
These override behavior at runtime. Bool-ish values treat anything except 0, false, or off as true.
WAYSCRIBER_NO_TRAY=1disables the tray icon (default: tray enabled)WAYSCRIBER_RESUME_SESSION=1/0forces session persistence on/off for the current run (default: unset; follows config)WAYSCRIBER_CONFIGURATOR=/path/to/wayscriber-configuratoroverrides the configurator executable pathWAYSCRIBER_FORCE_INLINE_TOOLBARS=1forces inline toolbars on Wayland (default: off)WAYSCRIBER_TOOLBAR_DRAG_PREVIEW=0disables inline toolbar drag preview (default: on)WAYSCRIBER_TOOLBAR_POINTER_LOCK=1enables pointer-lock drag path (experimental; default: on)WAYSCRIBER_TOOLBAR_DRAG_THROTTLE_MS=12throttles toolbar drag updates (default: 12; set 0 to disable)WAYSCRIBER_DEBUG_TOOLBAR_DRAG=1enables toolbar drag logging (default: off)WAYSCRIBER_DEBUG_TOOLBAR_COLOR=1enables toolbar color picker logging (default: off)WAYSCRIBER_DEBUG_DAMAGE=1enables damage region logging (default: off)WAYSCRIBER_XDG_OUTPUT=...forces GNOME fallback overlays onto a specific output (overridesui.preferred_output)WAYSCRIBER_XDG_FULLSCREEN=1requests fullscreen GNOME fallback overlays (overridesui.xdg_fullscreen)WAYSCRIBER_XDG_FULLSCREEN_FORCE=1bypasses the GNOME opacity safety checkRUST_LOG=infoenables Rust logging (default: unset; usewayscriber=debugfor app-level logs)
Troubleshooting
Config File Not Loading
If your config file isn't being read:
-
Check the file path:
ls -la ~/.config/wayscriber/config.toml -
Verify TOML syntax:
# Install a TOML validator if needed toml-validator ~/.config/wayscriber/config.toml -
Check logs for errors:
RUST_LOG=info wayscriber --active
Invalid Values
If you specify invalid values:
- Out of range: Values will be clamped to valid ranges
- Invalid color name: Falls back to default (red)
- Malformed RGB: Falls back to default color
- Parse errors: Entire config file ignored, defaults used
Check the application logs for warnings about config issues.
Advanced Usage
Per-Project Configs
While wayscriber uses a single global config, you can:
- Create different config files
- Symlink the active one to
~/.config/wayscriber/config.toml
Example:
# Create project-specific configs
cp config.example.toml ~/configs/wayscriber-presentation.toml
cp config.example.toml ~/configs/wayscriber-recording.toml
# Switch configs
ln -sf ~/configs/wayscriber-presentation.toml ~/.config/wayscriber/config.toml
Configuration Examples
High-contrast presentation mode:
[drawing]
default_color = "yellow"
default_thickness = 5.0
default_font_size = 48.0
[ui]
status_bar_position = "top-right"
Screen recording mode (subtle annotations):
[drawing]
default_color = "blue"
default_thickness = 2.0
default_font_size = 24.0
[performance]
buffer_count = 4
enable_vsync = true
ui_animation_fps = 30
[ui]
show_status_bar = false
Teaching/presentation mode (start in whiteboard):
[boards]
default_board = "whiteboard"
[drawing]
default_thickness = 4.0
default_font_size = 42.0
[ui]
status_bar_position = "top-right"
High-refresh display optimization:
[performance]
buffer_count = 4
enable_vsync = true
ui_animation_fps = 120
See Also
SETUP.md- Installation and system requirementsconfig.example.toml- Annotated example configurationREADME.md- Main documentation with usage guide