As a Mac switcher to Omarchy I needed an easy way of doing quick screen recordings without firing up OBS Studio (which may or may not have an easy way to do screen recordings - I just haven’t learnt it yet). I was used to CleanShotX on the Mac which made it super simple to do quick demo screencasts (which I do often)

This guide will walk you through creating a screen recording system with a flashing red indicator in your waybar, automatic video compression, and seamless clipboard integration.

What We’re Building

  • Visual feedback: A flashing red dot in waybar while recording
  • Region selection: Use slurp to select exactly what to record
  • Audio support: Record with microphone audio or silent mode
  • Smart compression: Automatically compress recordings with H.264
  • Clipboard integration: Video path copied to clipboard when done
  • One-key operation: Start/stop recording with a single keybind

Dependencies

Before we start, install these packages on Arch:

sudo pacman -S wl-screenrec slurp wl-clipboard ffmpeg waybar
  • wl-screenrec - Wayland screen recorder
  • slurp - Region selection tool
  • wl-clipboard - Clipboard utilities for Wayland
  • ffmpeg - For video compression
  • waybar - Status bar (you probably already have this)

DEMO

The Screen Recording Script

Create ~/screen-record.sh:

#!/usr/bin/env bash

# Parse command line arguments
SILENT=false
COMPRESS=true
while [[ $# -gt 0 ]]; do
  case $1 in
  --silent)
    SILENT=true
    shift
    ;;
  --no-compress)
    COMPRESS=false
    shift
    ;;
  *)
    echo "Unknown option: $1"
    echo "Usage: $0 [--silent] [--no-compress]"
    exit 1
    ;;
  esac
done

SAVE_DIR="$HOME/Videos"
mkdir -p "$SAVE_DIR"

# ── Stop if already recording ──────────────────────────────────────────────
if pgrep -x wl-screenrec >/dev/null; then
  pkill -INT wl-screenrec
  
  # Wait up to 3 seconds for graceful shutdown
  for i in {1..15}; do
    pgrep -x wl-screenrec >/dev/null || break
    sleep 0.2
  done
  
  # Force kill if still running (prevents infinite loops with stuck processes)
  if pgrep -x wl-screenrec >/dev/null; then
    pkill -9 wl-screenrec
    sleep 0.5
  fi
  
  LATEST=$(ls -t "$SAVE_DIR"/*.mp4 | head -n1)

  # Compress the video if enabled
  if [[ "$COMPRESS" == true ]] && command -v ffmpeg >/dev/null; then
    notify-send "Compressing video..." "Please wait" --expire-time=2000
    
    COMPRESSED="${LATEST%.mp4}_compressed.mp4"
    if ffmpeg -i "$LATEST" -c:v libx264 -crf 23 -preset medium -c:a copy -movflags +faststart "$COMPRESSED" -y 2>/dev/null; then
      # Get file sizes for comparison
      ORIG_SIZE=$(du -h "$LATEST" | cut -f1)
      COMP_SIZE=$(du -h "$COMPRESSED" | cut -f1)
      
      # Replace original with compressed version
      mv "$COMPRESSED" "$LATEST"
      
      notify-send "Recording finished & compressed" "Size: $ORIG_SIZE$COMP_SIZE" --expire-time=2500
    else
      notify-send "Recording finished" "Compression failed, keeping original" --expire-time=2500
    fi
  else
    notify-send "Recording finished" "Path copied: $(basename "$LATEST")" --expire-time=1500
  fi

  # Copy the file path to clipboard as text
  echo "$LATEST" | wl-copy

  # Also try to open the file location in file manager for easy drag-and-drop
  if command -v xdg-open >/dev/null; then
    xdg-open "$(dirname "$LATEST")" &
  fi

  # Signal waybar to update
  pkill -RTMIN+8 waybar 2>/dev/null || true
  
  exit 0
fi

# ── Pick region ────────────────────────────────────────────────────────────
REGION=$(slurp) || exit 1

FILE="$SAVE_DIR/$(date +'%Y-%m-%d_%H-%M-%S').mp4"

if [[ "$SILENT" == false ]]; then
  # ── Choose which ONE source to record ──────────────────────────────────────
  MIC_SRC=$(pactl info | awk -F': ' '/Default Source/ {print $2}')
  AUDIO_SRC="$MIC_SRC"
  DESC=$(pactl list sources | awk -v s="$AUDIO_SRC" '$2==s {getline;sub(/^\s*Description: /,"");print;exit}')

  notify-send "Recording… (source: $DESC)" --expire-time=1000

  wl-screenrec -g "$REGION" --audio --audio-device "$AUDIO_SRC" -f "$FILE" &
else
  notify-send "Recording… (silent mode)" --expire-time=1000

  wl-screenrec -g "$REGION" -f "$FILE" &
fi

# Signal waybar to update
pkill -RTMIN+8 waybar 2>/dev/null || true

Make it executable:

chmod +x ~/screen-record.sh

Script Highlights

  1. Toggle behavior: If already recording, stops the recording. Otherwise, starts a new one.
  2. Robust process handling: Tries graceful shutdown first, then force kills if needed (prevents stuck recordings).
  3. Automatic compression: Uses H.264 codec for universal browser compatibility while still reducing file size significantly.
  4. Smart notifications: Shows compression progress and file size reduction.
  5. Waybar integration: Sends signals to update the recording indicator.

Waybar Configuration

Add this custom module to your waybar config (~/.config/waybar/config.jsonc):

// In modules-right, add "custom/recording" at the beginning:
"modules-right": [
    "custom/recording",  // Add this line
    "group/tray-expander",
    "bluetooth",
    "network",
    "pulseaudio",
    "cpu",
    "battery"
],

// Then add the module definition:
"custom/recording": {
    "exec": "pgrep -x wl-screenrec > /dev/null && echo '●' || echo ''",
    "interval": 1,
    "format": "{}",
    "tooltip": false,
    "on-click": "~/screen-record.sh"
}

How the Waybar Module Works

  • exec: Checks if wl-screenrec is running every second
  • Shows when recording, nothing when not
  • on-click: Clicking the dot runs the script (stops recording)
  • interval: 1: Updates every second for responsive feedback

Waybar Styling

Add this to your waybar CSS (~/.config/waybar/style.css):

/* Recording indicator */
#custom-recording {
  color: #ff0000;
  font-size: 16px;
  margin-right: 8px;
  animation: blink 1s linear infinite;
}

