diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..32ebb15 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.rs] +indent_style = space +indent_size = 4 +max_line_length = 100 + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 + +[*.toml] +indent_style = space +indent_size = 4 + +[*.nix] +indent_style = space +indent_size = 2 diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..456b693 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Ensure we're at the repo root +cd "$(git rev-parse --show-toplevel)" || exit 1 + +echo "Running cargo fmt (auto-format)..." +# Run formatter to apply fixes but do not stage them. If formatting changed, +# fail the commit so the user can review and stage the changes manually. +cargo fmt --all +if ! git diff --quiet --exit-code; then + echo "" >&2 + echo "ERROR: cargo fmt modified files. Review changes, stage them, and commit again." >&2 + git --no-pager diff --name-only + exit 1 +fi + +echo "Running cargo clippy..." +# Matches CI: deny warnings to keep code health strict +if ! cargo clippy --workspace --all-targets --all-features -- -D warnings; then + echo "" >&2 + echo "ERROR: clippy found warnings/errors. Fix them before committing." >&2 + exit 1 +fi + +echo "Running cargo test..." +if ! cargo test --workspace --all-features; then + echo "" >&2 + echo "ERROR: Some tests failed. Fix tests before committing." >&2 + exit 1 +fi + +echo "All pre-commit checks passed." +exit 0 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..05414c4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,65 @@ +# Lan Mouse Agent Instructions + +## Overview + +Lan Mouse is an open-source Software KVM sharing mouse/keyboard input across local networks. The Rust workspace combines a GTK frontend, CLI/daemon mode, and multi-OS capture/emulation backends for Linux, Windows, and macOS. + +## Core principles + +- **Scope discipline.** Only implement what was requested; describe follow-up work instead of absorbing it. +- **Clarify OS behavior.** Ask when requirements touch OS-specific capture/emulation (they differ significantly). +- **Docs stay current.** Update [README.md](README.md) or [DOC.md](DOC.md) when touching public APIs or platform support. +- **Rust idioms.** Use `Result`/`Option`, `thiserror` for errors, descriptive logs, and concise comments for non-obvious invariants. + +## Terminology + +- **Client:** A remote machine that can receive or send input events. Each client is either _active_ (receiving events) or _inactive_ (can send events back). This mutual exclusion prevents feedback loops. +- **Backend:** OS-specific implementation for capture or emulation (e.g., libei, layer-shell, wlroots, X11, Windows, macOS). +- **Handle:** A per-client identifier used to route events and track state (pressed keys, position). + +## Architecture + +**Pipeline:** `input-capture` → `lan-mouse-ipc` → `input-emulation` + +- **input-capture:** Reads OS events into a `Stream`. Backends tried in priority order (libei → layer-shell → X11 → fallback). Tracks `pressed_keys` to avoid stuck modifiers. `position_map` queues events when multiple clients share a screen edge. +- **input-emulation:** Replays events via the `Emulation` trait (`consume`, `create`, `destroy`, `terminate`). Maintains `pressed_keys` and releases them on disconnect. +- **lan-mouse-ipc / lan-mouse-proto:** Protocol glue and serialization. Events are UDP; connection requests are TCP on the same port. Version bumps required when serialization changes. +- **input-event:** Shared scancode enums and abstract event types—extend here, don't duplicate translations. + +## Feature & cfg discipline + +- Feature flags live in root `Cargo.toml`. Gate OS-specific modules with tight cfgs (e.g., `cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))`). +- Prefer module-level gating over per-function cfgs to avoid empty stubs. +- New backends: add feature in `Cargo.toml`, create gated module, log backend selection. + +## Async patterns + +- Tokio runtime with `futures` streams and `async_trait`. Model new flows as streams or async methods. +- Avoid blocking; use `spawn_blocking` if needed. Prefer existing single-threaded stream handling. +- `InputCapture` implements `Stream` and manually pumps backends—don't short-circuit this logic. + +## Commands + +```sh +cargo build --workspace # full build +cargo build -p # single crate +cargo test --workspace # all tests +cargo fmt && cargo clippy --workspace --all-targets --all-features # lint +RUST_LOG=lan_mouse=debug cargo run # debug logging +``` + +Run from repo root—no `cd` in scripts. + +## Testing + +- Unit tests for utilities; integration tests for protocol behavior. +- OS-specific backends: test via GTK/CLI on target OS or document manual verification. +- Dummy backend exercises pipeline without real dependencies. +- Verify `terminate()` releases keys on unexpected disconnect. + +## Workflow + +1. Clarify ambiguous requirements, especially OS-specific behavior. +2. Implement minimal change; flag follow-up work. +3. Add proportional tests; run `cargo test` on affected crates. +4. Run `cargo fmt` and `cargo clippy --workspace --all-targets --all-features`. diff --git a/README.md b/README.md index fe6fdc3..f3b4b49 100644 --- a/README.md +++ b/README.md @@ -182,8 +182,27 @@ For a detailed list of available features, checkout the [Cargo.toml](./Cargo.tom +## Development -## Installing Dependencies for Development / Compiling from Source +### Git pre-commit hook + +This repository includes a local git hooks directory `.githooks/` with a `pre-commit` script that enforces formatting, lints, and tests before allowing a commit. It is optional to enable it, but it will prevent you from committing code with failing unit tests or that needs clippy/fmt fixes. To enable the hook locally: + +1. Make the hook executable: + +```sh +chmod +x .githooks/pre-commit +``` + +2. Point git to the hooks directory (one-time per clone): + +```sh +git config core.hooksPath .githooks +``` + +The `pre-commit` script runs `cargo fmt --all` (and fails if files were modified), `cargo clippy --workspace --all-targets --all-features -- -D warnings`, and `cargo test --workspace --all-features`. + +### Dependencies & Compiling from Source
MacOS @@ -456,4 +475,4 @@ The following sections detail the emulation and capture backends provided by lan - `libei`: This backend uses [libei](https://gitlab.freedesktop.org/libinput/libei) and is supported by GNOME >= 45 or KDE Plasma >= 6.1. - `windows`: Backend for input capture on Windows. - `macos`: Backend for input capture on MacOS. -- `x11`: TODO (not yet supported) +- `x11`: TODO (not yet supported) \ No newline at end of file