Skip to content

Restructure codebase into modular architecture#1

Closed
ledati16 wants to merge 100 commits intomainfrom
claude/restructure-modular-codebase-01Uzyx6PGpuKhi7sB5xBALhk
Closed

Restructure codebase into modular architecture#1
ledati16 wants to merge 100 commits intomainfrom
claude/restructure-modular-codebase-01Uzyx6PGpuKhi7sB5xBALhk

Conversation

@ledati16
Copy link
Copy Markdown
Owner

@ledati16 ledati16 commented Dec 10, 2025

This pull request rebrands the project from "NASW" (Niri Audio Switcher) to "PWSW" (PipeWire Switcher), broadening its scope from a Niri-specific tool to a Wayland compositor-agnostic audio switcher. The documentation, configuration, and build files have all been updated to reflect this new focus, including support for multiple compositors via standard Wayland protocols and improved clarity on usage, supported platforms, and architecture. Additionally, a new CLAUDE.md file has been added to provide detailed guidance for contributors and LLMs.

Project rebranding and scope expansion:

  • Renamed the project from "NASW" to "PWSW" throughout all documentation and build files, including updates to the binary name, configuration paths, and repository links. The description now reflects support for multiple Wayland compositors rather than just Niri. [1] [2] [3] [4] [5] [6] [7] [8]

Documentation and configuration improvements:

  • Updated the README to document new supported compositors (Sway, Hyprland, Niri, KDE Plasma, etc.) via standard Wayland protocols (wlr-foreign-toplevel-management and plasma-window-management), and clarified that GNOME/Mutter is not supported.
  • Modernized and clarified CLI command usage, configuration file locations, and example config, replacing Niri-specific instructions with compositor-agnostic guidance. [1] [2] [3] [4] [5]

Build system and dependency updates:

  • Updated Cargo.toml to reflect the new project name, version, description, keywords, and repository. Added explicit dependencies for Wayland protocol support (wayland-client, wayland-protocols-wlr, wayland-protocols-plasma) and expanded Tokio features.

Contributor guidance:

  • Added a comprehensive CLAUDE.md file with project overview, architecture, build instructions, configuration notes, and common pitfalls to assist contributors and LLMs in understanding and safely modifying the codebase.

General improvements and clarifications:

  • Improved explanations of the threading model, IPC infrastructure, and configuration validation. Updated references to commands, file paths, and environment variables to match the new project name and broadened scope. [1] [2] [3] [4]This pull request introduces a major rebranding and architectural clarification for the project, transitioning from "NASW" (Niri Audio Switcher) to "PWSW" (PipeWire Switcher). The changes include renaming, documentation updates, and improved clarity about supported compositors, protocols, and usage. Additionally, a comprehensive developer guide (CLAUDE.md) is added, and the Cargo.toml is updated to reflect new dependencies and project metadata.

Project rebranding and documentation overhaul:

  • The project is renamed from "NASW" to "PWSW" throughout the codebase and documentation, including all references in README.md, Cargo.toml, and configuration examples. The description and keywords are updated to reflect broader Wayland compositor support, not just Niri. [1] [2] [3] [4] [5] [6] [7] [8]

Expanded compositor and protocol support:

  • The documentation now clarifies that PWSW supports a wide range of Wayland compositors via standard protocols (wlr-foreign-toplevel-management and plasma-window-management), listing compatible compositors explicitly and noting that GNOME/Mutter is not supported.

Improved user and developer guidance:

  • A new CLAUDE.md file provides a detailed overview of the architecture, threading model, configuration, and testing procedures for developers and advanced users.
  • The README.md is updated with clearer instructions for building, running, and managing the daemon, as well as for using IPC commands and finding relevant configuration fields. [1] [2]

Dependency and configuration updates:

  • Cargo.toml is updated with new project metadata, repository URL, and additional dependencies for Wayland protocol support (wayland-client, wayland-protocols-wlr, wayland-protocols-plasma). The tokio dependency is expanded with more features for async support.

Configuration and usage improvements:

  • The configuration examples and documentation are updated to reflect new command names, improved notification settings, and better guidance for discovering window/app IDs across various compositors. [1] [2]

These changes collectively modernize the project, clarify its scope and usage, and provide both users and contributors with more comprehensive and accurate information.This pull request renames the project from "NASW" (Niri Audio Switcher) to "PWSW" (PipeWire Switcher) and broadens its focus from the Niri compositor to general Wayland compositors using standard window management protocols. The documentation and configuration have been updated to reflect this, and the codebase now includes new modules for CLI argument parsing and command handling. The most important changes are summarized below.

Project-wide rebranding and protocol support:

  • The project is renamed from "nasw" to "pwsw" throughout the codebase, documentation, and configuration. The repository URL, binary name, config directory, and all references are updated accordingly. [1] [2] [3] [4] [5] [6] [7] [8]
  • The tool now supports all Wayland compositors that implement the wlr-foreign-toplevel-management or plasma-window-management protocols, rather than being specific to Niri. The documentation lists supported compositors and explains the use of standard protocols for broader compatibility. [1] [2]

