Skip to content

Latest commit

 

History

481 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Otto

A Wayland desktop that feels like someone cared. Smooth animations, thoughtful gestures, and the kind of details you notice only when they're missing — built from scratch in Rust on Smithay, with a Skia renderer and the lay-rs scene graph.

Otto is a Wayland compositor and stacking window manager. Parts of the desktop are handed straight to hardware display planes instead of being composited into one buffer.

You can try it inside your current session in about a minute — jump to Try it.

Documentation: User Guide · Developer Guide

Testing phase. Many features are ready for daily use, but Otto is not finished and not yet fully stable. Playing with it, breaking it and telling us about it is genuinely the most useful thing you can do right now. Feedback and questions: Discord or Matrix #otto-compositor:matrix.org.

See it

The Otto desktop

Wallpaper, top bar, Dock, Files browsing poster thumbnails, the user guide in a browser window.

Exposé

Exposé, with the workspace strip on top — the window previews are live, not screenshots.

A warm Otto desktop over a rainy jazz-club street, with a now-playing panel and a gold-tinted Dock

The same compositor, configured differently — and a third-party wlr-layer-shell widget (eww) on the desktop layer, behind windows and above the wallpaper. See Desktop Widgets.

A near-black Otto desktop over a James Webb deep field image, the brightness indicator over otto-settings

Otto's own surfaces follow the theme: the Dock down the right edge, the brightness indicator, and otto-settings editing the running compositor over D-Bus.

Otto Settings on a cold blue-grey desktop, showing the accent, corner and window-control settings

None of this is a theme engine: a look is an accent, an icon tint, which edge the Dock sits on and which side the window controls are — one config file. More of them in Customization.

Try it

Zero risk: Otto runs as a window inside the desktop you're using right now.

git clone https://github.com/nongio/otto
cd otto
cargo run --release        # opens Otto in a window (winit backend)

Then open something inside it (WAYLAND_DISPLAY=wayland-1 <your app>), minimize a window to the Dock, hit PageUp for Exposé, Ctrl+Tab for the app switcher.

For real: install a package and pick "Otto" in your login manager.

sudo dpkg -i otto_*.deb && sudo apt-get install -f   # Debian / Ubuntu
sudo dnf install otto-*.rpm                          # Fedora / RHEL
curl -O https://raw.githubusercontent.com/nongio/otto/main/PKGBUILD && makepkg -si   # Arch

Packages come from the GitHub Releases page. See Installation for the details and post-install notes, and the Getting Started guide for a walkthrough.

What you get

  • A Dock that is a real task manager — pinned apps, running apps and minimized windows in one strip, along the bottom edge or down either side. Icons magnify on approach, bounce while an app is launching, auto-hide when you want the space back, and the whole thing resizes by dragging its handle.

  • Workspaces that animate — multiple workspaces per monitor, each monitor independent, drag windows between them, configurable backgrounds.

  • Exposé and an app switcherPageUp (or a three-finger swipe up) spreads every window out with live previews; Ctrl+Tab walks apps, cycles windows within an app, and can close them. Both appear on the monitor under your pointer.

  • Window management that stays out of the way — animated fullscreen/maximize, snap to halves, minimize to the Dock, and new windows placed where they overlap the least. Otto draws the title bar for clients that want a server-side one, on both xdg-decoration and KDE's org_kde_kwin_server_decoration, so the controls keep working while an application is busy.

  • A top bar and a dynamic island — clock, tray and application menus over DBusMenu; notifications, ongoing activities and permission dialogs in a floating panel; compositor-drawn volume and brightness indicators.

  • Multi-monitor that holds up — per-output rendering, hotplug, arrangement and modes from the config, virtual outputs created on demand.

  • Lock, login and powerext-session-lock-v1 locking with a PAM-backed locker, lock on hotkey / power button / lid close / idle timeout (respecting idle-inhibit), a greetd login screen with password and fingerprint, and Otto-owned lid-suspend with clamshell awareness.

  • Screen sharing — an XDG Desktop Portal backend over PipeWire: share a whole output or a single window with browsers, OBS and anything else that speaks the portal, and send an output to an AirPlay receiver. The portal also answers file-picker, screenshot and permission-dialog requests.

  • Remote desktopotto-rdp serves an output to any RDP client (Microsoft Remote Desktop on Windows, macOS, iOS and Android, or FreeRDP), with TLS, hardware H.264 through VA-API where the GPU offers it and a bitmap fallback where it doesn't. Remote pointer and keyboard input is injected back into the session, so it is a screen you can actually work on.

  • Virtual outputs — monitors with no display behind them, declared in the config and rendered like any other screen, each published as a PipeWire node. They have their own workspaces, exposé and workspace selector, and you can drag windows onto them: a remote screen for RDP, a stage to record or cast from, or simply more desk than your hardware has.

  • X11 apps, including fullscreen games — keyboard focus for globally-active clients, output scale via XSETTINGS, direct scanout.

  • A file managerotto-files: list, icon and column views, thumbnails read from the shared cache other file managers write, drag and drop in and out of other apps, background copy/move/trash with progress and 32 levels of undo, and a quick-view panel on Space that previews pictures, text, PDFs and media details in a sandboxed process. It is also the desktop's file picker, so Open and Save dialogs in Firefox and Chrome are this window rather than a GTK one.

  • A settings appotto-settings edits the configuration live over D-Bus, so you don't have to hand-write TOML (you still can — the app writes to the same file, though it does not watch it for outside edits). Displays, Dock, input, sound, power, lock and login, and the shortcut list.

  • A launcherotto-launcher: Ctrl+Space to start an application, Ctrl+Shift+P to jump to a window, with fuzzy ranking and arithmetic in the query field. All three are first versions — they aim to be useful day to day, and each guide lists what is still missing rather than leaving you to find out.

  • Rendering built for this — a Skia pipeline with KMS multi-plane scanout (Dock, app switcher, popups and topmost windows on their own hardware planes) and cross-plane backdrop blur.

  • Input and theming — natural and two-finger scrolling, keyboard remapping, fully configurable shortcuts, dark/light themes, accent colors, and night shift through wlsunset or gammastep, which drive the hardware gamma tables.

  • Accessibility — the desktop's own chrome and bundled apps expose an AT-SPI tree over D-Bus through AccessKit, so a screen reader can walk the dock, the bar and the settings app, not just client windows. See Accessibility.

  • Translated — Otto's interface ships in German, English (GB and US), Spanish, French, Italian, Polish, Portuguese (Brazil), Russian and Ukrainian, selected with the locales setting.

Note on KMS scanout: on the tty-udev backend, Otto puts parts of the desktop on their own hardware planes instead of compositing everything into one buffer, keeping the number of overlapping planes small to limit GPU work. This has mostly been tested on Intel GPUs. Other drivers are expected to fall back to full composition when the atomic test rejects a plane configuration, but that path is untested — if you see missing, misplaced or flickering elements on AMD or NVIDIA, this is the first thing to suspect, and a report is welcome. See docs/developer/drm_plane.md.

Not there yet

  • Screen capture: a screenshot UI for picking a region or a window interactively, and per-window capture through wlr-screencopy. Whole-output and region capture already work with grim, the desktop portal answers screenshot requests from applications, and per-window capture is available through the screen-sharing portal.
  • Multi-monitor: display mirroring.
  • Dock: favorite locations; moving Dock code out of the compositor core.
  • Input: scroll acceleration.

Experimentation

  • Scene graph protocol: a WIP protocol (otto-surface-style-unstable-v1) exposing the scene graph and its animations to clients — size, position, corner radius, blur and shadow driven by compositor-side springs, a Core Animation-like model. The top bar and the dynamic island are built on it.

Supported Wayland protocols

Otto implements a comprehensive set of protocols — click to expand
  • Core: wl_compositor, wl_subcompositor, wl_shm, wl_seat, wl_data_device_manager
  • Shells: xdg_wm_base (XDG shell), xdg_decoration_manager_v1, org_kde_kwin_server_decoration, wlr_layer_shell_v1 (Layer shell 1.0), xwayland_shell_v1
  • Output management: wl_output, xdg_output, wp_presentation, wp_fractional_scale_v1, wp_viewporter
  • Rendering and DRM: zwp_linux_dmabuf_v1, wp_linux_drm_syncobj_v1 (explicit sync), wp_drm_lease_device_v1
  • Input: pointer gestures, relative pointer, pointer constraints, tablet, wp_cursor_shape_v1, keyboard shortcuts inhibit, text input, input method, virtual keyboard, zwlr_virtual_pointer_v1, XWayland keyboard grab
  • Selection: primary selection, data control (wlr-data-control)
  • Session: ext_session_lock_v1, zwp_idle_inhibit_manager_v1, xdg_activation_v1, security context
  • Window listing: ext_foreign_toplevel_list_v1, zwlr_foreign_toplevel_management_v1
  • Capture: zwlr_screencopy_v1
  • XDG foreign: cross-client surface identification
  • Display control: zwlr_gamma_control_v1 (color temperature / night shift with hardware gamma tables)
  • Otto extensions: otto-surface-style-unstable-v1, otto-dock-v1

