Skip to content

Mac Snap is a powerful and intuitive window management utility for macOS that makes organizing your workspace effortless. With intelligent window snapping, customizable shortcuts, and a clean interface, Mac Snap helps you maximize productivity by keeping your windows perfectly organized.

License

Notifications You must be signed in to change notification settings

nicksoftware/MacSnapper

Repository files navigation

Mac Snap πŸͺŸ

Professional Window Snapping for macOS

Mac Snap Logo

Mac Snap is a powerful and intuitive window management utility for macOS that makes organizing your workspace effortless. With intelligent window snapping, customizable shortcuts, and a clean interface, Mac Snap helps you maximize productivity by keeping your windows perfectly organized.

Swift Platform Architecture License

✨ Features

🎯 Core Functionality

  • Smart Window Snapping: Snap windows to halves, quarters, thirds, and custom positions
  • Drag & Drop Snapping: Intuitive window snapping by dragging to screen edges
  • Multi-Monitor Support: Full support for multiple displays with individual snapping zones
  • Custom Presets: Create and save custom window arrangements

πŸ”§ Customization

  • Global Hotkeys: Customizable keyboard shortcuts for all snapping actions
  • Exclusion Lists: Exclude specific applications from snapping
  • Visual Feedback: Real-time preview of window positions during snapping
  • Menu Bar Integration: Quick access via menu bar icon

πŸ’Ž Professional Design

  • Modern macOS Interface: Native SwiftUI design following Apple's Human Interface Guidelines
  • Professional Logo: Custom-designed gradient app icon with window snapping iconography
  • Clean Architecture: Built with Domain-Driven Design and SOLID principles
  • Performance Optimized: Minimal memory footprint and CPU usage

Core Window Management

  • Precise Window Snapping: Left/Right halves, quarters, thirds, and custom positions
  • Multiple Screen Support: Intelligent screen detection and window positioning
  • Real-time Window Monitoring: Live updates of window state changes
  • Focused Window Control: Quick actions on the currently active window

User Interface

  • Modern SwiftUI Design: Native macOS appearance with dark/light mode support
  • Menu Bar Integration: Quick access to common actions without opening the main app
  • Sidebar Navigation: Searchable window list with detailed information
  • Visual Feedback: Loading states, animations, and clear status indicators

Developer Experience

  • Clean Architecture: Separation of concerns with clear layer boundaries
  • SOLID Principles: Single responsibility, dependency inversion, and open/closed design
  • Comprehensive Testing: Unit test structure with dependency injection support
  • Type Safety: Strong typing throughout with proper error handling

πŸ—οΈ Architecture

Mac Snap follows Clean Architecture principles with clear separation between layers:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    PRESENTATION LAYER                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   MainView      β”‚  β”‚  WindowDetail   β”‚  β”‚  MenuBarView β”‚ β”‚
β”‚  β”‚   (SwiftUI)     β”‚  β”‚     View        β”‚  β”‚   (SwiftUI)  β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   APPLICATION LAYER                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚          WindowManagementUseCase                        β”‚ β”‚
β”‚  β”‚       (Business Logic Orchestration)                    β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚
β”‚  β”‚  ScreenService  β”‚  β”‚   DIContainer   β”‚                   β”‚
β”‚  β”‚                 β”‚  β”‚ (Dependency     β”‚                   β”‚
β”‚  β”‚                 β”‚  β”‚  Injection)     β”‚                   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     DOMAIN LAYER                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   WindowInfo    β”‚  β”‚   SnapAction    β”‚  β”‚  Repository  β”‚ β”‚
β”‚  β”‚   (Entity)      β”‚  β”‚   (Entity)      β”‚  β”‚  Protocols   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 INFRASTRUCTURE LAYER                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚        AccessibilityWindowRepository                    β”‚ β”‚
β”‚  β”‚         (macOS Accessibility APIs)                      β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Layer Responsibilities

🎨 Presentation Layer

  • SwiftUI Views: User interface components
  • View Models: UI state management (using UseCase as ViewModel)
  • User Interactions: Button taps, menu selections, keyboard shortcuts

πŸ”„ Application Layer

  • Use Cases: Business logic orchestration
  • Services: Cross-cutting concerns (screen management, etc.)
  • Dependency Injection: Service registration and resolution

πŸ›οΈ Domain Layer

  • Entities: Core business objects (WindowInfo, SnapAction)
  • Protocols: Contracts for external dependencies
  • Business Rules: Pure business logic without external dependencies

πŸ”§ Infrastructure Layer

  • Repository Implementations: Data access using macOS APIs
  • External Services: Accessibility APIs, system integration
  • Platform-specific Code: macOS-specific implementations

πŸ› οΈ Design Patterns Used

Repository Pattern

protocol WindowRepositoryProtocol {
    func getAllWindows() async throws -> [WindowInfo]
    func setWindowFrame(_ window: WindowInfo, frame: CGRect) async throws
    // ... other methods
}

Dependency Injection

class DIContainer {
    func register<T>(_ type: T.Type, service: T)
    func resolve<T>(_ type: T.Type) throws -> T
}

Observer Pattern

var windowUpdates: AnyPublisher<[WindowInfo], Never>
var focusedWindowUpdates: AnyPublisher<WindowInfo?, Never>

Command Pattern

struct SnapAction {
    let type: SnapType
    let targetFrame: CGRect
    let keyboardShortcut: KeyboardShortcut?
}

Strategy Pattern

enum SnapType {
    case leftHalf, rightHalf, topHalf, bottomHalf
    case topLeftQuarter, topRightQuarter
    // ... different snapping strategies
}

πŸ“ Project Structure