Documentation and configuration updates:

  • The README.md is extensively revised to reflect the new name, supported compositors, updated usage examples, and configuration paths. Instructions and examples now use pwsw instead of nasw, and references to Niri-specific features are replaced with Wayland protocol-based descriptions. [1] [2] [3] [4] [5] [6]

Dependency and build updates:

  • Cargo.toml is updated to add dependencies for Wayland protocol support (wayland-client, wayland-protocols-wlr, wayland-protocols-plasma) and to enable the sync feature for tokio. The project metadata is updated to match the new name and scope.

New and refactored code modules:

  • A new src/cli.rs module defines the command-line interface using clap, including detailed help and argument parsing for all supported commands.
  • A new src/commands.rs module implements the logic for one-shot CLI commands such as --list-sinks, --get-sink, --set-sink, --next-sink, and --prev-sink, with improved output formatting and integration with the updated configuration.Split monolithic main.rs into focused modules to support:
  • Multi-compositor backends (Niri, Sway, Hyprland)
  • Future TUI integration
  • Cleaner separation of concerns

New structure:

  • src/lib.rs: Library crate with module re-exports
  • src/bin/nasw.rs: Binary entry point
  • src/cli.rs: CLI argument definitions
  • src/config.rs: Configuration loading and validation
  • src/pipewire.rs: PipeWire types and interface
  • src/notification.rs: Desktop notifications and icons
  • src/state.rs: Application state and event processing
  • src/commands.rs: One-shot CLI commands
  • src/daemon.rs: Daemon mode event loop
  • src/compositor/: Compositor abstraction layer
    • mod.rs: Compositor trait and WindowEvent enum
    • niri.rs: Niri IPC implementation

This enables adding Sway/Hyprland support by implementing the
Compositor trait, and prepares for a separate TUI binary that
can share the library code.

claude and others added 30 commits December 10, 2025 16:12
Split monolithic main.rs into focused modules to support:
- Multi-compositor backends (Niri, Sway, Hyprland)
- Future TUI integration
- Cleaner separation of concerns

New structure:
- src/lib.rs: Library crate with module re-exports
- src/bin/nasw.rs: Binary entry point
- src/cli.rs: CLI argument definitions
- src/config.rs: Configuration loading and validation
- src/pipewire.rs: PipeWire types and interface
- src/notification.rs: Desktop notifications and icons
- src/state.rs: Application state and event processing
- src/commands.rs: One-shot CLI commands
- src/daemon.rs: Daemon mode event loop
- src/compositor/: Compositor abstraction layer
  - mod.rs: Compositor trait and WindowEvent enum
  - niri.rs: Niri IPC implementation

This enables adding Sway/Hyprland support by implementing the
Compositor trait, and prepares for a separate TUI binary that
can share the library code.
- Restore checkmark (✓) in config validation output
- Use unicode arrow (→) consistently in log messages
  (state.rs, commands.rs, pipewire.rs)
Implement SwayCompositor using i3-ipc protocol:
- Binary protocol: magic + length + type + JSON payload
- Subscribe to window events (new, close, title)
- Handle both native Wayland (app_id) and XWayland (window class)

XWayland handling:
- Native Wayland windows use app_id
- XWayland windows use window_properties.class as app_id equivalent
- Falls back to instance if class unavailable

Architecture:
- Add AnyCompositor enum for runtime dispatch (async traits not dyn-compatible)
- compositor::detect() auto-detects via NIRI_SOCKET or SWAYSOCK env vars
- Update daemon to use auto-detection instead of hardcoded Niri

Supported compositors: Niri, Sway (Hyprland planned)
Replace compositor-specific IPC with Wayland protocols for broader support
Fix channel closure detection, race conditions, and optimize protocol detection
Check if the event channel receiver has been dropped after each dispatch.
This allows the Wayland thread to exit cleanly when the daemon shuts down
via Ctrl+C, rather than blocking indefinitely in the event loop.

Note: The thread will still block until the next Wayland event arrives,
but will then exit gracefully rather than continuing to run.
- Rename binary from nasw to pwsw (src/bin/nasw.rs → src/bin/pwsw.rs)
- Update package name, description, repository URL in Cargo.toml
- Bump version to 0.3.0 for the rename
- Update config directory from ~/.config/nasw to ~/.config/pwsw
- Update CLI name and description
- Update notification app name to PWSW
- Update log filter prefix to pwsw=
- Update all documentation and README references

The name change reflects that the tool now supports multiple Wayland
compositors via standard protocols, not just Niri.
- Created src/ipc.rs with Request/Response types and Unix socket IPC
- Restructured src/cli.rs to use subcommands instead of flags
- Updated src/bin/pwsw.rs to dispatch to subcommands
- Added IPC-based commands to src/commands.rs (status, reload, shutdown, list-windows, test-rule)
- Integrated IPC server into daemon event loop in src/daemon.rs
- Updated State to track app_id and title for IPC queries
- Added tokio time feature for IPC timeouts

