Contributing - ArunPrakashG/native-launcher GitHub Wiki

Contributing to Native Launcher

Thank you for your interest in contributing to Native Launcher! This guide will help you get started.

Table of Contents

Code of Conduct

  • Be respectful and constructive in discussions
  • Focus on the code, not the person
  • Welcome newcomers and help them get started
  • Follow the project's technical standards
  • No harassment or discriminatory behavior

Ways to Contribute

🐛 Report Bugs

Found a bug? Open an issue with:

  • Clear title describing the problem
  • Steps to reproduce the issue
  • Expected vs actual behavior
  • Environment details (compositor, GTK version, Rust version)
  • Logs if available (RUST_LOG=debug native-launcher)

💡 Suggest Features

Have an idea? Open a discussion with:

  • Use case - What problem does it solve?
  • Proposed solution - How would it work?
  • Alternatives considered - Other approaches?
  • Performance impact - Will it affect startup/search time?

📝 Improve Documentation

Documentation improvements are always welcome:

  • Fix typos or clarify existing docs
  • Add examples or screenshots
  • Create tutorials or guides
  • Translate documentation (future)

🔧 Submit Bug Fixes

See the Development Setup section below.

✨ Develop Plugins

See the Plugin Development Guide for creating new plugins.

🌍 Add Translations (Future)

Translation support is planned for Phase 3. Check the roadmap in plans.md.

Development Setup

Prerequisites

  1. Rust toolchain (1.70+):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  1. GTK4 development libraries:

Arch/Manjaro:

sudo pacman -S gtk4 gtk4-layer-shell

Fedora:

sudo dnf install gtk4-devel gtk4-layer-shell-devel

Ubuntu/Debian:

sudo apt install libgtk-4-dev libgtk4-layer-shell-dev

Clone and Build

# Clone the repository
git clone https://github.com/ArunPrakashG/native-launcher.git
cd native-launcher

# Build in debug mode
cargo build

# Run with logging
RUST_LOG=debug cargo run

# Build optimized release
cargo build --release

Development Tools

Recommended IDE: VS Code with Rust Analyzer extension

Useful commands:

# Run tests
cargo test

# Run benchmarks
cargo bench

# Check code without building
cargo check

# Format code
cargo fmt

# Lint code
cargo clippy

# Generate documentation
cargo doc --open

Building and Testing

Running Tests

# Run all tests
cargo test

# Run specific test
cargo test test_name

# Run tests with output
cargo test -- --nocapture

# Run tests with logging
RUST_LOG=debug cargo test

Testing Changes Manually

  1. Build release binary:
cargo build --release
  1. Test on your compositor:
./target/release/native-launcher
  1. Test with different apps:
  • Apps with actions (Firefox, Chrome, VS Code)
  • Terminal apps (htop, vim)
  • Apps with special exec formats

Performance Testing

Startup time:

time ./target/release/native-launcher

Search benchmarks:

cargo bench

Memory usage:

/usr/bin/time -v ./target/release/native-launcher

Code Style Guidelines

Rust Style

Follow standard Rust conventions:

// ✅ Good: Use descriptive names
fn calculate_relevance_score(query: &str, entry: &DesktopEntry) -> f64 {
    // ...
}

// ❌ Bad: Cryptic abbreviations
fn calc_rel_sc(q: &str, e: &DesktopEntry) -> f64 {
    // ...
}

Error Handling

// ✅ Good: Use Result for fallible functions
fn parse_desktop_file(path: &Path) -> Result<DesktopEntry> {
    let contents = std::fs::read_to_string(path)?;
    // ...
}

// ❌ Bad: Don't use unwrap() in production code
fn parse_desktop_file(path: &Path) -> DesktopEntry {
    let contents = std::fs::read_to_string(path).unwrap();
    // ...
}

GTK4 Patterns

// ✅ Good: Use Rc<RefCell<T>> for shared mutable state
let usage_enabled = true; // usually derived from config
let search_engine = Rc::new(RefCell::new(SearchEngine::new(entries, usage_enabled)));
let search_engine_clone = search_engine.clone();