For where each one is implemented and how to trace it through the code, see docs/developer/wayland.md.

Installation

Pre-built packages are on the GitHub Releases page.

Debian/Ubuntu (.deb)

# Download the .deb package from releases, then:
sudo dpkg -i otto_*.deb
sudo apt-get install -f  # Install dependencies if needed

Fedora/RHEL (.rpm)

# Download the .rpm package from releases, then:
sudo dnf install otto-*.rpm
# or
sudo rpm -i otto-*.rpm

Arch Linux

# Download PKGBUILD and let makepkg fetch the tarball automatically:
curl -O https://raw.githubusercontent.com/nongio/otto/main/PKGBUILD
makepkg -si

If you already downloaded the tarball from GitHub Releases, put the PKGBUILD in the same directory — makepkg will use it without re-downloading:

cd ~/Downloads  # wherever your otto-*-x86_64.tar.gz is
curl -O https://raw.githubusercontent.com/nongio/otto/main/PKGBUILD
makepkg -si

After installation

Otto appears in your login manager (GDM, SDDM, LightDM, …) as "Otto" in the session menu. Select it and log in.

  • The packages install /etc/otto/config.toml and never overwrite a modified one on upgrade. Edit it to configure the whole machine, or copy it to ~/.config/otto/config.toml for just your user. On a HiDPI display set screen_scale = 2.0. If that file is missing, Otto falls back to compiled-in defaults and you get an empty Dock with no pinned apps.
  • Screen sharing requires xdg-desktop-portal on your system.
  • Using Otto as the login screen (otto --login with otto-greeter) requires greetd. On Debian/Ubuntu, copy the shipped otto-lock.pam example to /etc/pam.d/otto-lock before using the screen locker — the Arch and Fedora packages install it for you.
  • Otto handles the lid switch and the power button itself. Set HandleLidSwitch=ignore and HandlePowerKey=ignore in logind.conf for those to work.

Building Otto

Prerequisites

Install these (package names vary by distribution). The Debian/Ubuntu names are what CI installs, so that list is the authoritative one — see the "System dependencies" step in .github/workflows/ci.yml.

  • Wayland and input: libwayland, libxkbcommon, libudev, libinput, libseat
  • Graphics: libgbm, libdrm, libEGL/Mesa, libpixman, libdisplay-info
  • Text: freetype, fontconfig
  • Session and IPC: libdbus, libsystemd
  • Screen sharing and remote desktop: pipewire, gstreamer and gstreamer-plugins-base (otto-rdp)
  • Authentication: libpam (otto-lock, otto-greeter)

On Debian and Ubuntu:

sudo apt-get install -y libdrm-dev libudev-dev libgbm-dev libxkbcommon-dev \
  libegl1-mesa-dev libwayland-dev libinput-dev libdbus-1-dev libsystemd-dev \
  libseat-dev libpipewire-0.3-dev libfreetype-dev libfontconfig-dev \
  libdisplay-info-dev libpixman-1-dev libgstreamer1.0-dev \
  libgstreamer-plugins-base1.0-dev libpam0g-dev

Add xwayland if you want to run X11 applications inside Otto. Minimum supported Rust is 1.87.0 for the compositor; building the whole workspace needs 1.96.0 (otto-rdp pins it through GStreamer).

Build and run

git clone https://github.com/nongio/otto
cd otto

# Run Otto (auto-detects backend)
cargo run --release

# Development features (scene debugger, profiler)
cargo run --features "dev"

With no argument Otto looks at WAYLAND_DISPLAY:

  • set (you are in a Wayland session) — it uses --winit and runs as a window
  • unset — it uses --tty-udev and drives the display directly

That check does not know about X11, so on an X11 session pass --winit explicitly; otherwise Otto tries to take over the display from your running desktop.

