A screen recorder for the COSMIC desktop, with a
floating dock that sits above every workspace. Record the whole screen or a
region you drag out, with microphone, system audio, or both mixed together,
straight to .mp4.
Built the native way: the xdg-desktop-portal ScreenCast API asks COSMIC for permission, PipeWire delivers the frames, and GStreamer encodes them — with hardware (VA-API) H.264 when your machine has it, so recording barely touches the CPU.
Start from the panel applet, drag out a region, record — the pill keeps the elapsed time on screen while the border shows exactly what is being captured.
Settings: pick your audio sources, recording profile, 30/60 fps and resolution cap, then choose where files land. Recording starts behind a countdown, so it is never in the video.
Demos are hosted as release assets
rather than committed, to keep the repository small. Crisper .mp4 versions of
both are attached there too.
cargo build --release
./target/release/cosmic-recorder- Floating dock — always on top, on every workspace, drag it anywhere.
Idle dock, settings panel, and a compact recording pill with a live
RECtimer. - Full screen or region — drag a rectangle on a fullscreen overlay to record just that part. The selection stays highlighted with Record / Redraw / ✕ until you commit.
- Audio — microphone, system audio, or both mixed, with per-device selection and live mic mute while recording.
- Pause and resume mid-recording, with no gap in the finished file.
- Hidden while recording (the default) — the recorder UI disappears
entirely so it never appears in the video. Stop it with Super+Shift+S,
by launching the app again, from the panel indicator, or
cosmic-recorder --stop. - Asks permission once — the portal's restore token is saved, so COSMIC's screen-share dialog only appears on the very first recording.
- Panel applet and a status-area indicator with a live timer, pause and stop.
- CLI mode for scripts.
Recordings land in <save folder>/recording-<timestamp>.mp4, ~/Videos by
default.
./packaging/build-deb.sh
sudo apt install ./dist/cosmic-recorder_0.3.0_amd64.debThis installs both binaries, both desktop entries and the icon, and pulls in the GStreamer plugins the recorder needs.
cargo build --release
install -Dm755 target/release/cosmic-recorder ~/.local/bin/cosmic-recorder
install -Dm755 target/release/cosmic-recorder-applet ~/.local/bin/cosmic-recorder-applet
install -Dm644 assets/cosmic-recorder.desktop ~/.local/share/applications/cosmic-recorder.desktop
install -Dm644 assets/cosmic-recorder-applet.desktop ~/.local/share/applications/cosmic-recorder-applet.desktop
install -Dm644 assets/cosmic-recorder.svg ~/.local/share/icons/hicolor/scalable/apps/cosmic-recorder.svgTo add the applet to your panel: Settings → Desktop → Panel → Configure panel applets → Add applet → Cosmic Recorder.
COSMIC (or any Wayland desktop with a ScreenCast portal), PipeWire, and
GStreamer with the pipewire, good and bad plugin sets plus an H.264
encoder. To build you also need Rust ≥ 1.85 and libgstreamer1.0-dev.
Check what your machine actually has:
cosmic-recorder --checkIt reports every element and encoder the recorder looks for, plus your audio devices, without recording anything.
| Control | Does |
|---|---|
| grip handle (dots) | move the dock: hold-drag, or click once and the bar follows the cursor — click again to place, Esc to cancel |
| red button | start (behind a 3-2-1 countdown) / stop |
| mic chip | mute the microphone, live, mid-recording |
Screen chip |
choose full screen or drag out a region |
⚙ chip |
settings — devices, sound mix, profile, frame rate, resolution, save folder, whether the recorder shows in the video, accent colour |
| compact pill | stop · REC timer · pause/resume · mic mute |
✕ |
quit (finishes saving first if a recording is running) |
Everything persists across runs, including where you dragged the dock. Panels open above the dock, or below it when you've dragged the dock to the top of the screen. The UI scales itself to your screen so it keeps the design's proportions at any resolution.
The accent colour follows your COSMIC theme by default (honouring dark/light mode); switch Accent colour to Cosmo red for the classic look.
During a region recording the selected area keeps a red border on screen so you always know what is being captured. The border sits just outside the recorded rectangle, so it never appears in the video, and it is click-through, so it never blocks your mouse.
Stopping a hidden recording
With Recorder in video: Hidden (the default) there is nothing on screen to click. Any of these stop it:
- Super+Shift+S — registered as a COSMIC custom shortcut on first run
- the red dot in the panel's status area — click to stop, or open its menu for the live timer, Pause/Resume and Stop
- the panel applet
- launching Cosmic Recorder again
cosmic-recorder --stop
Set Recorder in video: Visible to keep the compact pill on screen instead — it will then appear in the video.
cosmic-recorder launch the dock
cosmic-recorder --record launch and start recording (toggles if running)
cosmic-recorder --stop stop the running instance's recording
cosmic-recorder --cli record in the terminal until Ctrl+C
cosmic-recorder --check report available encoders and devices
cosmic-recorder --remove-shortcut remove the Super+Shift+S shortcut
cosmic-recorder --version
# with --cli
--audio <mic|system|both>
--region <X,Y,WxH>
--quality <native|1080|720>
--profile <balanced|high|maximum>
--fps <30|60>
cosmic-recorder --cli --audio both --profile high --fps 60 --quality 1080
cosmic-recorder --cli --audio mic --region 100,100,1280x720- First run shows COSMIC's screen-share dialog — pick your display and Share. Every later run reuses that grant silently. The dialog appears before the countdown, so it is never in the recording.
- Reset the permission:
rm ~/.config/cosmic-recorder/restore-token - System audio records the monitor of your default output; microphone records the default input. Change the defaults in COSMIC's sound settings, or pick specific devices in the recorder's own settings.
- Multi-monitor: region recording assumes the region was drawn on the same output the portal granted. If they differ, the crop will be wrong — see docs/known-issues.md.
xdg-desktop-portal (COSMIC) — permission + picks the monitor
│ PipeWire node id + fd
▼
pipewiresrc ─ videoconvert ─ videorate ─ [videocrop] ─ [videoscale] ─ valve ─ H.264 ─┐
├─ mp4mux ─ filesink
pulsesrc ─ audioconvert ─ audioresample ─ [audiomixer] ─ valve ─ AAC ──────────────────┘
The recorder holds the portal session open for the length of the recording and
sends EOS on stop so mp4mux can write the file header — that step is what
makes the file playable. The valve elements are how pause works without
leaving a gap in the timeline.
src/
main.rs — argument parsing, single-instance signalling, dispatch
recorder.rs — the engine: portal session, pipeline, record/stop, pause + mute
app.rs — the dock UI (iced + iced_layershell)
outputs.rs — the screen's logical size, straight from the compositor
overlay.rs — the click-through region border
tray.rs — the panel status indicator (StatusNotifierItem)
theme.rs — design tokens and widget styles
icons.rs — the embedded Lucide icon font
config.rs — persisted settings
cli.rs — terminal mode
applet/ — the COSMIC panel applet (a separate binary, on libcosmic)
design/ — design.pen, the UI spec
docs/ — how the libraries are used, and what is known to be broken
packaging/ — .deb build script
The GUI hides itself while recording, so it cannot film its own dock — but
--cli is dispatched before the single-instance check, so a headless capture
runs happily alongside a GUI session and films everything:
./packaging/record-demo.sh 40 # 40 s, full screen
./packaging/record-demo.sh 40 gif # also write a README-sized GIFSet Recorder in video to Visible in settings first, or the pill will not be in the shot.
Start with docs/README.md. It explains what each library does in this project, what is tunable in it, and where the code currently fights the library instead of using it — docs/known-issues.md catalogues what is still wrong and why.
cargo test
cargo clippy --workspace --all-targets
cargo run --features dev-ui -- --ui-state settings # render a design stateGPL-3.0-or-later. See LICENSE.
Bundled fonts: Inter, Geist and IBM Plex Mono under the SIL Open Font License 1.1; the Lucide icon font under the ISC license.