@keyframes blink {
  0% { opacity: 1; }
  50% { opacity: 1; }
  51% { opacity: 0; }
  100% { opacity: 0; }
}

This creates a red dot that blinks on and off every second, making it impossible to miss when you’re recording.

Hyprland Keybinding

Add this to your Hyprland config:

bind = SUPER SHIFT, R, exec, ~/screen-record.sh
bind = SUPER ALT, R, exec, ~/screen-record.sh --silent

Now you can:

  • Super+Shift+R: Start recording with audio
  • Super+Alt+R: Start recording without audio
  • Press again to stop recording

Usage Flow

  1. Press your keybind → Slurp opens for region selection
  2. Draw a rectangle → Recording starts, red dot appears in waybar
  3. Press keybind again → Recording stops, video is compressed
  4. Notification shows compression → “Size: 7.7MB → 2.3MB”
  5. File manager opens → Video path is in your clipboard

Pro Tips

  • High DPI screens: The script handles any resolution, but high DPI screens create larger files
  • Disable compression: Use --no-compress flag if you need the original quality
  • Audio sources: The script auto-detects your default microphone
  • Quick sharing: The video path is automatically copied to clipboard

Troubleshooting

If recording won’t start:

  • Check if a previous recording is stuck: pkill -9 wl-screenrec
  • Ensure all dependencies are installed
  • Check waybar logs: journalctl -u waybar -f

If the red dot doesn’t appear:

  • Restart waybar: pkill waybar && waybar &
  • Check your waybar config syntax with waybar -c ~/.config/waybar/config.jsonc

Conclusion

This setup gives you a simple screen recording workflow in Omarchy with visual feedback and automatic compression. The flashing red dot ensures you never forget you’re recording, and the hot-key operation makes it effortless to capture anything on your screen.