1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00
Files
DankMaterialShell/CLAUDE.md
2025-07-10 16:40:04 -04:00

10 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Quickshell-based desktop shell implementation with Material Design 3 dark theme. The shell provides a complete desktop environment experience with panels, widgets, and system integration services.

Architecture: Modular design with clean separation between UI components (Widgets), system services (Services), and shared utilities (Common).

Technology Stack

  • QML (Qt Modeling Language) - Primary language for all UI components
  • Quickshell Framework - QML-based framework for building desktop shells
  • Qt/QtQuick - UI rendering and controls
  • Qt5Compat - Graphical effects
  • Wayland - Display server protocol

Development Commands

Since this is a Quickshell-based project without traditional build configuration files, development typically involves:

# Run the shell (requires Quickshell to be installed)
quickshell -p shell.qml

# Or use the shorthand
qs -p .

Architecture Overview

Modular Structure

The shell follows a clean modular architecture reduced from 4,830 lines to ~250 lines in shell.qml:

shell.qml           # Main entry point (minimal orchestration)
├── Common/         # Shared resources
│   ├── Theme.qml   # Material Design 3 theme singleton
│   └── Utilities.js # Shared utility functions
├── Services/       # System integration singletons
│   ├── AudioService.qml
│   ├── NetworkService.qml
│   ├── BrightnessService.qml
│   └── [9 total services]
└── Widgets/        # UI components
    ├── TopBar.qml
    ├── AppLauncher.qml
    ├── ControlCenterPopup.qml
    └── [18 total widgets]

Component Organization

  1. Shell Entry Point (shell.qml)

    • Minimal orchestration layer (~250 lines)
    • Imports and instantiates components
    • Handles global state and property bindings
    • Multi-monitor support using Quickshell's Variants
  2. Common/ - Shared resources

    • Theme.qml - Material Design 3 theme singleton with consistent colors, spacing, fonts
    • Utilities.js - Shared functions for workspace parsing, notifications, menu handling
  3. Services/ - System integration singletons

    • Pattern: All services use Singleton type with id: root
    • Independence: No cross-service dependencies
    • Examples: AudioService, NetworkService, BrightnessService, WeatherService
    • Services handle system commands, state management, and hardware integration
  4. Widgets/ - Reusable UI components

    • Full-screen components: AppLauncher, ClipboardHistory, ControlCenterPopup
    • Panel components: TopBar, SystemTrayWidget, NotificationPopup
    • Reusable controls: CustomSlider, WorkspaceSwitcher
    • Each widget directory contains qmldir for module registration

Key Architectural Patterns

  1. Singleton Services Pattern:

    import QtQuick
    import Quickshell
    import Quickshell.Io
    pragma Singleton
    pragma ComponentBehavior: Bound
    
    Singleton {
        id: root
    
        property type value: defaultValue
    
        function performAction() { /* implementation */ }
    }
    
  2. Module Registration: Each directory contains qmldir file:

    singleton ServiceName 1.0 ServiceName.qml
    ComponentName 1.0 ComponentName.qml
    
  3. Smart Feature Detection: Services detect system capabilities:

    property bool featureAvailable: false
    // Auto-hide UI elements when features unavailable
    visible: ServiceName.featureAvailable
    
  4. Property Bindings: Reactive UI updates through property binding

  5. Material Design Theming: Consistent use of Theme singleton throughout

Important Components

  • ControlCenterPopup: System controls (WiFi, Bluetooth, brightness, volume, night mode)
  • AppLauncher: Full-featured app grid/list with 93+ applications, search, categories
  • ClipboardHistory: Complete clipboard management with cliphist integration
  • TopBar: Per-monitor panels with workspace switching, clock, system tray
  • CustomSlider: Reusable enhanced slider with animations and smart detection

Code Conventions

QML Style Guidelines

  1. Structure and Formatting:

    • Use 4-space indentation
    • id should be the first property
    • Properties before signal handlers before child components
    • Prefer property bindings over imperative code
  2. Naming Conventions:

    • Services: Use Singleton type with id: root
    • Components: Use descriptive names (e.g., CustomSlider, TopBar)
    • Properties: camelCase for properties, PascalCase for types
  3. Component Structure:

    // For regular components
    Item {
        id: root
    
        property type name: value
    
        signal customSignal(type param)
    
        onSignal: { /* handler */ }
    
        Component { /* children */ }
    }
    
    // For services (singletons)
    Singleton {
        id: root
    
        property bool featureAvailable: false
        property type currentValue: defaultValue
    
        function performAction(param) { /* implementation */ }
    }
    

