wayscriber

repository·main·Indexed 20 days ago

https://github.com/devmobasa/wayscriber

A 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.

Tokens
42K
Snippets
97
Records
173
Agent score
69%

What's inside wayscriber

  1. Overview of wayscriber

    main
    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.
  2. Core features of wayscriber

    main

    wayscriber 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 the V tool.

    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, and wl-clipboard (automatically installed via package managers) or falls back to xdg-desktop-portal.
  3. Wayscriber Roadmap and Feature Status

    main

    Wayscriber 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)
  4. Use Daemon Mode vs One-Shot Mode

    main

    Wayscriber offers two primary operational modes. Daemon Mode is highly recommended for most users.

    In this mode, a background process manages the overlay. This allows your drawings to persist even when the overlay is hidden.

    Workflow:

    1. Start: The daemon runs in the background (via systemd or compositor autostart).
    2. Toggle: Press your toggle shortcut (e.g., Super+D) to show the drawing overlay.
    3. Draw: Use all available tools.
    4. Hide: Press Escape or Ctrl+Q to hide the overlay. The daemon remains running.
    5. 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-tray or set the environment variable WAYSCRIBER_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:

    1. Start: Run wayscriber --active.
    2. Draw: Use the tools.
    3. Exit: Press Escape. The process exits completely.
    4. 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 --active
  5. Understand the Wayscriber configuration model

    main

    Wayscriber uses a strict configuration model where config.toml is 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 authored Config to 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 .bak file 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.toml via explicit user gestures.
      • Ephemeral: UI preferences like toolbar layout, section visibility, and icon mode mutate the in-memory Config but are not written to disk. These settings are restored to their configured values upon restart.
    • 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).
  6. Manage Multi-monitor Focus

    main

    In multi-monitor setups, you can cycle the overlay focus between different outputs:

    • Shortcut: Use Ctrl+Alt+Shift+← or Ctrl+Alt+Shift+→ (default) to move focus between outputs.
    • Command Palette: Search for monitor or display to find output actions.
    • Pinning Output: To pin the overlay to a specific monitor, set the preferred_output key in your configuration or use the environment variable WAYSCRIBER_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.

  7. How Process Ownership and Brokers Work

    main

    Wayscriber 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/wget for 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-paste prefix 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-copy publication: 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, and process-start identity. The daemon only marks the child as ready when all three values match. Exit is monitored via pidfd.

  8. How Daemon Mode works

    main

    Daemon mode provides a persistent background service. Its lifecycle follows these steps:

    1. Initialization: An authenticated process broker is created. Daemon::run acquires a daemon lock, installs Unix signal listeners and queue watchers, and publishes a v2 runtime identity.
    2. Services: It optionally starts a status tray and a portal global-shortcut listener.
    3. Control: Commands like --daemon-toggle publish generation-bound controls that atomically rename an ordered queue reference. The watched queue wakes directly in response.
    4. Execution: The control loop linearizes cancellation and effect commits under a durable decision lock. The event-loop thread is the sole applier of actions.
    5. 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.
  9. Toolbar Frontend Architecture

    main

    Wayscriber uses a decoupled architecture for toolbars to support multiple frontends (Wayland/Cairo and GTK4):

    • Contract Layer: src/ui/toolbar/model/top_spec.rs defines 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-in WidgetTree, 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.
  10. Understand the Wayscriber execution flow

    main

    To build on or integrate with Wayscriber, it is helpful to understand the high-level lifecycle of the application:

    1. Launch: Initiated via CLI, where you choose between Daemon mode or Active mode.
    2. Daemon Mode: Provides lifecycle management, tray integration, and toggles the backend on demand.
    3. Backend (Wayland): Sets up Wayland surfaces and loops, forwarding input to the InputState.
    4. Input & Drawing: InputState combined with draw and ui modules update the overlay contents and request renders.
    5. Capture: The capture subsystem handles screenshot actions asynchronously and sends desktop notifications.
    6. Runtime UI State: Layers direct toolbar/board preferences over configured seeds and manages guarded writes/recovery.
    7. Session Management: Loads and saves configured or named session state (including Open/Save As/Clear transactions).
    8. Configuration: The config module ensures user preferences are applied across all subsystems.
  11. How the Wayland Backend (Active Mode) works

    main

    When running in --active mode, Wayscriber uses a Wayland backend to create an overlay for drawing.

    The Bootstrap Process:

    1. backend::run_wayland creates a WaylandBackend.
    2. The backend connects to Wayland via smithay-client-toolkit and binds essential protocols: compositor, layer shell, SHM, outputs, seats, and registry.
    3. It loads configuration (colors, board settings, keybindings) and initializes InputState.
    4. 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 CaptureManager for screenshots.
    • Exits when InputState.should_exit is triggered (e.g., via Escape or tray close).
  12. Manage Runtime UI preferences

    main

    Wayscriber separates core configuration from UI state. While config.toml provides 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.toml with 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.