wayscriber
repository·main·Indexed 20 days ago
https://github.com/devmobasa/wayscriberA real-time screen annotation and presentation tool for Linux/Wayland, functioning as a lightweight daemon similar to ZoomIt on Windows. It allows users to draw, zoom, and highlight content over any running application. Key features include a variety of drawing tools (pen, highlighter, shapes, arrows), blur and spotlight effects, persistent drawing boards, click highlights, and screen freeze. It is written in Rust and supports Wayland compositors such as Hyprland, Sway, River, Wayfire, Niri/Cosmic, and Plasma/KWin, with partial support for GNOME.
What's inside wayscriber
- wayscriber is a real-time screen annotation tool for Linux/Wayland, designed as a lightweight, ZoomIt-like daemon. It allows users to draw over any application, use professional presentation tools (like callouts, zoom, and click highlights), and maintain persistent drawing boards between sessions. It is written in Rust and optimized for native Wayland performance using layer-shell.
Core features of wayscriber
mainwayscriber provides a comprehensive suite of presentation and annotation tools:
Drawing & Editing
- Tools: Freehand pen, highlighter, eraser (circle/rect), lines, rectangles, ellipses, polygons (with fill toggle), and arrows with auto-numbered labels.
- Advanced Effects: Blur tool (soften, pixelate, secure, black out), Spotlight tool (dims everything except drawn regions), and multi-line text/sticky notes.
- Interaction: Radial menu at cursor via
<kbd>Middle-click</kbd>, color picker with screen eyedropper, and selection via<kbd>Alt</kbd>-drag or theVtool.
Boards & Persistence
- Boards: Named boards with transparent overlays or custom backgrounds. Supports isolated pages and jumping to slots via
<kbd>Ctrl+Shift+1..9</kbd>. - Persistence: Session persistence is enabled by default for boards, undo/redo history, and tool state.
Presenter Tools
- Click Highlights: Configurable colors/radius/duration.
- Presenter Mode (
<kbd>Ctrl+Shift+M</kbd>): Hides UI and forces click highlights. - Screen Freeze (
<kbd>Ctrl+Shift+F</kbd>): Pauses the display while apps continue running. - Zoom: Zoom in/out using
<kbd>Ctrl+Alt</kbd>+ scroll or<kbd>+</kbd>/<kbd>-</kbd>. Reset zoom with<kbd>Ctrl+Alt+0</kbd>.
Capture
- Supports full-screen, active-window, and region captures. Uses
grim,slurp, andwl-clipboard(automatically installed via package managers) or falls back toxdg-desktop-portal.
Wayscriber Roadmap and Feature Status
mainWayscriber is a feature-rich annotation and screen capture tool for Linux (Wayland). The following features are currently implemented and available for use:
Drawing and Editing
- Highlighter & eraser tools
- Additional shapes (filled shapes)
- Selection tools & properties panel
- Blur tool
- Tablet/stylus support with pressure
- Color picker
- Screen eyedropper: pick a draw color from the screen
- Render color profiles
- Zoom (ZoomIt-style controls)
- Presets (tool/color/size slots)
- Numbered callouts (incrementing arrow labels)
Boards and Content
- Multiple customizable boards/backgrounds
- Board pages (multi-page boards)
- Sticky notes
- Save annotations to image
- Multi-page board PDF export
Capture and Presentation
- Capture and screenshots
- Presenter mode
- Click highlights
- Screen freeze
- Light passthrough mode
UI and Navigation
- Command palette
- Radial menu
- Toolbars and UI
- Multi-monitor support
- Daemon mode with system tray
- Session manager and persistence (named sessions, overlay actions, configurator catalog, CLI override, tray navigation)
Use Daemon Mode vs One-Shot Mode
mainWayscriber offers two primary operational modes. Daemon Mode is highly recommended for most users.
Daemon Mode (Recommended)
In this mode, a background process manages the overlay. This allows your drawings to persist even when the overlay is hidden.
Workflow:
- Start: The daemon runs in the background (via systemd or compositor autostart).
- Toggle: Press your toggle shortcut (e.g.,
Super+D) to show the drawing overlay. - Draw: Use all available tools.
- Hide: Press
EscapeorCtrl+Qto hide the overlay. The daemon remains running. - Resume: Press your toggle shortcut again to bring back the overlay with your previous drawings intact.
Tip: If you don't use a system tray, start the daemon with
wayscriber --daemon --no-trayor set the environment variableWAYSCRIBER_NO_TRAY=1.One-Shot Mode (Alternative)
This mode is for quick, one-time annotations where you do not need to save your work.
Workflow:
- Start: Run
wayscriber --active. - Draw: Use the tools.
- Exit: Press
Escape. The process exits completely. - Note: Every time you run the command, you start with a fresh overlay; previous drawings are lost.
# Daemon mode (background) wayscriber --daemon # One-shot mode (foreground) wayscriber --activeUnderstand the Wayscriber configuration model
mainWayscriber uses a strict configuration model where
config.tomlis treated as an immutable source of truth that is only modified through explicit user actions. The system distinguishes between authored configuration (what the user explicitly typed) and effective configuration (the validated, normalized, and clamped values actually used by the application).Key Concepts
- ConfigDocument: The central authority for managing configuration. It handles loading, validation, and the logic for merging user edits with the existing file. It maintains the lossless TOML source, validated
Config, and authoredConfigto ensure that editing one setting never accidentally overwrites others. - Atomic Writes: All configuration changes are performed using
save_with_backup. This method creates a timestamped.bakfile of the previous configuration and uses an atomic rename to ensure the file is never left in a corrupted state. - Ephemeral vs. Durable Settings:
- Durable: Settings like keybindings, presets, and colors are written to
config.tomlvia explicit user gestures. - Ephemeral: UI preferences like toolbar layout, section visibility, and icon mode mutate the in-memory
Configbut are not written to disk. These settings are restored to their configured values upon restart.
- Durable: Settings like keybindings, presets, and colors are written to
- Board Data: Board contents (colors, names, etc.) are part of the session, not the core configuration. They are managed via session autosave and only the initial board list is stored in
config.toml(written only by the configurator).
- ConfigDocument: The central authority for managing configuration. It handles loading, validation, and the logic for merging user edits with the existing file. It maintains the lossless TOML source, validated
Manage Multi-monitor Focus
mainIn multi-monitor setups, you can cycle the overlay focus between different outputs:
- Shortcut: Use
Ctrl+Alt+Shift+←orCtrl+Alt+Shift+→(default) to move focus between outputs. - Command Palette: Search for
monitorordisplayto find output actions. - Pinning Output: To pin the overlay to a specific monitor, set the
preferred_outputkey in your configuration or use the environment variableWAYSCRIBER_XDG_OUTPUT.
Note: Output switching is blocked while a capture, freeze, or zoom operation is in progress. You must finish or exit those modes first.
- Shortcut: Use
How Process Ownership and Brokers Work
mainWayscriber uses an authenticated process broker to manage lifecycle and security. The broker is created by the Daemon, active-overlay, About, or explicit update-check runs before any locks are acquired or threads are started.
Broker Responsibilities
- Child Management: The broker is the sole entity responsible for creating and reaping runtime children (e.g.,
curl/wgetfor update checks). - Shutdown Control: Each broker owns an out-of-band shutdown socket. Closing or signaling this channel preempts active bounded helpers, kills their process groups, and reaps owned children immediately.
- Resource Constraints: Helpers are subject to strict output caps. If a helper exceeds its declared cap, the operation fails.
wl-pasteprefix mode: Returns a bounded sample and stops the helper once the prefix is complete.- Screenshot helpers: Use a 256 MiB cap to accommodate large compositor captures.
wl-copypublication: Uses the same 256 MiB cap.
Overlay Lifecycle
Overlays use a CSPRNG generation passed to the candidate. After winning the overlay singleton lock, the candidate publishes a private readiness record containing its
generation,PID, andprocess-start identity. The daemon only marks the child as ready when all three values match. Exit is monitored viapidfd.- Child Management: The broker is the sole entity responsible for creating and reaping runtime children (e.g.,
How Daemon Mode works
mainDaemon mode provides a persistent background service. Its lifecycle follows these steps:
- Initialization: An authenticated process broker is created.
Daemon::runacquires a daemon lock, installs Unix signal listeners and queue watchers, and publishes a v2 runtime identity. - Services: It optionally starts a status tray and a portal global-shortcut listener.
- Control: Commands like
--daemon-togglepublish generation-bound controls that atomically rename an ordered queue reference. The watched queue wakes directly in response. - Execution: The control loop linearizes cancellation and effect commits under a durable decision lock. The event-loop thread is the sole applier of actions.
- Process Management: The daemon manages generation/pidfd decisions, while the process broker handles waiting and reaping. Overlay readiness is only accepted after a child wins its lock and publishes a matching process identity.
- Initialization: An authenticated process broker is created.
Toolbar Frontend Architecture
mainWayscriber uses a decoupled architecture for toolbars to support multiple frontends (Wayland/Cairo and GTK4):
- Contract Layer:
src/ui/toolbar/model/top_spec.rsdefines a renderer-neutral contract. It specifies control IDs, strip/divider/chrome/overflow nodes, events, active/enabled states, labels, tooltips, and shortcut badges. It does not contain geometry or toolkit-specific types. - Wayland Frontend:
src/backend/wayland/toolbar/view/top/adapts the contract to the built-inWidgetTree, handling Cairo geometry, hit testing, and popover placement. - GTK Frontend:
src/toolbar_gtk/view/top_bar/adapts the same contract to GTK widgets, managing CSS, drag gestures, and popover lifecycles.
- Contract Layer:
Understand the Wayscriber execution flow
mainTo build on or integrate with Wayscriber, it is helpful to understand the high-level lifecycle of the application:
- Launch: Initiated via CLI, where you choose between Daemon mode or Active mode.
- Daemon Mode: Provides lifecycle management, tray integration, and toggles the backend on demand.
- Backend (Wayland): Sets up Wayland surfaces and loops, forwarding input to the
InputState. - Input & Drawing:
InputStatecombined withdrawanduimodules update the overlay contents and request renders. - Capture: The capture subsystem handles screenshot actions asynchronously and sends desktop notifications.
- Runtime UI State: Layers direct toolbar/board preferences over configured seeds and manages guarded writes/recovery.
- Session Management: Loads and saves configured or named session state (including Open/Save As/Clear transactions).
- Configuration: The
configmodule ensures user preferences are applied across all subsystems.
How the Wayland Backend (Active Mode) works
mainWhen running in
--activemode, Wayscriber uses a Wayland backend to create an overlay for drawing.The Bootstrap Process:
backend::run_waylandcreates aWaylandBackend.- The backend connects to Wayland via
smithay-client-toolkitand binds essential protocols: compositor, layer shell, SHM, outputs, seats, and registry. - It loads configuration (colors, board settings, keybindings) and initializes
InputState. - A layer-shell overlay surface is created, and the event loop begins.
The Main Loop:
- Dispatches Wayland events (keyboard, pointer, seat, compositor) via Smithay handlers.
- Throttles rendering using frame callbacks and vsync.
- Communicates with the
CaptureManagerfor screenshots. - Exits when
InputState.should_exitis triggered (e.g., via Escape or tray close).
Manage Runtime UI preferences
mainWayscriber separates core configuration from UI state. While
config.tomlprovides the 'seeds' (initial values), direct user manipulations of the UI (like moving the toolbar or pinning a board) are stored as overrides in a separate runtime-state file.Supported Runtime Overrides
- Pins: Board pins and toolbar pins.
- Visibility: Minimize/maximize states, side pane visibility, and collapsed sections.
- Layout: Toolbar positions (
top_position,side_position) and display modes (top_display_mode). - Order: Item visibility and ordering within UI elements.
Behavior
- Seed vs. Override: At startup, the system reconciles the authored seeds from
config.tomlwith the overrides in the runtime-state file. Overrides take precedence. - Recovery: If a runtime-state file is invalid or contains unsupported versions, the system provides recovery actions (retry, adopt, or preserve-reset) via the Toolbar Settings interface. The system is designed to be additive; older builds will treat new V1 keys as unknown and preserve them verbatim.