Import Guidelines

  1. Standard Import Order:

    import QtQuick
    import QtQuick.Controls  // If needed
    import Quickshell
    import Quickshell.Widgets
    import Quickshell.Io     // For Process, FileView
    import "../Common"       // For Theme, utilities
    import "../Services"     // For service access
    
  2. Service Dependencies:

    • Services should NOT import other services
    • Widgets can import and use services via property bindings
    • Use Theme.propertyName for consistent styling

Component Development Patterns

  1. Smart Feature Detection:

    // In services - detect capabilities
    property bool brightnessAvailable: false
    
    // In widgets - adapt UI accordingly
    CustomSlider {
        visible: BrightnessService.brightnessAvailable
        enabled: BrightnessService.brightnessAvailable
        value: BrightnessService.brightnessLevel
    }
    
  2. Reusable Components:

    • Create reusable widgets for common patterns (like CustomSlider)
    • Use configurable properties for different use cases
    • Include proper signal handling with unique names (avoid valueChanged)
  3. Service Integration:

    • Services expose properties and functions
    • Widgets bind to service properties for reactive updates
    • Use service functions for actions: ServiceName.performAction(value)

Error Handling and Debugging

  1. Console Logging:

    // Use appropriate log levels
    console.log("Info message")           // General info
    console.warn("Warning message")       // Warnings
    console.error("Error message")        // Errors
    
    // Include context in service operations
    onExited: (exitCode) => {
        if (exitCode !== 0) {
            console.warn("Service failed:", serviceName, "exit code:", exitCode)
        }
    }
    
  2. Graceful Degradation:

    • Always check feature availability before showing UI
    • Provide fallbacks for missing system tools
    • Use visible and enabled properties appropriately

Multi-Monitor Support

The shell uses Quickshell's Variants pattern for multi-monitor support:

  • Each connected monitor gets its own top bar instance
  • Workspace switchers are per-display and Niri-aware
  • Monitors are automatically detected by screen name (DP-1, DP-2, etc.)
  • Workspaces are dynamically synchronized with Niri's per-output workspaces

Common Development Tasks

Testing and Validation

When modifying the shell:

  1. Test changes: qs -p . (automatic reload on file changes)
  2. Performance: Ensure animations remain smooth (60 FPS target)
  3. Theming: Use Theme.propertyName for Material Design 3 consistency
  4. Wayland compatibility: Test on Wayland session
  5. Multi-monitor: Verify behavior with multiple displays
  6. Feature detection: Test on systems with/without required tools

Adding New Widgets

  1. Create component:

    # Create new widget file
    touch Widgets/NewWidget.qml
    
  2. Register in qmldir:

    # Add to Widgets/qmldir
    NewWidget 1.0 NewWidget.qml
    
  3. Follow widget patterns:

    • Use Theme.propertyName for styling
    • Import "../Common" and "../Services" as needed
    • Bind to service properties for reactive updates
    • Consider per-screen vs global behavior
  4. Integration in shell.qml:

    NewWidget {
        id: newWidget
        // Configure properties
    }
    

Adding New Services

  1. Create service:

    // Services/NewService.qml
    import QtQuick
    import Quickshell
    import Quickshell.Io
    pragma Singleton
    pragma ComponentBehavior: Bound
    
    Singleton {
        id: root
    
        property bool featureAvailable: false
        property type currentValue: defaultValue
    
        function performAction(param) {
            // Implementation
        }
    }
    
  2. Register in qmldir:

    # Add to Services/qmldir
    singleton NewService 1.0 NewService.qml
    
  3. Use in widgets:

    // In widget files
    property alias serviceValue: NewService.currentValue
    
    SomeControl {
        visible: NewService.featureAvailable
        enabled: NewService.featureAvailable
        onTriggered: NewService.performAction(value)
    }
    

Debugging Common Issues

  1. Import errors: Check qmldir registration and import paths
  2. Singleton conflicts: Ensure services use Singleton type with id: root
  3. Property binding issues: Use property aliases for reactive updates
  4. Process failures: Check system tool availability and command syntax
  5. Theme inconsistencies: Always use Theme.propertyName instead of hardcoded values

Best Practices Summary

  • Modularity: Keep components focused and independent
  • Reusability: Create reusable components for common patterns
  • Responsiveness: Use property bindings for reactive UI
  • Robustness: Implement feature detection and graceful degradation
  • Consistency: Follow Material Design 3 principles via Theme singleton
  • Performance: Minimize expensive operations and use appropriate data structures