Co-authored-by: ledati16 <[email protected]>
- Updated project overview to reflect IPC-based daemon commands
- Documented daemon management section
- Updated running examples with subcommand syntax
- Documented IPC socket location
- Removed references to old flag-based commands

Co-authored-by: ledati16 <[email protected]>
- Use async socket check in cleanup_stale_socket to avoid blocking
- Replace std::process::exit with broadcast channel for graceful shutdown
- Clarify reload message (config validation only, restart needed for full reload)
- Fix duplicate logging initialization issue in bin/pwsw.rs

Co-authored-by: ledati16 <[email protected]>
- Use username-based socket path in /tmp fallback (/tmp/pwsw-$USER.sock)
- Improve socket cleanup error handling with clearer pattern matching
- Remove unused import

Co-authored-by: ledati16 <[email protected]>
- Fix protocol detection to properly use GlobalList's with_list() API
- Add event_created_child! macro for wlr-foreign-toplevel manager
  (required for correct wayland-client event dispatching)
- Add debug logging for detected globals
- Remove unnecessary event handling in registry dispatch

These fixes address runtime issues with compositor protocol detection
introduced in the IPC infrastructure changes.
- Add early daemon detection with clear error messages
- Fix default command: 'pwsw' now shows status instead of starting daemon
- Implement proper foreground/background modes for 'pwsw daemon'
- Improve status command to show helpful startup instructions when daemon not running
- Add CLAUDE.md with project documentation for LLM assistance

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Command Improvements:
- test-rule: Now tests against ALL open windows (not just tracked ones)
- test-rule: Tests both app_id and title fields with match indicators
- list-windows: Shows all windows grouped by tracked vs untracked status
- list-windows: Displays which sink tracked windows are using

CLI Refinements:
- Remove redundant 'reload' command (use 'pwsw shutdown && pwsw daemon')
- Update help text for clarity and consistency
- Clearly indicate which commands require running daemon
- Add helpful first-run message when config is auto-created

State Management:
- Track all open windows efficiently (HashMap scales with open windows)
- Windows automatically removed from tracking on close
- Minimal memory overhead (~50-200 bytes per window)

User Experience:
- First-time users get clear next steps when config is created
- Improved help text with better organization and examples
- Config restart instructions included in help

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…pipeline

- Store compiled regexes as Option<Arc<Regex>> in RuleEditor
- Send cloned Arc caches to background preview worker to avoid recompilation
- Replace render-time Regex usage to prefer cached Arcs
- Update input handlers to eagerly update caches and send previews

Co-Authored-By: Automation <no-reply@autobot>

🤖 Generated with CLAUDE.md-guided assistant
…ded displays

\nSummary:\n- Cache compiled regexes and prefer cached usage for previews and saves\n- Add padded display cache for Sinks and Settings to avoid per-frame formatting\n- Use sink padded-display lookup in Rules list to align sink column\n- Replace hot-path format! allocations with span-based rendering\n- Update TEMP_TUI_REFACTOR.md to record progress and next steps

\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Sonnet 4.5 <[email protected]>
Adds grapheme-aware unit tests for SimpleEditor word navigation and Ctrl+Backspace.
… word-nav

Update TEMP_TUI_REFACTOR.md and add edge-case tests for word navigation.
Add pub(crate) simulate_key_event and integration tests for Ctrl+Word navigation and Ctrl+Backspace; update TEMP_TUI_REFACTOR.md
Allow Up/Down arrows to move between fields in Add/Edit modals; strengthen focused textfield styling; improve sink selector affordance; update help hints
…pacing

Draw thin focus border on focused text fields; use colored spans for checkmarks and notify state; reduce vertical padding in add/edit modals for tighter layout
…n\n- Add left-side focus indicator and tighten field/modal spacing\n- Add focus rectangle and colored indicators for fields and lists\n- Improve modal navigation and keyboard handling across screens\n- Update cached display descriptions and sink selection behavior\n\nSigned-off-by: automated-agent <agent@local>
@ledati16 ledati16 closed this Dec 14, 2025
@ledati16 ledati16 deleted the claude/restructure-modular-codebase-01Uzyx6PGpuKhi7sB5xBALhk branch December 14, 2025 21:12
ledati16 added a commit that referenced this pull request Dec 21, 2025
- Add DEVICE_LOCKS cleanup to prevent memory leak (max 100 devices)
- Change Wayland event channel from unbounded to bounded (capacity: 100)
- Use blocking_send() to apply backpressure when channel is full
- Add 2 tests for device lock cleanup behavior

Fixes two high-priority resource management issues:
- Issue #1: DEVICE_LOCKS unbounded growth from USB device churn
- Issue #3: Unbounded Wayland channel memory growth

Test results: 109 tests passing (was 107, added 2)

See src_plan.md for implementation details and remaining phases.

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants