def take(name, layout, spec):
    """Take the specified screenshots and optionally animate them."""
    # prepare the layout
    try:
        client.prepare_layout(layout, spec.windows, spec.before or [])
    except Exception:
        client.kill_group_windows()
        return False, "While preparing layout:\n" + traceback.format_exc()
    time.sleep(0.5)

    # initialize screenshooter, create output directory
    layout_dir = output_dir / layout
    layout_dir.mkdir(parents=True, exist_ok=True)
    commands = spec.commands or []
    screen = Screenshooter(layout_dir / name, spec.geometry, spec.delay)
    errors = []

    # take initial screenshot (without number if it's the only one)
    screen.shoot(numbered=bool(commands))

    # take screenshots for each command, animate them at the end
    if commands:
        for command in commands:
            try:
                client.run_layout_command(command)
            except Exception:
                errors.append(f"While running command {command}:\n{traceback.format_exc()}")
                break
            time.sleep(0.05)
            screen.shoot()
        screen.animate(clear=True)

    # cleanup the layout
    try:
        client.clean_layout(spec.after or [])
    except Exception:
        errors.append("While cleaning layout:\n" + traceback.format_exc())

    if errors:
        return False, "\n\n".join(errors)
    return True, ""
Take the specified screenshots and optionally animate them.
docs/screenshots/take_all.py