Force a backend by passing it as an argument:

  • --tty-udev: start Otto in a tty with udev support — the "traditional" launch of a Wayland compositor. May require root if your system has no logind.
  • --winit: start Otto as a Winit application, inside another X11 or Wayland session. Best for development.
  • --x11: start Otto as an X11 client. Quite basic and not really maintained, and not in the default feature set — build with --features x11 to get it. For running inside an X11 session, use --winit instead.

Configuration

Otto reads TOML configuration files, in this order (later files override earlier ones):

  1. System: /etc/otto/config.toml (installed by the packages, and marked as a config file so your edits survive an upgrade)
  2. User: $XDG_CONFIG_HOME/otto/config.toml (defaults to ~/.config/otto/config.toml)
  3. Local override: ./otto_config.toml (current directory, for development)
  4. Backend-specific: ./otto_config.{backend}.toml (highest priority)

otto_config.example.toml is a complete, commented example:

mkdir -p ~/.config/otto
cp otto_config.example.toml ~/.config/otto/config.toml
$EDITOR ~/.config/otto/config.toml

Or skip the editor and use the otto-settings app, which changes settings live and writes them back to the same file.

Backend-specific configuration

Files named otto_config.{backend}.toml in the current directory — otto_config.winit.toml, otto_config.udev.toml — override everything else. Handy when, say, you want a different screen_scale in a window than on bare metal.

Keyboard shortcuts

Every hotkey is configurable in the [keyboard_shortcuts] section:

[keyboard_shortcuts]
"Ctrl+Return" = { open_default = { role = "terminal", fallback = "foot" } }
"Ctrl+Space" = { run = { cmd = "otto-launcher", args = [] } }
"Logo+Space" = { open_default = "file_manager" }
"Logo+B" = { open_default = "browser" }
"Ctrl+1" = { builtin = "Workspace", index = 0 }
"Ctrl+Tab" = "ApplicationSwitchNext"
"Prior" = "ExposeShowAll"

For everything else — window management, workspaces, gestures, the Dock and top bar, screen sharing, remote desktop, locking and login — see the configuration reference and the User Guide.

Development

Otto is the compositor plus a set of components, each under components/ and buildable on its own with cargo build -p <name>:

Component Description
otto Main compositor binary
otto-bar Top bar: clock, tray and application menus
otto-islands Dynamic island: notifications, activities and dialogs
otto-lock PAM-backed screen locker (ext-session-lock-v1)
otto-greeter Login screen client speaking greetd's IPC
otto-auth-ui Authentication panel shared by the locker and the greeter
otto-settings Settings app, driving the compositor over D-Bus
otto-files File manager, and the desktop's file picker
otto-quickview Sandboxed preview decoder behind Files' quick view
otto-launcher Keyboard-driven launcher — type to filter apps and windows
otto-rdp RDP bridge serving a virtual output to a remote client
otto-kit UI toolkit the Otto clients are built on
xdg-desktop-portal-otto XDG Desktop Portal backend: screen sharing, file picker, screenshots, settings, permission dialogs
apps-manager Debug tool for ext_foreign_toplevel_list_v1

To exercise a component against a running compositor:

cargo run --release -- --winit &
WAYLAND_DISPLAY=wayland-1 cargo run -p otto-launcher

The Developer Guide covers architecture, the rendering pipeline, the render loop, the scene graph, layers, DRM planes, screen sharing and more. The same pages live in docs/developer/.

Profiling

Otto can profile itself with puffin, through the profile feature (also enabled by dev):

  1. Run the compositor with profiling on — the puffin HTTP server starts on port 8585:
    cargo run --features "profile" -- --winit
  2. Install puffin_viewer:
    cargo install puffin_viewer
  3. Connect it to 127.0.0.1:8585.

You get frame timing, render performance and other metrics for finding bottlenecks.

Note: your puffin_viewer version must match the puffin version Otto uses (0.19.x needs puffin_viewer 0.22.0 or later).

Contributing

Otto and LayersEngine are both open to contributions — test the compositor, report bugs, implement features, bring ideas. Questions and bug reports go to the issue tracker, the Discord server or the Matrix room.

The repository ships AGENTS.md, automated code review instructions and developer documentation, for human contributors and coding agents alike.

License

MIT. See LICENSE.

Credits

About

A stacking window manager built around animation, gesture, and spatial interaction.

Topics

Resources

Stars

86 stars

Watchers

3 watching

Forks

Releases

Used by

Contributors

Languages