entry.connect_changed(move |entry| {
    let results = search_engine_clone.borrow().search(&query, 10);
    // ...
});

// ❌ Bad: Don't use unwrap() in GTK callbacks
button.connect_clicked(move |_| {
    let engine = search_engine.borrow_mut(); // Could panic!
    // ...
});

Performance Guidelines

Critical rules (see copilot-instructions.md):

  • ❌ Don't add features that degrade startup time or search latency
  • ❌ Don't add dependencies without profiling their impact
  • ❌ Don't add visual effects that block the UI thread
  • ✅ Profile before and after every significant change
  • ✅ Question any feature that adds >10ms to critical paths
  • ✅ Cache aggressively, compute lazily, render on-demand

Performance targets (hard limits):

  • Startup: <100ms cold start (target: <50ms)
  • Search: <10ms for 500 apps (target: <5ms)
  • Memory: <30MB idle (target: <20MB)
  • UI latency: <16ms (60fps, target: 120fps)

Code Formatting

Run before committing:

cargo fmt
cargo clippy

Clippy configuration: See clippy.toml for project-specific lints.

Submitting Changes

1. Create a Branch

git checkout -b feature/your-feature-name
# or
git checkout -b fix/bug-description

Branch naming:

  • feature/ - New features
  • fix/ - Bug fixes
  • refactor/ - Code refactoring
  • docs/ - Documentation only
  • perf/ - Performance improvements

2. Make Your Changes

  • Write tests for new functionality
  • Update documentation if behavior changes
  • Follow code style guidelines
  • Keep commits focused (one logical change per commit)

3. Test Thoroughly

# Run all tests
cargo test

# Run clippy
cargo clippy

# Format code
cargo fmt

# Test manually on compositor
cargo build --release
./target/release/native-launcher

4. Commit Your Changes

Write clear commit messages:

# Good commit message format
git commit -m "feat: Add fuzzy search support

- Integrate nucleo crate for fuzzy matching
- Add relevance scoring algorithm
- Update tests and benchmarks

Closes #42"

Commit message format:

  • feat: - New feature
  • fix: - Bug fix
  • refactor: - Code refactoring
  • docs: - Documentation changes
  • perf: - Performance improvements
  • test: - Test additions/changes
  • chore: - Build/tooling changes

5. Push and Create Pull Request

git push origin feature/your-feature-name

Then open a PR on GitHub with:

  • Clear title describing the change
  • Description explaining what and why
  • Related issues (Closes #42, Fixes #43)
  • Testing done (how you verified it works)
  • Screenshots (for UI changes)
  • Breaking changes (if any)

6. Code Review Process

  • Maintainers will review your PR
  • Address feedback constructively
  • Make requested changes in new commits
  • Once approved, maintainer will merge

Plugin Development

See the comprehensive Plugin Development Guide for:

  • Creating new plugins
  • Implementing the Plugin trait
  • Handling keyboard events
  • Best practices and examples

Documentation

Where Documentation Lives

  • README.md - Quick start and overview
  • Wiki - Comprehensive guides and references
  • Code comments - Implementation details
  • plans.md - Roadmap and architecture decisions

Updating Documentation

When making changes:

  1. Update code comments if implementation changes
  2. Update README if user-facing behavior changes
  3. Update wiki if architecture changes
  4. Update tests to reflect new behavior

Documentation Style

Code comments:

/// Searches for applications matching the query.
///
/// # Arguments
/// * `query` - The search string
/// * `limit` - Maximum number of results
///
/// # Returns
/// Vector of matching desktop entries, sorted by relevance
pub fn search(&self, query: &str, limit: usize) -> Vec<&DesktopEntry> {
    // ...
}

Wiki pages:

  • Use clear headings and table of contents
  • Include code examples with explanations
  • Add screenshots for UI features
  • Link to related pages

Questions?


Thank you for contributing to Native Launcher! 🚀

⚠️ **GitHub.com Fallback** ⚠️