MacSnapper/
β”œβ”€β”€ MacSnapperApp.swift              # App entry point
β”œβ”€β”€ Domain/                          # Business logic layer
β”‚   β”œβ”€β”€ Entities/
β”‚   β”‚   β”œβ”€β”€ WindowInfo.swift         # Core window entity
β”‚   β”‚   └── SnapAction.swift         # Snap action entity
β”‚   └── Protocols/
β”‚       └── WindowRepositoryProtocol.swift # Repository contract
β”œβ”€β”€ Application/                     # Use cases and services
β”‚   β”œβ”€β”€ UseCases/
β”‚   β”‚   └── WindowManagementUseCase.swift # Main business logic
β”‚   └── DependencyInjection/
β”‚       └── DIContainer.swift        # Dependency management
β”œβ”€β”€ Infrastructure/                  # External integrations
β”‚   └── Services/
β”‚       └── AccessibilityWindowRepository.swift # macOS integration
└── Presentation/                    # UI layer
    └── Views/
        β”œβ”€β”€ MainView.swift           # Main application window
        β”œβ”€β”€ WindowDetailView.swift   # Window management interface
        β”œβ”€β”€ MenuBarView.swift        # Menu bar quick actions
        └── SettingsView.swift       # App configuration

πŸš€ Getting Started

Prerequisites

  • macOS 14.0 or later
  • Xcode 16.0 or later
  • Swift 5.9 or later

Installation

  1. Clone the repository
    git clone https://github.com/yourusername/MacSnap.git

cd MacSnap


2. **Open in Xcode**
```bash
open MacSnap.xcodeproj
  1. Build and Run
    • Select the Mac Snap target
    • Press Cmd+R to build and run

First Launch Setup

  1. Grant Accessibility Permissions

    • Mac Snap will prompt for accessibility permissions on first launch
    • Click "Grant Permissions" and follow the system prompts
    • Go to System Settings > Privacy & Security > Accessibility
    • Enable Mac Snap in the list
  2. Start Managing Windows

    • Open some applications to see their windows in the sidebar
    • Select a window to see available snap actions
    • Use the menu bar for quick access to common operations

🎯 Usage

Main Window Interface

  • Window List: Browse all manageable windows with search
  • Detail View: Select a window to see snapping options
  • Quick Actions: Common operations like left/right half, maximize
  • Advanced Options: Thirds, quarters, and custom positioning

Menu Bar Quick Actions

  • Instant Access: Right-click the menu bar icon for quick actions
  • Focused Window: Snap the currently active window without opening the main app
  • Status Indicator: Visual feedback on permission status

Keyboard Shortcuts

  • βŒ₯βŒƒ+←: Snap left half
  • βŒ₯βŒƒ+β†’: Snap right half
  • βŒ₯βŒƒ+↑: Snap top half
  • βŒ₯βŒƒ+↓: Snap bottom half
  • βŒ₯βŒƒ+F: Maximize window
  • βŒ₯βŒƒ+C: Center window

πŸ§ͺ Testing

The architecture supports comprehensive testing through dependency injection:

// Example: Testing the use case with mocked dependencies
func testWindowSnapping() async {
    let mockRepository = MockWindowRepository()
    let mockScreenService = MockScreenService()
    let useCase = WindowManagementUseCase(
        windowRepository: mockRepository,
        screenService: mockScreenService
    )

    // Test business logic in isolation
    await useCase.snapWindow(testWindow, to: .leftHalf)

    XCTAssertTrue(mockRepository.setWindowFrameCalled)
}

πŸ›‘οΈ Error Handling

MacSnapper implements comprehensive error handling:

enum WindowRepositoryError: LocalizedError {
    case accessibilityPermissionsDenied
    case windowNotFound(String)
    case systemError(String)

    var errorDescription: String? { /* ... */ }
    var recoverySuggestion: String? { /* ... */ }
}

πŸ”„ Future Enhancements

Planned Features

  • Customizable keyboard shortcuts
  • Window arrangement presets
  • Multi-monitor advanced positioning
  • Window history and undo functionality
  • Integration with Spaces and Mission Control
  • Scripting API for automation

Architecture Improvements

  • Event Sourcing for window state changes
  • CQRS pattern for complex queries
  • Plugin architecture for custom snap behaviors
  • Performance optimizations for large window counts

🀝 Contributing

We welcome contributions! Please follow these guidelines:

  1. Fork the repository and create a feature branch
  2. Follow the architecture patterns established in the codebase
  3. Write tests for new functionality
  4. Update documentation for any API changes
  5. Submit a pull request with a clear description

Code Style

  • Follow Swift naming conventions
  • Use MARK comments for organization
  • Document public APIs with DocC comments
  • Maintain the layered architecture boundaries

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Inspired by Rectangle and other great window managers
  • Built with Apple's Accessibility APIs
  • Architecture influenced by Clean Architecture principles by Uncle Bob
  • SwiftUI design patterns from Apple's Human Interface Guidelines

Development

🎨 App Icon Generation

The professional app icon is generated from the SVG logo using the included script:

./scripts/create_app_icon.sh

This script:

  • Converts the SVG logo to all required macOS icon sizes (16x16 to 1024x1024)
  • Creates both 1x and 2x (retina) versions
  • Generates the .icns file for the app bundle
  • Updates the Xcode asset catalog with proper file references

MacSnapper - Professional window management for macOS developers and power users.

About

Mac Snap is a powerful and intuitive window management utility for macOS that makes organizing your workspace effortless. With intelligent window snapping, customizable shortcuts, and a clean interface, Mac Snap helps you maximize productivity by keeping your windows perfectly organized.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published