Showing preview only (3,263K chars total). Download the full file or copy to clipboard to get everything.
Repository: rxhanson/Rectangle
Branch: main
Commit: fa2b425bce88
Files: 301
Total size: 3.0 MB
Directory structure:
gitextract_oju34tob/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── funding.yml
│ └── workflows/
│ └── build.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── Rectangle/
│ ├── AccessibilityAuthorization/
│ │ ├── AccessibilityAuthorization.swift
│ │ └── AccessibilityWindowController.swift
│ ├── AccessibilityElement.swift
│ ├── AppDelegate.swift
│ ├── AppIcon.icon/
│ │ └── icon.json
│ ├── ApplicationToggle.swift
│ ├── Assets.xcassets/
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── StatusTemplate.imageset/
│ │ │ └── Contents.json
│ │ ├── WindowPositions/
│ │ │ ├── Contents.json
│ │ │ ├── almostMaximizeTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── blEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomCenterLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomCenterLeftTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomCenterNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomCenterRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomCenterRightTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomCenterSixthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomHalfTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomLeftNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomLeftSixthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomLeftTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomLeftTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomRightNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomRightSixthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomRightTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomRightTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomThirdTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── bottomTwoThirdsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── brEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── cblEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── cbrEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerLeftFourthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerRightFourthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerThirdHorizontalTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerThirdTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerThreeFourthsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── centerTwoThirdsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── ctlEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── ctrEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── firstThirdTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── firstThreeFourthsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── firstTwoThirdsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── halfWidthCenterTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── largerWidthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lastThirdTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lastThreeFourthsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lastTwoThirdsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── leftFourthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── leftHalfTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lowerMiddleCenterLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lowerMiddleCenterRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lowerMiddleLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── lowerMiddleRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── makeLargerTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── makeSmallerTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── maximizeHeightTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── maximizeTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleCenterLeftTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleCenterNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleCenterRightTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleLeftNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleLeftTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleRightNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── middleRightTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── moveDownTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── moveLeftTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── moveRightTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── moveUpTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── nextDisplayTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── prevDisplayTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── restoreTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── rightFourthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── rightHalfTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── smallerWidthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── tlEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topCenterLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topCenterLeftTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topCenterNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topCenterRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topCenterRightTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topCenterSixthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topHalfTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topLeftNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topLeftSixthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topLeftTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topLeftTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topRightNinthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topRightSixthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topRightTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topRightTwelfthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topThirdTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── topTwoThirdsTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── trEighthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── upperMiddleCenterLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── upperMiddleCenterRightSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── upperMiddleLeftSixteenthTemplate.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── upperMiddleRightSixteenthTemplate.imageset/
│ │ │ └── Contents.json
│ │ ├── keyboardToolbarTemplate.imageset/
│ │ │ └── Contents.json
│ │ ├── snapAreaTemplate.imageset/
│ │ │ └── Contents.json
│ │ ├── square.and.arrow.down.imageset/
│ │ │ └── Contents.json
│ │ ├── square.and.arrow.up.imageset/
│ │ │ └── Contents.json
│ │ ├── toolbarSettingsTemplate.imageset/
│ │ │ └── Contents.json
│ │ ├── wallpaperTiger.imageset/
│ │ │ └── Contents.json
│ │ └── wallpaperTigerVertical.imageset/
│ │ └── Contents.json
│ ├── Base.lproj/
│ │ └── Main.storyboard
│ ├── CycleSize.swift
│ ├── Defaults.swift
│ ├── Info.plist
│ ├── InternetAccessPolicy.plist
│ ├── LaunchOnLogin.swift
│ ├── Logging/
│ │ ├── LogViewer.storyboard
│ │ └── LogViewer.swift
│ ├── MultiWindow/
│ │ ├── MultiWindowManager.swift
│ │ └── ReverseAllManager.swift
│ ├── Popover/
│ │ ├── MessageView.swift
│ │ └── MessageView.xib
│ ├── PrefsWindow/
│ │ ├── Config.swift
│ │ ├── PrefsViewController.swift
│ │ ├── SettingsViewController.swift
│ │ └── SnapAreaViewController.swift
│ ├── Rectangle-Bridging-Header.h
│ ├── Rectangle.entitlements
│ ├── RectangleRelease.entitlements
│ ├── RectangleStatusItem.swift
│ ├── ScreenDetection.swift
│ ├── ShortcutManager.swift
│ ├── Snapping/
│ │ ├── CompoundSnapArea/
│ │ │ ├── CompoundSnapArea.swift
│ │ │ ├── EighthsCompoundCalculation.swift
│ │ │ ├── FourthsCompoundCalculation.swift
│ │ │ ├── HalvesCompoundCalculation.swift
│ │ │ ├── SixthsCompoundCalculation.swift
│ │ │ └── ThirdsCompoundCalculation.swift
│ │ ├── FootprintWindow.swift
│ │ ├── SnapAreaModel.swift
│ │ └── SnappingManager.swift
│ ├── SubsequentExecutionMode.swift
│ ├── TitleBarManager.swift
│ ├── TodoMode/
│ │ └── TodoManager.swift
│ ├── Utilities/
│ │ ├── AXExtension.swift
│ │ ├── AlertUtil.swift
│ │ ├── CFExtension.swift
│ │ ├── CGExtension.swift
│ │ ├── CUtil.swift
│ │ ├── Debounce.swift
│ │ ├── DispatchTimeExtension.swift
│ │ ├── EventMonitor.swift
│ │ ├── MASShortcutMigration.swift
│ │ ├── MacTilingDefaults.swift
│ │ ├── NSImageExtension.swift
│ │ ├── NotificationExtension.swift
│ │ ├── RunLoopThread.swift
│ │ ├── SequenceExtension.swift
│ │ ├── StageUtil.swift
│ │ ├── StringExtension.swift
│ │ ├── TimeoutCache.swift
│ │ └── WindowUtil.swift
│ ├── WelcomeWindow/
│ │ └── WelcomeViewController.swift
│ ├── WindowAction.swift
│ ├── WindowActionCategory.swift
│ ├── WindowCalculation/
│ │ ├── AlmostMaximizeCalculation.swift
│ │ ├── BottomCenterLeftEighthCalculation.swift
│ │ ├── BottomCenterLeftSixteenthCalculation.swift
│ │ ├── BottomCenterLeftTwelfthCalculation.swift
│ │ ├── BottomCenterNinthCalculation.swift
│ │ ├── BottomCenterRightEighthCalculation.swift
│ │ ├── BottomCenterRightSixteenthCalculation.swift
│ │ ├── BottomCenterRightTwelfthCalculation.swift
│ │ ├── BottomCenterSixthCalculation.swift
│ │ ├── BottomHalfCalculation.swift
│ │ ├── BottomLeftEighthCalculation.swift
│ │ ├── BottomLeftNinthCalculation.swift
│ │ ├── BottomLeftSixteenthCalculation.swift
│ │ ├── BottomLeftSixthCalculation.swift
│ │ ├── BottomLeftThirdCalculation.swift
│ │ ├── BottomLeftTwelfthCalculation.swift
│ │ ├── BottomRightEighthCalculation.swift
│ │ ├── BottomRightNinthCalculation.swift
│ │ ├── BottomRightSixteenthCalculation.swift
│ │ ├── BottomRightSixthCalculation.swift
│ │ ├── BottomRightThirdCalculation.swift
│ │ ├── BottomRightTwelfthCalculation.swift
│ │ ├── BottomVerticalThirdCalculation.swift
│ │ ├── BottomVerticalTwoThirdsCalculation.swift
│ │ ├── CenterCalculation.swift
│ │ ├── CenterHalfCalculation.swift
│ │ ├── CenterProminentlyCalculation.swift
│ │ ├── CenterThirdCalculation.swift
│ │ ├── CenterThreeFourthsCalculation.swift
│ │ ├── CenterTwoThirdsCalculation.swift
│ │ ├── ChangeSizeCalculation.swift
│ │ ├── ChangeWindowDimensionCalculation.swift
│ │ ├── EighthsRepeated.swift
│ │ ├── FirstFourthCalculation.swift
│ │ ├── FirstThirdCalculation.swift
│ │ ├── FirstThreeFourthsCalculation.swift
│ │ ├── FirstTwoThirdsCalculation.swift
│ │ ├── GapCalculation.swift
│ │ ├── HalfOrDoubleDimensionCalculation.swift
│ │ ├── HorizontalThirdsRepeated.swift
│ │ ├── LastFourthCalculation.swift
│ │ ├── LastThirdCalculation.swift
│ │ ├── LastThreeFourthsCalculation.swift
│ │ ├── LastTwoThirdsCalculation.swift
│ │ ├── LeftRightHalfCalculation.swift
│ │ ├── LeftTodoCalculation.swift
│ │ ├── LowerLeftCalculation.swift
│ │ ├── LowerMiddleCenterLeftSixteenthCalculation.swift
│ │ ├── LowerMiddleCenterRightSixteenthCalculation.swift
│ │ ├── LowerMiddleLeftSixteenthCalculation.swift
│ │ ├── LowerMiddleRightSixteenthCalculation.swift
│ │ ├── LowerRightCalculation.swift
│ │ ├── MaximizeCalculation.swift
│ │ ├── MaximizeHeightCalculation.swift
│ │ ├── MiddleCenterLeftTwelfthCalculation.swift
│ │ ├── MiddleCenterNinthCalculation.swift
│ │ ├── MiddleCenterRightTwelfthCalculation.swift
│ │ ├── MiddleLeftNinthCalculation.swift
│ │ ├── MiddleLeftTwelfthCalculation.swift
│ │ ├── MiddleRightNinthCalculation.swift
│ │ ├── MiddleRightTwelfthCalculation.swift
│ │ ├── MiddleVerticalThirdCalculation.swift
│ │ ├── MoveLeftRightCalculation.swift
│ │ ├── MoveUpDownCalculation.swift
│ │ ├── NextPrevDisplayCalculation.swift
│ │ ├── NinthsRepeated.swift
│ │ ├── OrientationAware.swift
│ │ ├── QuartersRepeated.swift
│ │ ├── RepeatedExecutionsCalculation.swift
│ │ ├── RepeatedExecutionsInThirdsCalculation.swift
│ │ ├── RightTodoCalculation.swift
│ │ ├── SecondFourthCalculation.swift
│ │ ├── SixteenthsRepeated.swift
│ │ ├── SixthsRepeated.swift
│ │ ├── SpecifiedCalculation.swift
│ │ ├── ThirdFourthCalculation.swift
│ │ ├── TopCenterLeftEighthCalculation.swift
│ │ ├── TopCenterLeftSixteenthCalculation.swift
│ │ ├── TopCenterLeftTwelfthCalculation.swift
│ │ ├── TopCenterNinthCalculation.swift
│ │ ├── TopCenterRightEighthCalculation.swift
│ │ ├── TopCenterRightSixteenthCalculation.swift
│ │ ├── TopCenterRightTwelfthCalculation.swift
│ │ ├── TopCenterSixthCalculation.swift
│ │ ├── TopHalfCalculation.swift
│ │ ├── TopLeftEighthCalculation.swift
│ │ ├── TopLeftNinthCalculation.swift
│ │ ├── TopLeftSixteenthCalculation.swift
│ │ ├── TopLeftSixthCalculation.swift
│ │ ├── TopLeftThirdCalculation.swift
│ │ ├── TopLeftTwelfthCalculation.swift
│ │ ├── TopRightEighthCalculation.swift
│ │ ├── TopRightNinthCalculation.swift
│ │ ├── TopRightSixteenthCalculation.swift
│ │ ├── TopRightSixthCalculation.swift
│ │ ├── TopRightThirdCalculation.swift
│ │ ├── TopRightTwelfthCalculation.swift
│ │ ├── TopVerticalThirdCalculation.swift
│ │ ├── TopVerticalTwoThirdsCalculation.swift
│ │ ├── TwelfthsRepeated.swift
│ │ ├── UpperLeftCalculation.swift
│ │ ├── UpperMiddleCenterLeftSixteenthCalculation.swift
│ │ ├── UpperMiddleCenterRightSixteenthCalculation.swift
│ │ ├── UpperMiddleLeftSixteenthCalculation.swift
│ │ ├── UpperMiddleRightSixteenthCalculation.swift
│ │ ├── UpperRightCalculation.swift
│ │ └── WindowCalculation.swift
│ ├── WindowHistory.swift
│ ├── WindowManager.swift
│ ├── WindowMover/
│ │ ├── BestEffortWindowMover.swift
│ │ ├── CenteringFixedSizedWindowMover.swift
│ │ ├── QuantizedWindowMover.swift
│ │ ├── StandardWindowMover.swift
│ │ └── WindowMover.swift
│ └── mul.lproj/
│ └── Main.xcstrings
├── Rectangle.xcodeproj/
│ └── project.pbxproj
├── RectangleLauncher/
│ ├── AppDelegate.swift
│ ├── Assets.xcassets/
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj/
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── RectangleLauncher.entitlements
│ ├── RectangleLauncherRelease.entitlements
│ └── mul.lproj/
│ └── Main.xcstrings
├── RectangleTests/
│ ├── Info.plist
│ └── RectangleTests.swift
└── TerminalCommands.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
assignees: ''
---
- [ ] This is a new bug that hasn't been documented in a closed issue or in the Readme.
macOS version:
Rectangle version:
Logs if applicable (In Rectangle menu, hold option, "View Logging..."):
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature idea
about: Please use the Discussions tab to share a feature idea ⬆️
title: ''
labels: 'enhancement'
assignees: ''
contact_links:
- name: Rectangle Discussions
url: https://github.com/rxhanson/Rectangle/discussions
about: Please discuss feature ideas here.
---
Feature ideas are now kept in the [discussions tab](https://github.com/rxhanson/Rectangle/discussions). Please create an issue there, not here.
================================================
FILE: .github/funding.yml
================================================
github: rxhanson
custom: https://rectangleapp.com
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on: [push, pull_request]
permissions: read-all
env:
XCODE_PROJECT: "Rectangle.xcodeproj"
XCODE_SCHEME: "Rectangle"
CODE_SIGN_IDENTITY: "-"
BUILD_DIR: "build"
XCODE_ARCHIVE: "Rectangle.xcarchive"
APP_NAME: "Rectangle.app"
EXPORT_OPTIONS_PLIST: "exportOptions.plist"
DMG_NAME: "Rectangle"
DMG_FILE_NAME: "Rectangle.dmg"
jobs:
build:
runs-on: macos-26
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
run: xcodebuild -project "$XCODE_PROJECT" -scheme "$XCODE_SCHEME" archive CODE_SIGN_IDENTITY="$CODE_SIGN_IDENTITY" -archivePath "$BUILD_DIR/$XCODE_ARCHIVE"
- name: Export
run: |
plutil -convert xml1 - -o "$EXPORT_OPTIONS_PLIST" << EOF
{
"destination": "export",
"method": "mac-application"
}
EOF
xcodebuild -exportArchive -archivePath "$BUILD_DIR/$XCODE_ARCHIVE" -exportPath "$BUILD_DIR" -exportOptionsPlist "$EXPORT_OPTIONS_PLIST"
- name: Resign App
run: codesign --force --deep -s "$CODE_SIGN_IDENTITY" "$BUILD_DIR/$APP_NAME"
- name: Make DMG
run: hdiutil create -srcdir "$BUILD_DIR" -volname "$DMG_NAME" "$DMG_FILE_NAME"
- name: Upload
uses: actions/upload-artifact@v4
with:
name: Build
path: ${{ env.DMG_FILE_NAME }}
================================================
FILE: .gitignore
================================================
.idea
**/.DS_Store
*/xcuserdata/
xcuserdata/
**.xcuserstate
*.xcworkspace
Pods
## Xcode per-user config
*.mode1
*.mode1v3
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser
## Xcode Patch
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcworkspace/contents.xcworkspacedata
/*.gcno
## Build products
build/
*.o
*.LinkFileList
*.hmap
## Automatic backup files
*~.nib/
*.swp
*~
*.dat
*.dep
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ryan@ryanhanson.dev. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
## Feature Requests
Rectangle is not accepting any new feature requests at this time, sorry. You can file a feature request for a feature that you plan to implement and submit a pull request for, so that the feature can be reviewed and you will know ahead of time if the feature will be rejected.
## Bugs
Please search through the existing issues, open and closed, before filing a new bug.
Add the version of Rectangle, the version of the OS, and screenshots or videos as necessary.
## Coding Style
Please match the existing coding style as much as possible.
## License
By contributing to Rectangle you agree that your contributions will be licensed under its MIT license.
## Incentives
Logic from Rectangle is used in the [Multitouch](https://multitouch.app) app. The [Rectangle Pro](https://rectangleapp.com/pro) app is entirely built on top of Rectangle. If you contribute significant code or localizations that get merged into Rectangle, you get a free license of Multitouch or Rectangle Pro. Contributors to Sparkle, MASShortcut, or Spectacle can also receive free Multitouch or Rectangle Pro licenses (just send me a direct message on [Gitter](https://gitter.im)).
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019-2025 Ryan Hanson
Based on the Spectacle app, Copyright (c) 2017 Eric Czarny eczarny@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Rectangle
[](https://github.com/rxhanson/Rectangle/actions/workflows/build.yml)
Rectangle is a window management app based on Spectacle, written in Swift.
<img width="962" height="886" alt="image" src="https://github.com/user-attachments/assets/e8d88e5f-7d4f-43bc-a82e-146c42f92d68" />
## System Requirements
Rectangle supports macOS v10.15+. The last version that is supported for macOS 10.13 and 10.14 is https://github.com/rxhanson/Rectangle/releases/tag/v0.73.
## Installation
You can download the latest dmg from <https://rectangleapp.com> or the [Releases page](https://github.com/rxhanson/Rectangle/releases).
Or install with brew cask:
```bash
brew install --cask rectangle
```
## How to use it
The [keyboard shortcuts](https://support.apple.com/guide/mac-help/what-are-those-symbols-shown-in-menus-cpmh0011/mac) are self explanatory, but the snap areas can use some explanation if you've never used them on Windows or other window management apps.
Drag a window to the edge of the screen. When the mouse cursor reaches the edge of the screen, you'll see a footprint that Rectangle will attempt to resize and move the window to when the click is released.
| Snap Area | Resulting Action |
|--------------------------------------------------------|----------------------------------------|
| Left or right edge | Left or right half |
| Top | Maximize |
| Corners | Quarter in respective corner |
| Left or right edge, just above or below a corner | Top or bottom half |
| Bottom left, center, or right third | Respective third |
| Bottom left or right third, then drag to bottom center | First or last two thirds, respectively |
### Ignore an app
Ignoring an app means that when the app is frontmost, keyboard shortcuts are un-registered from macOS. When the app is no longer frontmost, keyboard shortcuts are re-registered with macOS. This is useful for apps that have the same shortcuts like Rectangle and you do not want to change them.
1. Focus the app that you want to ignore (make a window from that app frontmost).
1. Open the Rectangle menu and select "Ignore app"
To un-ignore an app that you have selected to ignore, simply bring that app frontmost again, open the Rectangle menu, and deselect "Ignore".
## Execute an action by URL
Open the URL `rectangle://execute-action?name=[name]`. Do not activate Rectangle if possible.
Available values for `[name]`: `left-half`, `right-half`, `center-half`, `top-half`, `bottom-half`, `top-left`, `top-right`, `bottom-left`, `bottom-right`, `first-third`, `center-third`, `last-third`, `first-two-thirds`, `last-two-thirds`, `maximize`, `almost-maximize`, `maximize-height`, `smaller`, `larger`, `center`, `center-prominently`, `restore`, `next-display`, `previous-display`, `move-left`, `move-right`, `move-up`, `move-down`, `first-fourth`, `second-fourth`, `third-fourth`, `last-fourth`, `first-three-fourths`, `last-three-fourths`, `top-left-sixth`, `top-center-sixth`, `top-right-sixth`, `bottom-left-sixth`, `bottom-center-sixth`, `bottom-right-sixth`, `specified`, `reverse-all`, `top-left-ninth`, `top-center-ninth`, `top-right-ninth`, `middle-left-ninth`, `middle-center-ninth`, `middle-right-ninth`, `bottom-left-ninth`, `bottom-center-ninth`, `bottom-right-ninth`, `top-left-third`, `top-right-third`, `bottom-left-third`, `bottom-right-third`, `top-left-eighth`, `top-center-left-eighth`, `top-center-right-eighth`, `top-right-eighth`, `bottom-left-eighth`, `bottom-center-left-eighth`, `bottom-center-right-eighth`, `bottom-right-eighth`, `tile-all`, `cascade-all`, `cascade-active-app`
Example, from a shell: `open -g "rectangle://execute-action?name=left-half"`
URLs can also be used to ignore/unignore apps.
```
rectangle://execute-task?name=ignore-app
rectangle://execute-task?name=unignore-app
```
A bundle identifier can also be specified, for example:
```
rectangle://execute-task?name=ignore-app&app-bundle-id=com.apple.Safari
```
## Terminal Commands for Hidden Preferences
See [TerminalCommands.md](TerminalCommands.md)
## Differences with Spectacle
* Rectangle uses [MASShortcut](https://github.com/rxhanson/MASShortcut) for keyboard shortcut recording. Spectacle used its own shortcut recorder.
* Rectangle has additional window actions: move windows to each edge without resizing, maximize only the height of a window, almost maximizing a window.
* Next/prev screen thirds is replaced with explicitly first third, first two thirds, center third, last two thirds, and last third. Screen orientation is taken into account, as in first third will be left third on landscape and top third on portrait.
* You can however emulate Spectacle's third cycling using first and last third actions. So, if you repeatedly execute first third, it will cycle through thirds (first, center, last) and vice-versa with the last third.
* There's an option to have windows traverse across displays on subsequent left or right executions.
* Windows will snap when dragged to edges/corners of the screen. This can be disabled.
## Common Known Issues
### Rectangle doesn't have the ability to move to other desktops/spaces
Apple never released a public API for doing this. Rectangle Pro has next/prev Space actions, but there are no plans to add those into Rectangle at this time.
### Window resizing is off slightly for iTerm2
By default iTerm2 will only resize in increments of character widths. There might be a setting inside iTerm2 to disable this, but you can change it with the following command.
```bash
defaults write com.googlecode.iterm2 DisableWindowSizeSnap -integer 1
```
### Rectangle appears to cause Notification Center to freeze
This appears to affect only a small amount of users. To prevent this from happening, uncheck the box for "Snap windows by dragging".
See issue [317](https://github.com/rxhanson/Rectangle/issues/317).
### Troubleshooting
If windows aren't resizing or moving as you expect, here's some initial steps to get to the bottom of it. Most issues of this type have been caused by other apps.
**Quick fixes (try these first):**
1. **Lock and unlock your Mac** – This simple step resolves many issues, especially after system updates.
1. Make sure macOS is up to date.
1. Restart your Mac (this often fixes things right after a macOS update).
**Diagnose the issue:**
4. **Enable debug logging** (see instructions in the following section) – This helps identify whether Rectangle is working correctly.
1. The logs are straightforward. If your calculated rect and your resulting rect are identical, chances are that there is another application causing issues.
**Check for conflicts:**
6. Make sure there are no other window manager applications running.
1. Make sure that the app whose windows are not behaving properly does not have any conflicting keyboard shortcuts.
1. Try using the menu items to execute a window action or changing the keyboard shortcut to something different so we can tell if it's a keyboard shortcut issue or not.
**Advanced troubleshooting:**
9. If you suspect there may be another application causing issues, try creating and logging in as a new macOS user.
1. Save your logs to attach to an issue if you need to create one.
#### Try resetting the macOS accessibility permissions for Rectangle:
```bash
tccutil reset All com.knollsoft.Rectangle
```
Or, this can be done with the following steps instead of the tccutil terminal command.
1. Close Rectangle if it's running
2. In System Settings -> Privacy & Security -> Accessibility, first disable Rectangle, then remove it with the minus button. (it's important to do both of those steps in that order)
3. Restart your mac.
4. Launch Rectangle and enable settings for it as prompted.
## View Debug Logging
1. Hold down the alt (option) key with the Rectangle menu open.
1. Select the "View Logging..." menu item, which is in place of the "About" menu item.
1. Logging will appear in the window as you perform Rectangle commands.
## Import & export JSON config
There are buttons for importing and exporting the config as a JSON file in the settings tab of the preferences window.
Upon launch, Rectangle will load a config file at `~/Library/Application Support/Rectangle/RectangleConfig.json` if it is present and will rename that file with a time/date stamp so that it isn't read on subsequent launches.
## Preferences Storage
The configuration for Rectangle is stored using NSUserDefaults, meaning it is stored in the following location:
`~/Library/Preferences/com.knollsoft.Rectangle.plist`
Note that shortcuts in v0.41+ are stored in a different format and will not load in prior versions.
That file can be backed up or transferred to other machines.
If you are using Rectangle v0.44+, you can also use the import/export button in the Preferences pane to share to your preferences and keyboard shortcuts across machines using a JSON file.
> [!NOTE]
> If you are having issues with configuration options persisting after an application restart and you've installed using Homebrew, you will need to uninstall and reinstall with the `--zap` flag.
```
brew uninstall --zap rectangle
brew install rectangle
```
## Uninstallation
Rectangle can be uninstalled by quitting the app and moving it to the trash. You can remove the Rectangle defaults from your machine with the following terminal command:
```bash
defaults delete com.knollsoft.Rectangle
```
> [!TIP]
> If you are uninstalling after installing with Homebrew, you should include the `--zap` flag to ensure it removes the plist entries too.
```
brew uninstall --zap rectangle
```
---
## Contributing
Logic from Rectangle is used in the [Multitouch](https://multitouch.app) app. The [Rectangle Pro](https://rectangleapp.com/pro) app is entirely built on top of Rectangle. If you contribute significant code or localizations that get merged into Rectangle, send me an email for a free license of Multitouch or Rectangle Pro. Contributors to Sparkle, MASShortcut, or Spectacle can also receive free Multitouch or Rectangle Pro licenses.
### Contributing additional sizes and positions
Rectangle's UI is intentionally simple. If you want to add a size and position that's not in the Shortcuts tab, then you can now add them into the "Extra Shortcuts" section accessed via the ellipsis button at the bottom of the General tab.
### Localization
If you would like to contribute to localization, all of the translations are held in the Main.strings.
Pull requests for new localizations or improvements on existing localizations are welcome.
### Running the app in Xcode (for developers)
Rectangle uses [Swift Package Manager](https://www.swift.org/package-manager/) to install Sparkle and MASShortcut.
The original repository for MASShortcut was archived, so Rectangle uses my [fork](https://github.com/rxhanson/MASShortcut). If you want to make any changes that involve MASShortcut, please make a pull request on my fork.
Due to the addition of the Liquid Glass icon with a fallback for older versions of macOS, there will be a build failure on macOS versions < 26. You can delete the "Asset Catalog Other Flags" to build locally on versions < 26 (but don't check that change in if you create a pull request).
## Credits
As mentioned above, Rectangle uses a forked version of [MASShortcut](https://github.com/rxhanson/MASShortcut), which still works great, and it uses [Sparkle](https://sparkle-project.org) for updates.
The Big Sur variant of the Rectangle app icon was created by Giovanni Maria Cusaro (@gmcusaro). The Liquid Glass variant of the app icon was created by [Alexander Käßner](https://www.alexkaessner.de) (@alexkaessner).
And of course, there's been a lot of community contributions over the years :)
================================================
FILE: Rectangle/AccessibilityAuthorization/AccessibilityAuthorization.swift
================================================
//
// AccessibilityAuthorization.swift
// Rectangle
//
// Created by Ryan Hanson on 6/11/19.
// Copyright © 2019 Ryan Hanson. All rights reserved.
//
import Foundation
import Cocoa
class AccessibilityAuthorization {
private var accessibilityWindowController: NSWindowController?
public func checkAccessibility(completion: @escaping () -> Void) -> Bool {
if !AXIsProcessTrusted() {
accessibilityWindowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "AccessibilityWindowController") as? NSWindowController
NSApp.activate(ignoringOtherApps: true)
accessibilityWindowController?.showWindow(self)
pollAccessibility(completion: completion)
return false
} else {
return true
}
}
private func pollAccessibility(completion: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
if AXIsProcessTrusted() {
self.accessibilityWindowController?.close()
self.accessibilityWindowController = nil
completion()
} else {
self.pollAccessibility(completion: completion)
}
}
}
func showAuthorizationWindow() {
if accessibilityWindowController?.window?.isMiniaturized == true {
accessibilityWindowController?.window?.deminiaturize(self)
}
NSApp.activate(ignoringOtherApps: true)
}
}
================================================
FILE: Rectangle/AccessibilityAuthorization/AccessibilityWindowController.swift
================================================
//
// AccessibilityWindow.swift
// Rectangle
//
// Created by Ryan Hanson on 6/13/19.
// Copyright © 2019 Ryan Hanson. All rights reserved.
//
import Cocoa
class AccessibilityWindowController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
let closeButton = self.window?.standardWindowButton(.closeButton)
closeButton?.target = self
closeButton?.action = #selector(quit)
}
@objc func quit() {
exit(1)
}
}
class AccessibilityViewController: NSViewController {
@IBOutlet weak var sysPrefsPathField: NSTextField!
@IBOutlet weak var openSysPrefsButton: NSButton!
@IBOutlet weak var padlockField: NSTextField!
override func viewDidLoad() {
if #available(OSX 13, *) {
sysPrefsPathField.stringValue = NSLocalizedString(
"Go to System Settings → Privacy & Security → Accessibility", tableName: "Main", value: "", comment: "")
openSysPrefsButton.title = NSLocalizedString(
"Open System Settings", tableName: "Main", value: "", comment: "")
padlockField.isHidden = true
}
}
@IBAction func openSystemPrefs(_ sender: Any) {
NSWorkspace.shared.open(URL(string:"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!)
}
}
================================================
FILE: Rectangle/AccessibilityElement.swift
================================================
//
// AccessibilityElement.swift
// Rectangle, Ported from Spectacle, Combined with snippets from ModMove
//
// Created by Ryan Hanson on 6/12/19.
// Copyright © 2019 Ryan Hanson. All rights reserved.
//
import Foundation
class AccessibilityElement {
fileprivate let wrappedElement: AXUIElement
init(_ element: AXUIElement) {
wrappedElement = element
}
convenience init(_ pid: pid_t) {
self.init(AXUIElementCreateApplication(pid))
}
convenience init?(_ bundleIdentifier: String) {
guard let app = (NSWorkspace.shared.runningApplications.first { $0.bundleIdentifier == bundleIdentifier }) else { return nil }
self.init(app.processIdentifier)
}
convenience init?(_ position: CGPoint) {
guard let element = AXUIElement.systemWide.getElementAtPosition(position) else { return nil }
self.init(element)
}
private func getElementValue(_ attribute: NSAccessibility.Attribute) -> AccessibilityElement? {
guard let value = wrappedElement.getValue(attribute), CFGetTypeID(value) == AXUIElementGetTypeID() else { return nil }
return AccessibilityElement(value as! AXUIElement)
}
private func getElementsValue(_ attribute: NSAccessibility.Attribute) -> [AccessibilityElement]? {
guard let value = wrappedElement.getValue(attribute), let array = value as? [AXUIElement] else { return nil }
return array.map { AccessibilityElement($0) }
}
private var role: NSAccessibility.Role? {
guard let value = wrappedElement.getValue(.role) as? String else { return nil }
return NSAccessibility.Role(rawValue: value)
}
private var isApplication: Bool? {
guard let role = role else { return nil }
return role == .application
}
var isWindow: Bool? {
guard let role = role else { return nil }
return role == .window
}
var isSheet: Bool? {
guard let role = role else { return nil }
return role == .sheet
}
var isToolbar: Bool? {
guard let role = role else { return nil }
return role == .toolbar
}
var isGroup: Bool? {
guard let role = role else { return nil }
return role == .group
}
var isTabGroup: Bool? {
guard let role = role else { return nil }
return role == .tabGroup
}
var isStaticText: Bool? {
guard let role = role else { return nil }
return role == .staticText
}
private var subrole: NSAccessibility.Subrole? {
guard let value = wrappedElement.getValue(.subrole) as? String else { return nil }
return NSAccessibility.Subrole(rawValue: value)
}
var isSystemDialog: Bool? {
guard let subrole = subrole else { return nil }
return subrole == .systemDialog
}
private var position: CGPoint? {
get {
wrappedElement.getWrappedValue(.position)
}
set {
guard let newValue = newValue else { return }
wrappedElement.setValue(.position, newValue)
Logger.log("AX position proposed: \(newValue.debugDescription), result: \(position?.debugDescription ?? "N/A")")
}
}
func isResizable() -> Bool {
if let isResizable = wrappedElement.isValueSettable(.size) {
return isResizable
}
Logger.log("Unable to determine if window is resizeable. Assuming it is.")
return true
}
var size: CGSize? {
get {
wrappedElement.getWrappedValue(.size)
}
set {
guard let newValue = newValue else { return }
wrappedElement.setValue(.size, newValue)
Logger.log("AX sizing proposed: \(newValue.debugDescription), result: \(size?.debugDescription ?? "N/A")")
}
}
var frame: CGRect {
guard let position = position, let size = size else { return .null }
return .init(origin: position, size: size)
}
/// The Accessebility API only allows size & position adjustments individually.
/// To handle moving to different displays, we have to adjust the size then the position, then the size again since macOS will enforce sizes that fit on the current display.
/// When windows take a long time to adjust size & position, there is some visual stutter with doing each of these actions. The stutter can be slightly reduced by removing the initial size adjustment, which can make unsnap restore appear smoother.
func setFrame(_ frame: CGRect, adjustSizeFirst: Bool = true) {
let appElement = applicationElement
var enhancedUI: Bool? = nil
if let appElement = appElement {
enhancedUI = appElement.enhancedUserInterface
if enhancedUI == true {
Logger.log("AXEnhancedUserInterface was enabled, will disable before resizing")
appElement.enhancedUserInterface = false
}
}
if adjustSizeFirst {
size = frame.size
}
position = frame.origin
size = frame.size
// If "enhanced user interface" was originally enabled for the app, turn it back on
if Defaults.enhancedUI.value == .disableEnable, let appElement = appElement, enhancedUI == true {
appElement.enhancedUserInterface = true
}
}
private var childElements: [AccessibilityElement]? {
getElementsValue(.children)
}
func getChildElement(_ role: NSAccessibility.Role) -> AccessibilityElement? {
return childElements?.first { $0.role == role }
}
func getChildElements(_ role: NSAccessibility.Role) -> [AccessibilityElement]? {
guard let elements = (childElements?.filter { $0.role == role }), elements.count > 0 else {
return nil
}
return elements
}
func getChildElement(_ subrole: NSAccessibility.Subrole) -> AccessibilityElement? {
return childElements?.first { $0.subrole == subrole }
}
func getChildElements(_ subrole: NSAccessibility.Subrole) -> [AccessibilityElement]? {
guard let elements = (childElements?.filter { $0.subrole == subrole }), elements.count > 0 else {
return nil
}
return elements
}
func getSelfOrChildElementRecursively(_ position: CGPoint) -> AccessibilityElement? {
func getChildElement() -> AccessibilityElement? {
return element.childElements?
.map { (element: $0, frame: $0.frame) }
.filter { $0.frame.contains(position) }
.min { $0.frame.width * $0.frame.height < $1.frame.width * $1.frame.height }?
.element
}
var element = self
var elements = Set<AccessibilityElement>()
while let childElement = getChildElement(), elements.insert(childElement).inserted {
element = childElement
}
return element
}
var windowId: CGWindowID? {
wrappedElement.getWindowId()
}
func getWindowId() -> CGWindowID? {
if let windowId = windowId {
return windowId
}
let frame = frame
// Take the first match because there's no real way to guarantee which window we're actually getting
if let pid = pid, let info = (WindowUtil.getWindowList().first { $0.pid == pid && $0.frame == frame }) {
return info.id
}
Logger.log("Unable to obtain window id")
return nil
}
var pid: pid_t? {
wrappedElement.getPid()
}
var windowElement: AccessibilityElement? {
if isWindow == true { return self }
return getElementValue(.window)
}
private var isMainWindow: Bool? {
get {
windowElement?.wrappedElement.getValue(.main) as? Bool
}
set {
guard let newValue = newValue else { return }
windowElement?.wrappedElement.setValue(.main, newValue)
}
}
var isMinimized: Bool? {
windowElement?.wrappedElement.getValue(.minimized) as? Bool
}
var isFullScreen: Bool? {
guard let subrole = windowElement?.getElementValue(.fullScreenButton)?.subrole else { return nil }
return subrole == .zoomButton
}
var titleBarFrame: CGRect? {
guard
let windowElement,
case let windowFrame = windowElement.frame,
windowFrame != .null,
let closeButtonFrame = windowElement.getChildElement(.closeButton)?.frame,
closeButtonFrame != .null
else {
return nil
}
let gap = closeButtonFrame.minY - windowFrame.minY
let height = 2 * gap + closeButtonFrame.height
return CGRect(origin: windowFrame.origin, size: CGSize(width: windowFrame.width, height: height))
}
private var applicationElement: AccessibilityElement? {
if isApplication == true { return self }
guard let pid = pid else { return nil }
return AccessibilityElement(pid)
}
private var focusedWindowElement: AccessibilityElement? {
applicationElement?.getElementValue(.focusedWindow)
}
var windowElements: [AccessibilityElement]? {
applicationElement?.getElementsValue(.windows)
}
var isHidden: Bool? {
applicationElement?.wrappedElement.getValue(.hidden) as? Bool
}
var enhancedUserInterface: Bool? {
get {
applicationElement?.wrappedElement.getValue(.enhancedUserInterface) as? Bool
}
set {
guard let newValue = newValue else { return }
applicationElement?.wrappedElement.setValue(.enhancedUserInterface, newValue)
}
}
// Only for Stage Manager
var windowIds: [CGWindowID]? {
wrappedElement.getValue(.windowIds) as? [CGWindowID]
}
func bringToFront(force: Bool = false) {
if isMainWindow != true {
isMainWindow = true
}
if let pid = pid, let app = NSRunningApplication(processIdentifier: pid), !app.isActive || force {
app.activate(options: .activateIgnoringOtherApps)
}
}
}
extension AccessibilityElement {
static func getFrontApplicationElement() -> AccessibilityElement? {
guard let app = NSWorkspace.shared.frontmostApplication else { return nil }
return AccessibilityElement(app.processIdentifier)
}
static func getFrontWindowElement() -> AccessibilityElement? {
guard let appElement = getFrontApplicationElement() else {
Logger.log("Failed to find the application that currently has focus.")
return nil
}
if let focusedWindowElement = appElement.focusedWindowElement {
return focusedWindowElement
}
if let firstWindowElement = appElement.windowElements?.first {
return firstWindowElement
}
Logger.log("Failed to find frontmost window.")
return nil
}
private static func getWindowInfo(_ location: CGPoint) -> WindowInfo? {
WindowUtil.getWindowList().first(where: {windowInfo in
windowInfo.level < 23 // 23 is the level of the Notification Center
&& !["Dock", "WindowManager"].contains(windowInfo.processName)
&& windowInfo.frame.contains(location)
})
}
static func getWindowElementUnderCursor() -> AccessibilityElement? {
let position = NSEvent.mouseLocation.screenFlipped
var systemWideFirst = Defaults.systemWideMouseDown.userEnabled
if Defaults.systemWideMouseDown.notSet, let frontAppId = ApplicationToggle.frontAppId {
systemWideFirst = Defaults.systemWideMouseDownApps.typedValue?.contains(frontAppId) == true
}
if systemWideFirst,
let element = AccessibilityElement(position),
let windowElement = element.windowElement {
return windowElement
}
if let info = getWindowInfo(position) {
if !Defaults.dragFromStage.userDisabled {
if StageUtil.stageCapable && StageUtil.stageEnabled,
let group = StageUtil.getStageStripWindowGroup(info.id),
let windowId = group.first,
windowId != info.id,
let element = StageWindowAccessibilityElement(windowId) {
return element
}
}
if let windowElements = AccessibilityElement(info.pid).windowElements {
if let windowElement = (windowElements.first { $0.windowId == info.id }) {
return windowElement
}
if let windowElement = (windowElements.first { $0.frame == info.frame }) {
return windowElement
}
}
}
if !systemWideFirst,
let element = AccessibilityElement(position),
let windowElement = element.windowElement {
if Logger.logging, let pid = windowElement.pid {
let appName = NSRunningApplication(processIdentifier: pid)?.localizedName ?? ""
Logger.log("Window under cursor fallback matched: \(appName)")
}
return windowElement
}
Logger.log("Unable to obtain the accessibility element with the specified attribute at mouse location")
return nil
}
static func getWindowElement(_ windowId: CGWindowID) -> AccessibilityElement? {
guard let pid = WindowUtil.getWindowList(ids: [windowId]).first?.pid else { return nil }
return AccessibilityElement(pid).windowElements?.first { $0.windowId == windowId }
}
private static let excludedProcessNames: Set<String> = ["Dock", "WindowManager", "Notification Center"]
static func getAllWindowElements() -> [AccessibilityElement] {
return WindowUtil.getWindowList()
.filter { !excludedProcessNames.contains($0.processName ?? "") }
.uniqueMap { $0.pid }
.compactMap { AccessibilityElement($0).windowElements }
.flatMap { $0 }
}
}
extension AccessibilityElement: Equatable {
static func == (lhs: AccessibilityElement, rhs: AccessibilityElement) -> Bool {
return lhs.wrappedElement == rhs.wrappedElement
}
}
extension AccessibilityElement: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(wrappedElement)
}
}
class StageWindowAccessibilityElement: AccessibilityElement {
private let _windowId: CGWindowID
init?(_ windowId: CGWindowID) {
guard let element = AccessibilityElement.getWindowElement(windowId) else { return nil }
_windowId = windowId
super.init(element.wrappedElement)
}
override var frame: CGRect {
let frame = super.frame
guard !frame.isNull, let windowId = windowId, let info = WindowUtil.getWindowList(ids: [windowId]).first else { return frame }
return .init(origin: info.frame.origin, size: frame.size)
}
override var windowId: CGWindowID? {
_windowId
}
}
enum EnhancedUI: Int {
case disableEnable = 1 /// The default behavior - disable Enhanced UI on every window move/resize
case disableOnly = 2 /// Don't re-enable enhanced UI after it gets disabled
case frontmostDisable = 3 /// Disable enhanced UI every time the frontmost app gets changed
}
================================================
FILE: Rectangle/AppDelegate.swift
================================================
//
// AppDelegate.swift
// Rectangle
//
// Created by Ryan Hanson on 6/11/19.
// Copyright © 2019 Ryan Hanson. All rights reserved.
//
import Cocoa
import Sparkle
import ServiceManagement
import os.log
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
static let launcherAppId = "com.knollsoft.RectangleLauncher"
private let accessibilityAuthorization = AccessibilityAuthorization()
private let statusItem = RectangleStatusItem.instance
static let windowHistory = WindowHistory()
var updaterController: SPUStandardUpdaterController!
var hasPendingUpdate = false {
didSet {
Notification.Name.updateAvailability.post()
}
}
private var shortcutManager: ShortcutManager!
private var windowManager: WindowManager!
private var applicationToggle: ApplicationToggle!
private var windowCalculationFactory: WindowCalculationFactory!
private var snappingManager: SnappingManager!
private var titleBarManager: TitleBarManager!
private var prefsWindowController: NSWindowController?
private var prevActiveAppObservation: NSKeyValueObservation?
private var prevActiveApp: NSRunningApplication?
private var additionalSizeMenuItems: [NSMenuItem] = []
private var dynamicMenuItemCount: Int = 0
@IBOutlet weak var mainStatusMenu: NSMenu!
@IBOutlet weak var unauthorizedMenu: NSMenu!
@IBOutlet weak var ignoreMenuItem: NSMenuItem!
@IBOutlet weak var viewLoggingMenuItem: NSMenuItem!
@IBOutlet weak var updatesMenuItem: NSMenuItem!
@IBOutlet weak var quitMenuItem: NSMenuItem!
static var instance: AppDelegate {
NSApp.delegate as! AppDelegate
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
Defaults.loadFromSupportDir()
migrateShowEighthsInMenu()
checkVersion()
mainStatusMenu.delegate = self
statusItem.refreshVisibility()
checkLaunchOnLogin()
let alreadyTrusted = accessibilityAuthorization.checkAccessibility {
self.showWelcomeWindow()
self.checkForConflictingApps()
self.openPreferences(self)
self.statusItem.statusMenu = self.mainStatusMenu
self.accessibilityTrusted()
}
if alreadyTrusted {
accessibilityTrusted()
}
statusItem.statusMenu = alreadyTrusted
? mainStatusMenu
: unauthorizedMenu
mainStatusMenu.autoenablesItems = false
addWindowActionMenuItems()
NotificationCenter.default.addObserver(self, selector: #selector(rebuildMenu), name: .showAdditionalSizesInMenuChanged, object: nil)
updaterController = SPUStandardUpdaterController(updaterDelegate: nil, userDriverDelegate: self)
checkAutoCheckForUpdates()
Notification.Name.configImported.onPost(using: { _ in
self.checkAutoCheckForUpdates()
self.statusItem.refreshVisibility()
self.applicationToggle.reloadFromDefaults()
self.shortcutManager.reloadFromDefaults()
self.snappingManager.reloadFromDefaults()
self.initializeTodo(false)
})
Notification.Name.todoMenuToggled.onPost(using: { _ in
self.initializeTodo(false)
})
prevActiveAppObservation = NSWorkspace.shared.observe(\.frontmostApplication, options: .old) { workspace, change in
self.prevActiveApp = change.oldValue ?? nil
}
}
func checkVersion() {
let currentVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
if let lastVersion = Defaults.lastVersion.value,
let intLastVersion = Int(lastVersion) {
if intLastVersion < 46 {
MASShortcutMigration.migrate()
}
if intLastVersion < 64 {
SnapAreaModel.instance.migrate()
}
if intLastVersion < 72 {
if #available(macOS 13, *) {
SMLoginItemSetEnabled(AppDelegate.launcherAppId as CFString, false)
}
}
} else {
Defaults.installVersion.value = currentVersion
Defaults.allowAnyShortcut.enabled = true
}
Defaults.lastVersion.value = currentVersion
}
func applicationWillBecomeActive(_ notification: Notification) {
Notification.Name.appWillBecomeActive.post()
}
func checkAutoCheckForUpdates() {
updaterController.updater.automaticallyChecksForUpdates = Defaults.SUEnableAutomaticChecks.enabled
}
func accessibilityTrusted() {
self.windowCalculationFactory = WindowCalculationFactory()
self.windowManager = WindowManager()
self.shortcutManager = ShortcutManager(windowManager: windowManager)
self.applicationToggle = ApplicationToggle(shortcutManager: shortcutManager)
self.snappingManager = SnappingManager()
self.titleBarManager = TitleBarManager()
self.initializeTodo()
checkForProblematicApps()
MacTilingDefaults.checkForBuiltInTiling(skipIfAlreadyNotified: true)
}
func checkForConflictingApps() {
let conflictingAppsIds: [String: String] = [
"com.divisiblebyzero.Spectacle": "Spectacle",
"com.crowdcafe.windowmagnet": "Magnet",
"com.hegenberg.BetterSnapTool": "BetterSnapTool",
"com.manytricks.Moom": "Moom"
]
let runningApps = NSWorkspace.shared.runningApplications
for app in runningApps {
guard let bundleId = app.bundleIdentifier else { continue }
if let conflictingAppName = conflictingAppsIds[bundleId] {
AlertUtil.oneButtonAlert(question: "Potential window manager conflict: \(conflictingAppName)", text: "Since \(conflictingAppName) might have some overlapping behavior with Rectangle, it's recommended that you either disable or quit \(conflictingAppName).")
break
}
}
}
/// certain applications have issues with the click listening done by the drag to snap feature
func checkForProblematicApps() {
guard !Defaults.windowSnapping.userDisabled, !Defaults.notifiedOfProblemApps.enabled else { return }
let problemBundleIds: [String] = [
"com.mathworks.matlab",
"com.live2d.cubism.CECubismEditorApp",
"com.aquafold.datastudio.DataStudio",
"com.adobe.illustrator",
"com.adobe.AfterEffects"
]
// these apps are java based with dynamic bundleIds
let problemJavaAppNames: [String] = [
"thinkorswim",
"Trader Workstation"
]
var problemBundles: [Bundle] = problemBundleIds.compactMap { bundleId in
if applicationToggle.isDisabled(bundleId: bundleId) { return nil }
// Directly instantiating the Bundle from the bundle id didn't work for matlab for some reason
if let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleId) {
return Bundle(url: url)
}
return nil
}
for name in problemJavaAppNames {
if let path = NSWorkspace.shared.fullPath(forApplication: name) {
if let bundle = Bundle(path: path),
let bundleId = bundle.bundleIdentifier {
if !applicationToggle.isDisabled(bundleId: bundleId),
bundleId.starts(with: "com.install4j") {
problemBundles.append(bundle)
}
}
}
}
let displayNames = problemBundles.compactMap { $0.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String }
let displayNameString = displayNames.joined(separator: "\n")
if !problemBundles.isEmpty {
AlertUtil.oneButtonAlert(question: "Known issues with installed applications", text: "\(displayNameString)\n\nThese applications have issues with the drag to screen edge to snap functionality in Rectangle.\n\nYou can either ignore the applications using the menu item in Rectangle, or disable drag to screen edge snapping in Rectangle preferences.")
Defaults.notifiedOfProblemApps.enabled = true
}
}
private func showWelcomeWindow() {
let welcomeWindowController = NSStoryboard(name: "Main", bundle: nil)
.instantiateController(withIdentifier: "WelcomeWindowController") as? NSWindowController
guard let welcomeWindow = welcomeWindowController?.window else { return }
welcomeWindow.delegate = self
NSApp.activate(ignoringOtherApps: true)
let response = NSApp.runModal(for: welcomeWindow)
let usingRecommended = response == .alertFirstButtonReturn || response == .abort
Defaults.alternateDefaultShortcuts.enabled = usingRecommended
Defaults.subsequentExecutionMode.value = usingRecommended ? .acrossMonitor : .resize
welcomeWindowController?.close()
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if Defaults.relaunchOpensMenu.enabled {
statusItem.openMenu()
} else {
openPreferences(sender)
}
return true
}
@IBAction func openPreferences(_ sender: Any) {
if prefsWindowController == nil {
prefsWindowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "PrefsWindowController") as? NSWindowController
}
NSApp.activate(ignoringOtherApps: true)
prefsWindowController?.showWindow(self)
}
@IBAction func showAbout(_ sender: Any) {
NSApp.activate(ignoringOtherApps: true)
NSApp.orderFrontStandardAboutPanel(sender)
}
@IBAction func viewLogging(_ sender: Any) {
Logger.showLogging(sender: sender)
}
@IBAction func ignoreFrontMostApp(_ sender: NSMenuItem) {
if sender.state == .on {
applicationToggle.enableApp()
} else {
applicationToggle.disableApp()
}
}
@IBAction func checkForUpdates(_ sender: Any) {
updaterController.checkForUpdates(sender)
}
@IBAction func authorizeAccessibility(_ sender: Any) {
accessibilityAuthorization.showAuthorizationWindow()
}
private func checkLaunchOnLogin() {
if #available(macOS 13.0, *) {
if Defaults.launchOnLogin.enabled, !LaunchOnLogin.isEnabled {
LaunchOnLogin.isEnabled = true
}
} else {
let running = NSWorkspace.shared.runningApplications
let isRunning = !running.filter({$0.bundleIdentifier == AppDelegate.launcherAppId}).isEmpty
if isRunning {
let killNotification = Notification.Name("killLauncher")
DistributedNotificationCenter.default().post(name: killNotification, object: Bundle.main.bundleIdentifier!)
}
if !Defaults.SUHasLaunchedBefore {
Defaults.launchOnLogin.enabled = true
}
// Even if we are already set up to launch on login, setting it again since macOS can be buggy with this type of launch on login.
if Defaults.launchOnLogin.enabled {
let smLoginSuccess = SMLoginItemSetEnabled(AppDelegate.launcherAppId as CFString, true)
if !smLoginSuccess {
if #available(OSX 10.12, *) {
os_log("Unable to enable launch at login. Attempting one more time.", type: .info)
}
SMLoginItemSetEnabled(AppDelegate.launcherAppId as CFString, true)
}
}
}
}
}
extension AppDelegate: NSMenuDelegate {
func menuWillOpen(_ menu: NSMenu) {
if menu != mainStatusMenu {
updateWindowActionMenuItems(menu: menu)
updateTodoModeMenuItems(menu: menu)
return
}
if let frontAppName = ApplicationToggle.frontAppName {
let ignoreString = NSLocalizedString("D99-0O-MB6.title", tableName: "Main", value: "Ignore frontmost.app", comment: "")
ignoreMenuItem.title = ignoreString.replacingOccurrences(of: "frontmost.app", with: frontAppName)
ignoreMenuItem.state = ApplicationToggle.shortcutsDisabled ? .on : .off
ignoreMenuItem.isHidden = false
} else {
ignoreMenuItem.isHidden = true
}
updateWindowActionMenuItems(menu: menu)
updateTodoModeMenuItems(menu: menu)
viewLoggingMenuItem.keyEquivalentModifierMask = .option
quitMenuItem.keyEquivalent = "q"
quitMenuItem.keyEquivalentModifierMask = .command
}
private func updateWindowActionMenuItems(menu: NSMenu) {
let frontmostWindow = AccessibilityElement.getFrontWindowElement()
let screenCount = NSScreen.screens.count
let isPortrait = NSScreen.main?.frame.isLandscape == false
for menuItem in menu.items {
guard let windowAction = menuItem.representedObject as? WindowAction else { continue }
menuItem.image = windowAction.image.copy() as? NSImage
menuItem.image?.size = NSSize(width: 18, height: 12)
if isPortrait && windowAction.classification == .thirds {
menuItem.image = menuItem.image?.rotated(by: 270)
menuItem.image?.isTemplate = true
}
if !ApplicationToggle.shortcutsDisabled {
if let fullKeyEquivalent = shortcutManager.getKeyEquivalent(action: windowAction),
let keyEquivalent = fullKeyEquivalent.0?.lowercased() {
menuItem.keyEquivalent = keyEquivalent
menuItem.keyEquivalentModifierMask = fullKeyEquivalent.1
}
}
if frontmostWindow == nil {
menuItem.isEnabled = false
}
if screenCount == 1
&& (windowAction == .nextDisplay || windowAction == .previousDisplay) {
menuItem.isEnabled = false
}
}
}
func menuDidClose(_ menu: NSMenu) {
for menuItem in menu.items {
menuItem.keyEquivalent = ""
menuItem.keyEquivalentModifierMask = NSEvent.ModifierFlags()
menuItem.isEnabled = true
}
}
@objc func executeMenuWindowAction(sender: NSMenuItem) {
guard let windowAction = sender.representedObject as? WindowAction else { return }
windowAction.postMenu()
}
func addWindowActionMenuItems() {
let additionalSizeCategories: Set<WindowActionCategory> = [.eighths, .ninths, .twelfths, .sixteenths]
let submenuOnlyWhenAdditional: Set<WindowActionCategory> = [.thirds, .size]
let showAdditional = Defaults.showAdditionalSizesInMenu.userEnabled
var menuIndex = 0
var categoryMenus: [CategoryMenu] = []
for action in WindowAction.active {
guard let displayName = action.displayName else { continue }
let newMenuItem = NSMenuItem(title: displayName, action: #selector(executeMenuWindowAction), keyEquivalent: "")
newMenuItem.representedObject = action
if !Defaults.showAllActionsInMenu.userEnabled, let category = action.category {
// When additional sizes are off, keep Thirds and Size as flat items
if submenuOnlyWhenAdditional.contains(category) && !showAdditional {
// Fall through to flat item handling below
} else {
if menuIndex != 0 && action.firstInGroup {
let menu = NSMenu(title: category.displayName)
menu.autoenablesItems = false
categoryMenus.append(CategoryMenu(menu: menu, category: category))
}
categoryMenus.last?.menu.addItem(newMenuItem)
continue
}
}
// Flat item - suppress extra separator for almostMaximize when Size is not a submenu
let showSeparator = action.firstInGroup && !(action == .almostMaximize && !showAdditional)
if menuIndex != 0 && showSeparator {
mainStatusMenu.insertItem(NSMenuItem.separator(), at: menuIndex)
menuIndex += 1
}
mainStatusMenu.insertItem(newMenuItem, at: menuIndex)
menuIndex += 1
}
if !categoryMenus.isEmpty {
mainStatusMenu.insertItem(NSMenuItem.separator(), at: menuIndex)
menuIndex += 1
let sortedCategoryMenus = categoryMenus.sorted { $0.category.menuOrder < $1.category.menuOrder }
for categoryMenu in sortedCategoryMenus {
categoryMenu.menu.delegate = self
let menuMenuItem = NSMenuItem(title: categoryMenu.category.displayName, action: nil, keyEquivalent: "")
if additionalSizeCategories.contains(categoryMenu.category) {
menuMenuItem.isHidden = !Defaults.showAdditionalSizesInMenu.userEnabled
additionalSizeMenuItems.append(menuMenuItem)
}
mainStatusMenu.insertItem(menuMenuItem, at: menuIndex)
mainStatusMenu.setSubmenu(categoryMenu.menu, for: menuMenuItem)
menuIndex += 1
}
}
mainStatusMenu.insertItem(NSMenuItem.separator(), at: menuIndex)
menuIndex += 1
addTodoModeMenuItems(startingIndex: menuIndex)
// Track total dynamic items: window actions + separators + todo items (4 items + 1 separator)
dynamicMenuItemCount = menuIndex + 5
}
@objc func rebuildMenu() {
// Remove all dynamically added items
for _ in 0..<dynamicMenuItemCount {
mainStatusMenu.removeItem(at: 0)
}
dynamicMenuItemCount = 0
additionalSizeMenuItems.removeAll()
addWindowActionMenuItems()
}
private func migrateShowEighthsInMenu() {
let oldKey = "showEighthsInMenu"
let oldValue = UserDefaults.standard.integer(forKey: oldKey)
if oldValue != 0 && Defaults.showAdditionalSizesInMenu.notSet {
Defaults.showAdditionalSizesInMenu.enabled = (oldValue == 1)
}
}
struct CategoryMenu {
let menu: NSMenu
let category: WindowActionCategory
}
}
// todo mode
extension AppDelegate {
func initializeTodo(_ bringToFront: Bool = true) {
self.showHideTodoMenuItems()
TodoManager.registerUnregisterToggleShortcut()
TodoManager.registerUnregisterReflowShortcut()
TodoManager.moveAllIfNeeded(bringToFront)
}
enum TodoItem {
case mode, app, reflow, separator, window
var tag: Int {
switch self {
case .mode: return 101
case .app: return 102
case .reflow: return 103
case .separator: return 104
case .window: return 105
}
}
static let tags = [101, 102, 103, 104, 105]
}
private func addTodoModeMenuItems(startingIndex: Int) {
var menuIndex = startingIndex
let todoModeItemTitle = NSLocalizedString("Enable Todo Mode", tableName: "Main", value: "", comment: "")
let todoModeMenuItem = NSMenuItem(title: todoModeItemTitle, action: #selector(toggleTodoMode), keyEquivalent: "")
todoModeMenuItem.tag = TodoItem.mode.tag
todoModeMenuItem.target = self
mainStatusMenu.insertItem(todoModeMenuItem, at: menuIndex)
menuIndex += 1
let todoAppItemTitle = NSLocalizedString("Use frontmost.app as Todo App", tableName: "Main", value: "", comment: "")
let todoAppMenuItem = NSMenuItem(title: todoAppItemTitle, action: #selector(setTodoApp), keyEquivalent: "")
todoAppMenuItem.tag = TodoItem.app.tag
mainStatusMenu.insertItem(todoAppMenuItem, at: menuIndex)
menuIndex += 1
let todoWindowItemTitle = NSLocalizedString("Use as Todo Window", tableName: "Main", value: "", comment: "")
let todoWindowMenuItem = NSMenuItem(title: todoWindowItemTitle, action: #selector(setTodoWindow), keyEquivalent: "")
todoWindowMenuItem.tag = TodoItem.window.tag
mainStatusMenu.insertItem(todoWindowMenuItem, at: menuIndex)
menuIndex += 1
let todoReflowItemTitle = NSLocalizedString("Reflow Todo", tableName: "Main", value: "", comment: "")
let todoReflowItem = NSMenuItem(title: todoReflowItemTitle, action: #selector(todoReflow), keyEquivalent: "")
todoReflowItem.tag = TodoItem.reflow.tag
mainStatusMenu.insertItem(todoReflowItem, at: menuIndex)
menuIndex += 1
let separator = NSMenuItem.separator()
separator.tag = TodoItem.separator.tag
mainStatusMenu.insertItem(separator, at: menuIndex)
showHideTodoMenuItems()
}
private func showHideTodoMenuItems() {
for item in mainStatusMenu.items {
if TodoItem.tags.contains(item.tag) {
item.isHidden = !Defaults.todo.userEnabled
}
}
}
@objc func toggleTodoMode(_ sender: NSMenuItem) {
let enabled = sender.state == .off
TodoManager.setTodoMode(enabled)
}
@objc func setTodoApp(_ sender: NSMenuItem) {
applicationToggle.setTodoApp()
TodoManager.moveAllIfNeeded()
}
@objc func todoReflow(_ sender: NSMenuItem) {
TodoManager.moveAll()
}
@objc func setTodoWindow(_ sender: NSMenuItem) {
TodoManager.resetTodoWindow()
TodoManager.moveAllIfNeeded()
}
private func updateTodoModeMenuItems(menu: NSMenu) {
guard Defaults.todo.userEnabled,
let todoAppMenuItem = menu.item(withTag: TodoItem.app.tag),
let todoModeMenuItem = menu.item(withTag: TodoItem.mode.tag),
let todoReflowMenuItem = menu.item(withTag: TodoItem.reflow.tag),
let todoWindowMenuItem = menu.item(withTag: TodoItem.window.tag)
else {
return
}
if let frontAppName = ApplicationToggle.frontAppName {
let appString = NSLocalizedString("Use frontmost.app as Todo App", tableName: "Main", value: "", comment: "")
todoAppMenuItem.title = appString.replacingOccurrences(
of: "frontmost.app", with: frontAppName)
todoAppMenuItem.isEnabled = !applicationToggle.todoAppIsActive()
todoAppMenuItem.state = applicationToggle.todoAppIsActive() ? .on : .off
todoAppMenuItem.isHidden = false
} else {
todoAppMenuItem.isHidden = true
}
todoModeMenuItem.state = Defaults.todoMode.enabled ? .on : .off
if let fullKeyEquivalent = TodoManager.getToggleKeyDisplay(),
let keyEquivalent = fullKeyEquivalent.0?.lowercased() {
todoModeMenuItem.keyEquivalent = keyEquivalent
todoModeMenuItem.keyEquivalentModifierMask = fullKeyEquivalent.1
}
if let fullKeyEquivalent = TodoManager.getReflowKeyDisplay(),
let keyEquivalent = fullKeyEquivalent.0?.lowercased() {
todoReflowMenuItem.keyEquivalent = keyEquivalent
todoReflowMenuItem.keyEquivalentModifierMask = fullKeyEquivalent.1
}
todoReflowMenuItem.isEnabled = Defaults.todoMode.enabled
todoWindowMenuItem.isHidden = !applicationToggle.todoAppIsActive() || TodoManager.isTodoWindowFront()
}
}
extension AppDelegate: NSWindowDelegate {
func windowWillClose(_ notification: Notification) {
NSApp.abortModal()
}
}
extension AppDelegate {
func application(_ application: NSApplication, open urls: [URL]) {
if NSWorkspace.shared.frontmostApplication == NSRunningApplication.current {
prevActiveApp?.activate()
}
DispatchQueue.main.async {
func getUrlName(_ name: String) -> String {
return name.map { $0.isUppercase ? "-" + $0.lowercased() : String($0) }.joined()
}
func extractBundleIdParameter(fromComponents components: URLComponents) -> String? {
(components.queryItems?.first { $0.name == "app-bundle-id" })?.value ?? ApplicationToggle.frontAppId
}
func isValidParameter(bundleId: String?) -> Bool {
let isValid = bundleId?.isEmpty != true
if !isValid {
Logger.log("Received an empty app-bundle-id parameter. Either pass a valid app bundle id or remove the parameter.")
}
return isValid
}
for url in urls {
guard
let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
components.path.isEmpty
else {
continue
}
let name = (components.queryItems?.first { $0.name == "name" })?.value
switch (components.host, name) {
case ("execute-action", _):
let action = (WindowAction.active.first { getUrlName($0.name) == name })
action?.postUrl()
case ("execute-task", "ignore-app"):
let bundleId = extractBundleIdParameter(fromComponents: components)
guard isValidParameter(bundleId: bundleId) else { continue }
self.applicationToggle.disableApp(appBundleId: bundleId)
case ("execute-task", "unignore-app"):
let bundleId = extractBundleIdParameter(fromComponents: components)
guard isValidParameter(bundleId: bundleId) else { continue }
self.applicationToggle.enableApp(appBundleId: bundleId)
default:
continue
}
}
}
}
}
extension AppDelegate: SPUStandardUserDriverDelegate {
var supportsGentleScheduledUpdateReminders: Bool {
true
}
func standardUserDriverShouldHandleShowingScheduledUpdate(_ update: SUAppcastItem, andInImmediateFocus immediateFocus: Bool) -> Bool {
if immediateFocus {
return true
}
self.hasPendingUpdate = true
updatesMenuItem.title = "Update Available…".localized
return false
}
func standardUserDriverWillFinishUpdateSession() {
self.hasPendingUpdate = false
updatesMenuItem.title = "Check for Updates…".localized(key: "HIK-3r-i7E.title")
}
}
================================================
FILE: Rectangle/AppIcon.icon/icon.json
================================================
{
"color-space-for-untagged-svg-colors" : "display-p3",
"fill" : {
"linear-gradient" : [
"display-p3:0.36863,0.43529,0.50980,1.00000",
"srgb:0.24706,0.27451,0.33333,1.00000"
]
},
"groups" : [
{
"blur-material" : null,
"layers" : [
{
"glass" : true,
"image-name" : "Dots.svg",
"name" : "Dots"
}
],
"shadow" : {
"kind" : "none",
"opacity" : 0.5
},
"specular" : true,
"translucency" : {
"enabled" : true,
"value" : 0.2
}
},
{
"layers" : [
{
"fill-specializations" : [
{
"appearance" : "tinted",
"value" : {
"linear-gradient" : [
"gray:0.90000,1.00000",
"extended-gray:0.75000,1.00000"
]
}
}
],
"glass" : true,
"image-name" : "Overlay.svg",
"name" : "Overlay"
}
],
"shadow" : {
"kind" : "layer-color",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"squares" : [
"macOS"
]
}
}
================================================
FILE: Rectangle/ApplicationToggle.swift
================================================
//
// ApplicationToggle.swift
// Rectangle
//
// Created by Ryan Hanson on 6/18/19.
// Copyright © 2019 Ryan Hanson. All rights reserved.
//
import Cocoa
class ApplicationToggle: NSObject {
private var disabledApps = Set<String>()
public private(set) static var frontAppId: String? = "com.knollsoft.Rectangle"
public private(set) static var frontAppName: String? = "Rectangle"
public private(set) static var shortcutsDisabled: Bool = false
private let shortcutManager: ShortcutManager
init(shortcutManager: ShortcutManager) {
self.shortcutManager = shortcutManager
super.init()
registerFrontAppChangeNote()
if let disabledApps = getDisabledApps() {
self.disabledApps = disabledApps
}
}
public func reloadFromDefaults() {
if let disabledApps = getDisabledApps() {
self.disabledApps = disabledApps
} else {
disabledApps.removeAll()
}
}
private func saveDisabledApps() {
let encoder = JSONEncoder()
if let jsonDisabledApps = try? encoder.encode(disabledApps) {
if let jsonString = String(data: jsonDisabledApps, encoding: .utf8) {
Defaults.disabledApps.value = jsonString
}
}
}
private func getDisabledApps() -> Set<String>? {
guard let jsonDisabledAppsString = Defaults.disabledApps.value else { return nil }
let decoder = JSONDecoder()
guard let jsonDisabledApps = jsonDisabledAppsString.data(using: .utf8) else { return nil }
guard let disabledApps = try? decoder.decode(Set<String>.self, from: jsonDisabledApps) else { return nil }
return disabledApps
}
private func disableShortcuts() {
if !Self.shortcutsDisabled {
Self.shortcutsDisabled = true
self.shortcutManager.unbindShortcuts()
if !Defaults.ignoreDragSnapToo.userDisabled {
Notification.Name.windowSnapping.post(object: false)
}
}
}
private func enableShortcuts() {
if Self.shortcutsDisabled {
Self.shortcutsDisabled = false
self.shortcutManager.bindShortcuts()
if !Defaults.ignoreDragSnapToo.userDisabled {
Notification.Name.windowSnapping.post(object: true)
}
}
}
public func disableApp(appBundleId: String? = frontAppId) {
if let appBundleId {
disabledApps.insert(appBundleId)
saveDisabledApps()
disableShortcuts()
}
}
public func enableApp(appBundleId: String? = frontAppId) {
if let appBundleId {
disabledApps.remove(appBundleId)
saveDisabledApps()
enableShortcuts()
}
}
public func isDisabled(bundleId: String) -> Bool {
return disabledApps.contains(bundleId)
}
private func registerFrontAppChangeNote() {
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.receiveFrontAppChangeNote(_:)), name: NSWorkspace.didActivateApplicationNotification, object: nil)
}
@objc func receiveFrontAppChangeNote(_ notification: Notification) {
if let application = notification.userInfo?["NSWorkspaceApplicationKey"] as? NSRunningApplication {
Self.frontAppId = application.bundleIdentifier
Self.frontAppName = application.localizedName
if let frontAppId = application.bundleIdentifier {
if isDisabled(bundleId: frontAppId) {
disableShortcuts()
} else {
enableShortcuts()
}
Notification.Name.frontAppChanged.post()
} else {
enableShortcuts()
}
if Defaults.enhancedUI.value == .frontmostDisable {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(50)) {
AccessibilityElement.getFrontApplicationElement()?.enhancedUserInterface = false
}
}
}
}
}
// todo mode
extension ApplicationToggle {
public func setTodoApp() {
Defaults.todoApplication.value = Self.frontAppId
}
public func todoAppIsActive() -> Bool {
return Defaults.todoApplication.value == Self.frontAppId
}
}
================================================
FILE: Rectangle/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"filename" : "mac016pts1x.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "mac016pts2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "mac032pts1x.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "mac032pts2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "mac128pts1x.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "mac128pts2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "mac256pts1x.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "mac256pts2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "mac512pts1x.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "mac512pts2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/StatusTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "RectangleStatusTemplate22.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "RectangleStatusTemplate44.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "RectangleStatusTemplate.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/almostMaximizeTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "almostMaximizeTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/blEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "blEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomCenterLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomCenterLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomCenterLeftTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomCenterLeftTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomCenterNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomCenterNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomCenterRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomCenterRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomCenterRightTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomCenterRightTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomCenterSixthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomCenterSixthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomHalfTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "bottomHalfTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomLeftNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomLeftNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomLeftSixthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomLeftSixthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomLeftTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "bottomLeftTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomLeftTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomLeftTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomRightNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomRightNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomRightSixthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomRightSixthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomRightTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "bottomRightTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomRightTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomRightTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomThirdTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomThirdTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/bottomTwoThirdsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "bottomTwoThirdsTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/brEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "brEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/cblEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "cblEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/cbrEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "cbrEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerLeftFourthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "centerLeftFourthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerRightFourthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "centerRightFourthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "centerTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerThirdHorizontalTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "centerThirdTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerThirdTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "centerThirdTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerThreeFourthsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "centerThreeFourthsTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/centerTwoThirdsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "centerTwoThirdsTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/ctlEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "ctlEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/ctrEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "ctrEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/firstThirdTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "firstThirdTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/firstThreeFourthsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "firstThreeFourthsTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/firstTwoThirdsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "firstTwoThirdsTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/halfWidthCenterTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "halfWidthCenterTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/largerWidthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "largerWidthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lastThirdTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "lastThirdTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lastThreeFourthsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "lastThreeFourthsTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lastTwoThirdsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "lastTwoThirdsTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/leftFourthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "leftFourthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/leftHalfTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "leftHalfTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lowerMiddleCenterLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "lowerMiddleCenterLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lowerMiddleCenterRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "lowerMiddleCenterRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lowerMiddleLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "lowerMiddleLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/lowerMiddleRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "lowerMiddleRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/makeLargerTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "makeLargerTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/makeSmallerTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "makeSmallerTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/maximizeHeightTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "maximizeHeightTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/maximizeTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "maximizeTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleCenterLeftTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleCenterLeftTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleCenterNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleCenterNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleCenterRightTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleCenterRightTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleLeftNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleLeftNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleLeftTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleLeftTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleRightNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleRightNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/middleRightTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "middleRightTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/moveDownTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "moveDownTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/moveLeftTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "moveLeftTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/moveRightTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "moveRightTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/moveUpTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "moveUpTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/nextDisplayTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "nextDisplayTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/prevDisplayTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "prevDisplayTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/restoreTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "restoreTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/rightFourthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "rightFourthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/rightHalfTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "rightHalfTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/smallerWidthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "smallerWidthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/tlEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "tlEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topCenterLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topCenterLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topCenterLeftTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topCenterLeftTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topCenterNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topCenterNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topCenterRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topCenterRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topCenterRightTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topCenterRightTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topCenterSixthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topCenterSixthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topHalfTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "topHalfTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topLeftNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topLeftNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topLeftSixthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topLeftSixthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topLeftTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "topLeftTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topLeftTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topLeftTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topRightNinthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topRightNinthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topRightSixthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topRightSixthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topRightTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "topRightTemplate.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topRightTwelfthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topRightTwelfthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topThirdTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topThirdTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/topTwoThirdsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "topTwoThirdsTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/trEighthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "trEighthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/upperMiddleCenterLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "upperMiddleCenterLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/upperMiddleCenterRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "upperMiddleCenterRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/upperMiddleLeftSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "upperMiddleLeftSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/WindowPositions/upperMiddleRightSixteenthTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "upperMiddleRightSixteenthTemplate.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/keyboardToolbarTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "keyboardToolbarTemplateSmall.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "keyboardToolbarTemplate.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/snapAreaTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "snapAreaTemplateSmall.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "snapAreaTemplate.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/square.and.arrow.down.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "square.and.arrow.down.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
================================================
FILE: Rectangle/Assets.xcassets/square.and.arrow.up.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "square.and.arrow.up.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
================================================
FILE: Rectangle/Assets.xcassets/toolbarSettingsTemplate.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "toolbarSettingsTemplate copy.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "toolbarSettingsTemplate.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/wallpaperTiger.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "wallpaperTiger.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Assets.xcassets/wallpaperTigerVertical.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "wallpaperTigerVertical.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Rectangle/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="Rectangle" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Rectangle" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About Rectangle" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide Rectangle" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit Rectangle" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="Rectangle Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Rectangle" customModuleProvider="target">
<connections>
<outlet property="ignoreMenuItem" destination="D99-0O-MB6" id="iBN-Bc-ds7"/>
<outlet property="mainStatusMenu" destination="6wc-Rn-2EG" id="UWt-be-ZH1"/>
<outlet property="quitMenuItem" destination="A66-A4-cGD" id="Vul-Dd-RcH"/>
<outlet property="unauthorizedMenu" destination="HZt-qn-3MK" id="c4f-hw-GWr"/>
<outlet property="updatesMenuItem" destination="HIK-3r-i7E" id="UGJ-IC-qKI"/>
<outlet property="viewLoggingMenuItem" destination="O8K-y6-bva" id="31H-se-kyh"/>
</connections>
</customObject>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<menu id="6wc-Rn-2EG">
<items>
<menuItem title="Ignore frontmost.app" id="D99-0O-MB6">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="ignoreFrontMostApp:" target="Voe-Tx-rLC" id="CTQ-bh-luD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="hf9-TP-K3t"/>
<menuItem title="Settings…" id="YRC-4a-xGg">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openPreferences:" target="Voe-Tx-rLC" id="EgB-O8-H7c"/>
</connections>
</menuItem>
<menuItem title="About" id="gFy-Zj-RGl">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showAbout:" target="Voe-Tx-rLC" id="dGA-Fy-dtB"/>
</connections>
</menuItem>
<menuItem title="View Logging…" alternate="YES" id="O8K-y6-bva">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="viewLogging:" target="Voe-Tx-rLC" id="8cH-2P-yKC"/>
</connections>
</menuItem>
<menuItem title="Check for Updates…" id="HIK-3r-i7E">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="checkForUpdates:" target="Voe-Tx-rLC" id="kWZ-ie-6y9"/>
</connections>
</menuItem>
<menuItem title="Quit Rectangle" keyEquivalent="q" id="A66-A4-cGD">
<connections>
<action selector="terminate:" target="hnw-xV-0zn" id="M1a-kx-BJY"/>
</connections>
</menuItem>
</items>
</menu>
<menu id="HZt-qn-3MK">
<items>
<menuItem title="Not Authorized to Control Your Computer" id="cBj-76-2E7">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Authorize…" id="VIf-4h-MJW">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="authorizeAccessibility:" target="Voe-Tx-rLC" id="fFL-4P-f1a"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="9x0-IB-BiQ"/>
<menuItem title="About" id="jxe-nr-LDQ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="hnw-xV-0zn" id="o6b-d0-Qt8"/>
</connections>
</menuItem>
<menuItem title="Quit Rectangle" keyEquivalent="q" id="yvN-PE-bxn">
<connections>
<action selector="terminate:" target="hnw-xV-0zn" id="esy-Pm-oTg"/>
</connections>
</menuItem>
</items>
</menu>
</objects>
<point key="canvasLocation" x="-168" y="-75"/>
</scene>
<!--Window Controller-->
<scene sceneID="9jZ-4I-Wps">
<objects>
<windowController storyboardIdentifier="PrefsWindowController" showSeguePresentationStyle="single" id="fmq-Go-Xew" sceneMemberID="viewController">
<window key="window" title="Rectangle Settings" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" titlebarAppearsTransparent="YES" id="STb-JK-oB1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<rect key="contentRect" x="245" y="301" width="433" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1025"/>
<connections>
<outlet property="delegate" destination="fmq-Go-Xew" id="Jj5-zM-epV"/>
</connections>
</window>
<connections>
<segue destination="5pc-CV-2b9" kind="relationship" relationship="window.shadowedContentViewController" id="94P-kM-qwg"/>
</connections>
</windowController>
<customObject id="jE6-FX-lql" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-204" y="230"/>
</scene>
<!--Prefs View Controller-->
<scene sceneID="vcH-Iu-BJm">
<objects>
<viewController storyboardIdentifier="PrefsViewController" showSeguePresentationStyle="single" id="zlF-FD-XEr" customClass="PrefsViewController" customModule="Rectangle" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="8J7-VI-pmF">
<rect key="frame" x="0.0" y="0.0" width="850" height="686"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView distribution="equalCentering" orientation="horizontal" alignment="centerY" spacing="0.0" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zal-I3-aOt">
<rect key="frame" x="0.0" y="0.0" width="850" height="686"/>
<subviews>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" horizontalHuggingPriority="251" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CSq-gR-vah">
<rect key="frame" x="59" y="20" width="733" height="646"/>
<subviews>
<stackView distribution="fillEqually" orientation="horizontal" alignment="top" spacing="43" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qhf-Xx-S0m">
<rect key="frame" x="0.0" y="389" width="733" height="257"/>
<subviews>
<stackView distribution="fill" orientation="vertical" alignment="trailing" spacing="9" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gt6-OD-H04">
<rect key="frame" x="0.0" y="0.0" width="345" height="257"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6dl-2T-B9P">
<rect key="frame" x="86" y="238" width="259" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ce1-6G-Nkf">
<rect key="frame" x="0.0" y="2" width="81" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oac-MY-1n1">
<rect key="frame" x="-2" y="0.0" width="56" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Left Half" id="Xc8-Sm-pig">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="FMg-QE-c8c">
<rect key="frame" x="60" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="grA-Oc-QdZ"/>
<constraint firstAttribute="width" constant="21" id="slt-a4-LiJ"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="leftHalfTemplate" id="niV-VO-dFO"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="bGP-y9-ToI" customClass="MASShortcutView">
<rect key="frame" x="99" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="height" constant="19" id="HHy-nL-j7h"/>
<constraint firstAttribute="width" constant="160" id="g6q-pY-eGi"/>
</constraints>
</customView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hzQ-m9-MoW">
<rect key="frame" x="78" y="210" width="267" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-Yv-nag">
<rect key="frame" x="0.0" y="2" width="89" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="daG-bl-Dca">
<rect key="frame" x="-2" y="0.0" width="64" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Right Half" id="F8S-GI-LiB">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="qQH-OG-nFg">
<rect key="frame" x="68" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="21" id="Hqn-G9-Fhg"/>
<constraint firstAttribute="height" constant="14" id="cMo-S4-1Xr"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="rightHalfTemplate" id="jFw-PK-jEa"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="DJc-yE-qoJ" customClass="MASShortcutView">
<rect key="frame" x="107" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="gbX-O0-CQo"/>
<constraint firstAttribute="height" constant="19" id="k1S-LY-sDu"/>
</constraints>
</customView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mCe-iK-xay">
<rect key="frame" x="69" y="182" width="276" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OYx-6S-b7J">
<rect key="frame" x="0.0" y="2" width="98" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3T8-Nh-bKb">
<rect key="frame" x="-2" y="0.0" width="73" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Center Half" id="bRX-dV-iAR">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="zuU-r6-8ZI">
<rect key="frame" x="77" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="VfN-dW-VyH"/>
<constraint firstAttribute="width" constant="21" id="wdM-Aa-wbu"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="halfWidthCenterTemplate" id="Nlm-wE-Ala"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="3Pa-H7-x3u" customClass="MASShortcutView">
<rect key="frame" x="116" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="Dx5-7f-weD"/>
<constraint firstAttribute="height" constant="19" id="egB-px-g2J"/>
</constraints>
</customView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UZI-sV-QY7">
<rect key="frame" x="87" y="154" width="258" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Us6-9p-1W0">
<rect key="frame" x="0.0" y="2" width="80" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="j1Z-dN-QdR">
<rect key="frame" x="-2" y="0.0" width="55" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Top Half" id="d7y-s8-7GE">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ije-LR-mK5">
<rect key="frame" x="59" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="B86-qt-NA5"/>
<constraint firstAttribute="width" constant="21" id="PfA-94-kot"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="topHalfTemplate" id="hLe-BD-DS8"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="ppH-ve-v6N" customClass="MASShortcutView">
<rect key="frame" x="98" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="CYP-H5-scH"/>
<constraint firstAttribute="height" constant="19" id="m73-1c-QCb"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="19" id="eyI-8P-Cor"/>
</constraints>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mG2-Ie-LGc">
<rect key="frame" x="65" y="126" width="280" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bJh-ua-m5c">
<rect key="frame" x="0.0" y="2" width="102" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xwW-KA-j8t">
<rect key="frame" x="-2" y="0.0" width="77" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Bottom Half" id="ec4-FB-fMa">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="a2i-42-WyD">
<rect key="frame" x="81" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="21" id="NNa-bt-h3b"/>
<constraint firstAttribute="height" constant="14" id="tEt-B4-ThP"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="bottomHalfTemplate" id="rhq-RH-9Dx"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="EhR-CV-u8d" customClass="MASShortcutView">
<rect key="frame" x="120" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="height" constant="19" id="QPA-YK-9mN"/>
<constraint firstAttribute="width" constant="160" id="eTK-wh-TKh"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="19" id="IIv-mh-mPl"/>
</constraints>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="vertical" alignment="leading" spacing="0.0" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="12W-gY-FHp">
<rect key="frame" x="21" y="112" width="324" height="5"/>
<constraints>
<constraint firstAttribute="height" constant="5" id="lTi-x2-WTD"/>
<constraint firstAttribute="width" priority="750" constant="324" id="xZH-Ps-oFE"/>
</constraints>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xSC-UJ-fXz">
<rect key="frame" x="88" y="84" width="257" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2uc-Nz-b1g">
<rect key="frame" x="0.0" y="2" width="79" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HKQ-k8-IOz">
<rect key="frame" x="-2" y="0.0" width="54" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Top Left" id="adp-cN-qkh">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="KwF-pH-4ai">
<rect key="frame" x="58" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="LUw-sU-CUy"/>
<constraint firstAttribute="width" constant="21" id="y9f-o3-9cn"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="topLeftTemplate" id="vqt-7b-pdJ"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="XIn-7Q-Fuy" customClass="MASShortcutView">
<rect key="frame" x="97" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="width" constant="160" id="L6q-We-uRa"/>
<constraint firstAttribute="height" constant="19" id="XcC-xK-4Ve"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="19" id="JNW-qU-mwE"/>
</constraints>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hng-5H-ol0">
<rect key="frame" x="80" y="56" width="265" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hDT-ZP-q5C">
<rect key="frame" x="0.0" y="2" width="87" height="16"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZHg-2r-X9K">
<rect key="frame" x="-2" y="0.0" width="62" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Top Right" id="0Ak-33-SM7">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="H9u-70-HWQ">
<rect key="frame" x="66" y="1" width="21" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="6PM-sF-9Sv"/>
<constraint firstAttribute="width" constant="21" id="QaT-Lr-c0r"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="topRightTemplate" id="dgI-LE-ah9"/>
</imageView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="OgW-L0-nuS" customClass="MASShortcutView">
<rect key="frame" x="105" y="0.0" width="160" height="19"/>
<constraints>
<constraint firstAttribute="height" constant="19" id="FKY-cN-MnA"/>
<constraint firstAttribute="width" constant="160" id="OIf-0U-mLf"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="19" id="2KF-NP-6dZ"/>
</constraints>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" spacing="18" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vdR-hP-Tpn">
<rect key="frame" x="66" y="28" width="279" height="19"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xfy-3f-KPI">
<rect key="frame" x="0.0" y="2" width="101" height="16"/>
gitextract_oju34tob/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ ├── funding.yml │ └── workflows/ │ └── build.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Rectangle/ │ ├── AccessibilityAuthorization/ │ │ ├── AccessibilityAuthorization.swift │ │ └── AccessibilityWindowController.swift │ ├── AccessibilityElement.swift │ ├── AppDelegate.swift │ ├── AppIcon.icon/ │ │ └── icon.json │ ├── ApplicationToggle.swift │ ├── Assets.xcassets/ │ │ ├── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── StatusTemplate.imageset/ │ │ │ └── Contents.json │ │ ├── WindowPositions/ │ │ │ ├── Contents.json │ │ │ ├── almostMaximizeTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── blEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomCenterLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomCenterLeftTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomCenterNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomCenterRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomCenterRightTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomCenterSixthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomHalfTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomLeftNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomLeftSixthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomLeftTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomLeftTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomRightNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomRightSixthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomRightTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomRightTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomThirdTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bottomTwoThirdsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── brEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── cblEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── cbrEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerLeftFourthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerRightFourthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerThirdHorizontalTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerThirdTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerThreeFourthsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── centerTwoThirdsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ctlEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ctrEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── firstThirdTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── firstThreeFourthsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── firstTwoThirdsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── halfWidthCenterTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── largerWidthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lastThirdTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lastThreeFourthsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lastTwoThirdsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── leftFourthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── leftHalfTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lowerMiddleCenterLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lowerMiddleCenterRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lowerMiddleLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── lowerMiddleRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── makeLargerTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── makeSmallerTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── maximizeHeightTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── maximizeTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleCenterLeftTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleCenterNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleCenterRightTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleLeftNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleLeftTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleRightNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── middleRightTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── moveDownTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── moveLeftTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── moveRightTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── moveUpTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── nextDisplayTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── prevDisplayTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── restoreTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── rightFourthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── rightHalfTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── smallerWidthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── tlEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topCenterLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topCenterLeftTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topCenterNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topCenterRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topCenterRightTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topCenterSixthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topHalfTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topLeftNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topLeftSixthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topLeftTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topLeftTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topRightNinthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topRightSixthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topRightTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topRightTwelfthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topThirdTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── topTwoThirdsTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── trEighthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── upperMiddleCenterLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── upperMiddleCenterRightSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── upperMiddleLeftSixteenthTemplate.imageset/ │ │ │ │ └── Contents.json │ │ │ └── upperMiddleRightSixteenthTemplate.imageset/ │ │ │ └── Contents.json │ │ ├── keyboardToolbarTemplate.imageset/ │ │ │ └── Contents.json │ │ ├── snapAreaTemplate.imageset/ │ │ │ └── Contents.json │ │ ├── square.and.arrow.down.imageset/ │ │ │ └── Contents.json │ │ ├── square.and.arrow.up.imageset/ │ │ │ └── Contents.json │ │ ├── toolbarSettingsTemplate.imageset/ │ │ │ └── Contents.json │ │ ├── wallpaperTiger.imageset/ │ │ │ └── Contents.json │ │ └── wallpaperTigerVertical.imageset/ │ │ └── Contents.json │ ├── Base.lproj/ │ │ └── Main.storyboard │ ├── CycleSize.swift │ ├── Defaults.swift │ ├── Info.plist │ ├── InternetAccessPolicy.plist │ ├── LaunchOnLogin.swift │ ├── Logging/ │ │ ├── LogViewer.storyboard │ │ └── LogViewer.swift │ ├── MultiWindow/ │ │ ├── MultiWindowManager.swift │ │ └── ReverseAllManager.swift │ ├── Popover/ │ │ ├── MessageView.swift │ │ └── MessageView.xib │ ├── PrefsWindow/ │ │ ├── Config.swift │ │ ├── PrefsViewController.swift │ │ ├── SettingsViewController.swift │ │ └── SnapAreaViewController.swift │ ├── Rectangle-Bridging-Header.h │ ├── Rectangle.entitlements │ ├── RectangleRelease.entitlements │ ├── RectangleStatusItem.swift │ ├── ScreenDetection.swift │ ├── ShortcutManager.swift │ ├── Snapping/ │ │ ├── CompoundSnapArea/ │ │ │ ├── CompoundSnapArea.swift │ │ │ ├── EighthsCompoundCalculation.swift │ │ │ ├── FourthsCompoundCalculation.swift │ │ │ ├── HalvesCompoundCalculation.swift │ │ │ ├── SixthsCompoundCalculation.swift │ │ │ └── ThirdsCompoundCalculation.swift │ │ ├── FootprintWindow.swift │ │ ├── SnapAreaModel.swift │ │ └── SnappingManager.swift │ ├── SubsequentExecutionMode.swift │ ├── TitleBarManager.swift │ ├── TodoMode/ │ │ └── TodoManager.swift │ ├── Utilities/ │ │ ├── AXExtension.swift │ │ ├── AlertUtil.swift │ │ ├── CFExtension.swift │ │ ├── CGExtension.swift │ │ ├── CUtil.swift │ │ ├── Debounce.swift │ │ ├── DispatchTimeExtension.swift │ │ ├── EventMonitor.swift │ │ ├── MASShortcutMigration.swift │ │ ├── MacTilingDefaults.swift │ │ ├── NSImageExtension.swift │ │ ├── NotificationExtension.swift │ │ ├── RunLoopThread.swift │ │ ├── SequenceExtension.swift │ │ ├── StageUtil.swift │ │ ├── StringExtension.swift │ │ ├── TimeoutCache.swift │ │ └── WindowUtil.swift │ ├── WelcomeWindow/ │ │ └── WelcomeViewController.swift │ ├── WindowAction.swift │ ├── WindowActionCategory.swift │ ├── WindowCalculation/ │ │ ├── AlmostMaximizeCalculation.swift │ │ ├── BottomCenterLeftEighthCalculation.swift │ │ ├── BottomCenterLeftSixteenthCalculation.swift │ │ ├── BottomCenterLeftTwelfthCalculation.swift │ │ ├── BottomCenterNinthCalculation.swift │ │ ├── BottomCenterRightEighthCalculation.swift │ │ ├── BottomCenterRightSixteenthCalculation.swift │ │ ├── BottomCenterRightTwelfthCalculation.swift │ │ ├── BottomCenterSixthCalculation.swift │ │ ├── BottomHalfCalculation.swift │ │ ├── BottomLeftEighthCalculation.swift │ │ ├── BottomLeftNinthCalculation.swift │ │ ├── BottomLeftSixteenthCalculation.swift │ │ ├── BottomLeftSixthCalculation.swift │ │ ├── BottomLeftThirdCalculation.swift │ │ ├── BottomLeftTwelfthCalculation.swift │ │ ├── BottomRightEighthCalculation.swift │ │ ├── BottomRightNinthCalculation.swift │ │ ├── BottomRightSixteenthCalculation.swift │ │ ├── BottomRightSixthCalculation.swift │ │ ├── BottomRightThirdCalculation.swift │ │ ├── BottomRightTwelfthCalculation.swift │ │ ├── BottomVerticalThirdCalculation.swift │ │ ├── BottomVerticalTwoThirdsCalculation.swift │ │ ├── CenterCalculation.swift │ │ ├── CenterHalfCalculation.swift │ │ ├── CenterProminentlyCalculation.swift │ │ ├── CenterThirdCalculation.swift │ │ ├── CenterThreeFourthsCalculation.swift │ │ ├── CenterTwoThirdsCalculation.swift │ │ ├── ChangeSizeCalculation.swift │ │ ├── ChangeWindowDimensionCalculation.swift │ │ ├── EighthsRepeated.swift │ │ ├── FirstFourthCalculation.swift │ │ ├── FirstThirdCalculation.swift │ │ ├── FirstThreeFourthsCalculation.swift │ │ ├── FirstTwoThirdsCalculation.swift │ │ ├── GapCalculation.swift │ │ ├── HalfOrDoubleDimensionCalculation.swift │ │ ├── HorizontalThirdsRepeated.swift │ │ ├── LastFourthCalculation.swift │ │ ├── LastThirdCalculation.swift │ │ ├── LastThreeFourthsCalculation.swift │ │ ├── LastTwoThirdsCalculation.swift │ │ ├── LeftRightHalfCalculation.swift │ │ ├── LeftTodoCalculation.swift │ │ ├── LowerLeftCalculation.swift │ │ ├── LowerMiddleCenterLeftSixteenthCalculation.swift │ │ ├── LowerMiddleCenterRightSixteenthCalculation.swift │ │ ├── LowerMiddleLeftSixteenthCalculation.swift │ │ ├── LowerMiddleRightSixteenthCalculation.swift │ │ ├── LowerRightCalculation.swift │ │ ├── MaximizeCalculation.swift │ │ ├── MaximizeHeightCalculation.swift │ │ ├── MiddleCenterLeftTwelfthCalculation.swift │ │ ├── MiddleCenterNinthCalculation.swift │ │ ├── MiddleCenterRightTwelfthCalculation.swift │ │ ├── MiddleLeftNinthCalculation.swift │ │ ├── MiddleLeftTwelfthCalculation.swift │ │ ├── MiddleRightNinthCalculation.swift │ │ ├── MiddleRightTwelfthCalculation.swift │ │ ├── MiddleVerticalThirdCalculation.swift │ │ ├── MoveLeftRightCalculation.swift │ │ ├── MoveUpDownCalculation.swift │ │ ├── NextPrevDisplayCalculation.swift │ │ ├── NinthsRepeated.swift │ │ ├── OrientationAware.swift │ │ ├── QuartersRepeated.swift │ │ ├── RepeatedExecutionsCalculation.swift │ │ ├── RepeatedExecutionsInThirdsCalculation.swift │ │ ├── RightTodoCalculation.swift │ │ ├── SecondFourthCalculation.swift │ │ ├── SixteenthsRepeated.swift │ │ ├── SixthsRepeated.swift │ │ ├── SpecifiedCalculation.swift │ │ ├── ThirdFourthCalculation.swift │ │ ├── TopCenterLeftEighthCalculation.swift │ │ ├── TopCenterLeftSixteenthCalculation.swift │ │ ├── TopCenterLeftTwelfthCalculation.swift │ │ ├── TopCenterNinthCalculation.swift │ │ ├── TopCenterRightEighthCalculation.swift │ │ ├── TopCenterRightSixteenthCalculation.swift │ │ ├── TopCenterRightTwelfthCalculation.swift │ │ ├── TopCenterSixthCalculation.swift │ │ ├── TopHalfCalculation.swift │ │ ├── TopLeftEighthCalculation.swift │ │ ├── TopLeftNinthCalculation.swift │ │ ├── TopLeftSixteenthCalculation.swift │ │ ├── TopLeftSixthCalculation.swift │ │ ├── TopLeftThirdCalculation.swift │ │ ├── TopLeftTwelfthCalculation.swift │ │ ├── TopRightEighthCalculation.swift │ │ ├── TopRightNinthCalculation.swift │ │ ├── TopRightSixteenthCalculation.swift │ │ ├── TopRightSixthCalculation.swift │ │ ├── TopRightThirdCalculation.swift │ │ ├── TopRightTwelfthCalculation.swift │ │ ├── TopVerticalThirdCalculation.swift │ │ ├── TopVerticalTwoThirdsCalculation.swift │ │ ├── TwelfthsRepeated.swift │ │ ├── UpperLeftCalculation.swift │ │ ├── UpperMiddleCenterLeftSixteenthCalculation.swift │ │ ├── UpperMiddleCenterRightSixteenthCalculation.swift │ │ ├── UpperMiddleLeftSixteenthCalculation.swift │ │ ├── UpperMiddleRightSixteenthCalculation.swift │ │ ├── UpperRightCalculation.swift │ │ └── WindowCalculation.swift │ ├── WindowHistory.swift │ ├── WindowManager.swift │ ├── WindowMover/ │ │ ├── BestEffortWindowMover.swift │ │ ├── CenteringFixedSizedWindowMover.swift │ │ ├── QuantizedWindowMover.swift │ │ ├── StandardWindowMover.swift │ │ └── WindowMover.swift │ └── mul.lproj/ │ └── Main.xcstrings ├── Rectangle.xcodeproj/ │ └── project.pbxproj ├── RectangleLauncher/ │ ├── AppDelegate.swift │ ├── Assets.xcassets/ │ │ ├── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj/ │ │ └── Main.storyboard │ ├── Info.plist │ ├── RectangleLauncher.entitlements │ ├── RectangleLauncherRelease.entitlements │ └── mul.lproj/ │ └── Main.xcstrings ├── RectangleTests/ │ ├── Info.plist │ └── RectangleTests.swift └── TerminalCommands.md
Condensed preview — 301 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,508K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 303,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: 'bug'\nassignees: ''\n\n---\n\n- [ ] This is"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 435,
"preview": "---\nname: Feature idea\nabout: Please use the Discussions tab to share a feature idea ⬆️\ntitle: ''\nlabels: 'enhancement'\n"
},
{
"path": ".github/funding.yml",
"chars": 50,
"preview": "github: rxhanson\ncustom: https://rectangleapp.com\n"
},
{
"path": ".github/workflows/build.yml",
"chars": 1329,
"preview": "name: Build\n\non: [push, pull_request]\n\npermissions: read-all\n\nenv:\n XCODE_PROJECT: \"Rectangle.xcodeproj\"\n XCODE_SCHEME"
},
{
"path": ".gitignore",
"chars": 416,
"preview": ".idea\n**/.DS_Store\n*/xcuserdata/\nxcuserdata/\n**.xcuserstate\n*.xcworkspace\nPods\n\n## Xcode per-user config\n*.mode1\n*.mode1"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3351,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 1198,
"preview": "# Contributing\n\n## Feature Requests\n\nRectangle is not accepting any new feature requests at this time, sorry. You can fi"
},
{
"path": "LICENSE",
"chars": 1150,
"preview": "MIT License\n\nCopyright (c) 2019-2025 Ryan Hanson\nBased on the Spectacle app, Copyright (c) 2017 Eric Czarny eczarny@gmai"
},
{
"path": "README.md",
"chars": 12142,
"preview": "# Rectangle\n\n[](https://github.com/"
},
{
"path": "Rectangle/AccessibilityAuthorization/AccessibilityAuthorization.swift",
"chars": 1562,
"preview": "//\n// AccessibilityAuthorization.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/11/19.\n// Copyright © 2019 Rya"
},
{
"path": "Rectangle/AccessibilityAuthorization/AccessibilityWindowController.swift",
"chars": 1376,
"preview": "//\n// AccessibilityWindow.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/13/19.\n// Copyright © 2019 Ryan Hanso"
},
{
"path": "Rectangle/AccessibilityElement.swift",
"chars": 15637,
"preview": "//\n// AccessibilityElement.swift\n// Rectangle, Ported from Spectacle, Combined with snippets from ModMove\n//\n// Creat"
},
{
"path": "Rectangle/AppDelegate.swift",
"chars": 27332,
"preview": "//\n// AppDelegate.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/11/19.\n// Copyright © 2019 Ryan Hanson. All r"
},
{
"path": "Rectangle/AppIcon.icon/icon.json",
"chars": 1286,
"preview": "{\n \"color-space-for-untagged-svg-colors\" : \"display-p3\",\n \"fill\" : {\n \"linear-gradient\" : [\n \"display-p3:0.368"
},
{
"path": "Rectangle/ApplicationToggle.swift",
"chars": 4433,
"preview": "//\n// ApplicationToggle.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/18/19.\n// Copyright © 2019 Ryan Hanson."
},
{
"path": "Rectangle/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 1284,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"mac016pts1x.png\",\n \"idiom\" : \"mac\",\n \"scale\" : \"1x\",\n \"size\" :"
},
{
"path": "Rectangle/Assets.xcassets/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "Rectangle/Assets.xcassets/StatusTemplate.imageset/Contents.json",
"chars": 425,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"RectangleStatusTemplate22.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/almostMaximizeTemplate.imageset/Contents.json",
"chars": 319,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"almostMaximizeTemplate.png\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/blEighthTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"blEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomCenterLeftSixteenthTemplate.imageset/Contents.json",
"chars": 331,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomCenterLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"s"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomCenterLeftTwelfthTemplate.imageset/Contents.json",
"chars": 329,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomCenterLeftTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sca"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomCenterNinthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomCenterNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomCenterRightSixteenthTemplate.imageset/Contents.json",
"chars": 332,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomCenterRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomCenterRightTwelfthTemplate.imageset/Contents.json",
"chars": 330,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomCenterRightTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sc"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomCenterSixthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomCenterSixthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomHalfTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"bottomHalfTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomLeftNinthTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomLeftNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomLeftSixteenthTemplate.imageset/Contents.json",
"chars": 325,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomLeftSixthTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomLeftSixthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomLeftTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"bottomLeftTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomLeftTwelfthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomLeftTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomRightNinthTemplate.imageset/Contents.json",
"chars": 322,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomRightNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomRightSixteenthTemplate.imageset/Contents.json",
"chars": 326,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomRightSixthTemplate.imageset/Contents.json",
"chars": 322,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomRightSixthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomRightTemplate.imageset/Contents.json",
"chars": 316,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"bottomRightTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomRightTwelfthTemplate.imageset/Contents.json",
"chars": 324,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomRightTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" :"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomThirdTemplate.imageset/Contents.json",
"chars": 317,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomThirdTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/bottomTwoThirdsTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"bottomTwoThirdsTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/brEighthTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"brEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/cblEighthTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"cblEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/cbrEighthTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"cbrEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerLeftFourthTemplate.imageset/Contents.json",
"chars": 322,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"centerLeftFourthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerRightFourthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"centerRightFourthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerTemplate.imageset/Contents.json",
"chars": 311,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"centerTemplate.png\",\n \"scale\" : \"1x\"\n },"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerThirdHorizontalTemplate.imageset/Contents.json",
"chars": 317,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"centerThirdTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerThirdTemplate.imageset/Contents.json",
"chars": 316,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"centerThirdTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerThreeFourthsTemplate.imageset/Contents.json",
"chars": 324,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"centerThreeFourthsTemplate.png\",\n \"scale\" :"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/centerTwoThirdsTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"centerTwoThirdsTemplate.png\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/ctlEighthTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"ctlEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/ctrEighthTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"ctrEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/firstThirdTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"firstThirdTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/firstThreeFourthsTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"firstThreeFourthsTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/firstTwoThirdsTemplate.imageset/Contents.json",
"chars": 319,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"firstTwoThirdsTemplate.png\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/halfWidthCenterTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"halfWidthCenterTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/largerWidthTemplate.imageset/Contents.json",
"chars": 317,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"largerWidthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lastThirdTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"lastThirdTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lastThreeFourthsTemplate.imageset/Contents.json",
"chars": 322,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"lastThreeFourthsTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lastTwoThirdsTemplate.imageset/Contents.json",
"chars": 318,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"lastTwoThirdsTemplate.png\",\n \"scale\" : \"1x\""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/leftFourthTemplate.imageset/Contents.json",
"chars": 316,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"leftFourthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/leftHalfTemplate.imageset/Contents.json",
"chars": 313,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"leftHalfTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lowerMiddleCenterLeftSixteenthTemplate.imageset/Contents.json",
"chars": 336,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"lowerMiddleCenterLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lowerMiddleCenterRightSixteenthTemplate.imageset/Contents.json",
"chars": 337,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"lowerMiddleCenterRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lowerMiddleLeftSixteenthTemplate.imageset/Contents.json",
"chars": 330,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"lowerMiddleLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sc"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/lowerMiddleRightSixteenthTemplate.imageset/Contents.json",
"chars": 331,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"lowerMiddleRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"s"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/makeLargerTemplate.imageset/Contents.json",
"chars": 315,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"makeLargerTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/makeSmallerTemplate.imageset/Contents.json",
"chars": 316,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"makeSmallerTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/maximizeHeightTemplate.imageset/Contents.json",
"chars": 319,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"maximizeHeightTemplate.png\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/maximizeTemplate.imageset/Contents.json",
"chars": 313,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"maximizeTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleCenterLeftTwelfthTemplate.imageset/Contents.json",
"chars": 329,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleCenterLeftTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sca"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleCenterNinthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleCenterNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleCenterRightTwelfthTemplate.imageset/Contents.json",
"chars": 330,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleCenterRightTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sc"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleLeftNinthTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleLeftNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleLeftTwelfthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleLeftTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleRightNinthTemplate.imageset/Contents.json",
"chars": 322,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleRightNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/middleRightTwelfthTemplate.imageset/Contents.json",
"chars": 324,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"middleRightTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" :"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/moveDownTemplate.imageset/Contents.json",
"chars": 313,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"moveDownTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/moveLeftTemplate.imageset/Contents.json",
"chars": 313,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"moveLeftTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/moveRightTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"moveRightTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/moveUpTemplate.imageset/Contents.json",
"chars": 311,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"moveUpTemplate.png\",\n \"scale\" : \"1x\"\n },"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/nextDisplayTemplate.imageset/Contents.json",
"chars": 316,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"nextDisplayTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/prevDisplayTemplate.imageset/Contents.json",
"chars": 316,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"prevDisplayTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/restoreTemplate.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"restoreTemplate.png\",\n \"scale\" : \"1x\"\n }"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/rightFourthTemplate.imageset/Contents.json",
"chars": 317,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"rightFourthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/rightHalfTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"rightHalfTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/smallerWidthTemplate.imageset/Contents.json",
"chars": 318,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"smallerWidthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/tlEighthTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"tlEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topCenterLeftSixteenthTemplate.imageset/Contents.json",
"chars": 328,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topCenterLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scal"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topCenterLeftTwelfthTemplate.imageset/Contents.json",
"chars": 326,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topCenterLeftTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topCenterNinthTemplate.imageset/Contents.json",
"chars": 320,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topCenterNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topCenterRightSixteenthTemplate.imageset/Contents.json",
"chars": 329,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topCenterRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sca"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topCenterRightTwelfthTemplate.imageset/Contents.json",
"chars": 327,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topCenterRightTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topCenterSixthTemplate.imageset/Contents.json",
"chars": 320,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topCenterSixthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topHalfTemplate.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"topHalfTemplate.png\",\n \"scale\" : \"1x\"\n }"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topLeftNinthTemplate.imageset/Contents.json",
"chars": 318,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topLeftNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topLeftSixteenthTemplate.imageset/Contents.json",
"chars": 322,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topLeftSixthTemplate.imageset/Contents.json",
"chars": 318,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topLeftSixthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topLeftTemplate.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"topLeftTemplate.png\",\n \"scale\" : \"1x\"\n }"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topLeftTwelfthTemplate.imageset/Contents.json",
"chars": 320,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topLeftTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topRightNinthTemplate.imageset/Contents.json",
"chars": 319,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topRightNinthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topRightSixteenthTemplate.imageset/Contents.json",
"chars": 323,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topRightSixthTemplate.imageset/Contents.json",
"chars": 319,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topRightSixthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\""
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topRightTemplate.imageset/Contents.json",
"chars": 313,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"topRightTemplate.png\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topRightTwelfthTemplate.imageset/Contents.json",
"chars": 321,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topRightTwelfthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topThirdTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topThirdTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/topTwoThirdsTemplate.imageset/Contents.json",
"chars": 318,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"topTwoThirdsTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/trEighthTemplate.imageset/Contents.json",
"chars": 314,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"trEighthTemplate.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/upperMiddleCenterLeftSixteenthTemplate.imageset/Contents.json",
"chars": 336,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"upperMiddleCenterLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/upperMiddleCenterRightSixteenthTemplate.imageset/Contents.json",
"chars": 337,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"upperMiddleCenterRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n "
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/upperMiddleLeftSixteenthTemplate.imageset/Contents.json",
"chars": 330,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"upperMiddleLeftSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"sc"
},
{
"path": "Rectangle/Assets.xcassets/WindowPositions/upperMiddleRightSixteenthTemplate.imageset/Contents.json",
"chars": 331,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"upperMiddleRightSixteenthTemplate.png\",\n \"idiom\" : \"universal\",\n \"s"
},
{
"path": "Rectangle/Assets.xcassets/keyboardToolbarTemplate.imageset/Contents.json",
"chars": 376,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"keyboardToolbarTemplateSmall.png\",\n \"idiom\" : \"universal\",\n \"scale\""
},
{
"path": "Rectangle/Assets.xcassets/snapAreaTemplate.imageset/Contents.json",
"chars": 362,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"snapAreaTemplateSmall.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\""
},
{
"path": "Rectangle/Assets.xcassets/square.and.arrow.down.imageset/Contents.json",
"chars": 388,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"square.and.arrow.down.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\""
},
{
"path": "Rectangle/Assets.xcassets/square.and.arrow.up.imageset/Contents.json",
"chars": 386,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"square.and.arrow.up.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n "
},
{
"path": "Rectangle/Assets.xcassets/toolbarSettingsTemplate.imageset/Contents.json",
"chars": 376,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"toolbarSettingsTemplate copy.png\",\n \"idiom\" : \"universal\",\n \"scale\""
},
{
"path": "Rectangle/Assets.xcassets/wallpaperTiger.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"wallpaperTiger.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n },"
},
{
"path": "Rectangle/Assets.xcassets/wallpaperTigerVertical.imageset/Contents.json",
"chars": 320,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"wallpaperTigerVertical.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x"
},
{
"path": "Rectangle/Base.lproj/Main.storyboard",
"chars": 510718,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" t"
},
{
"path": "Rectangle/CycleSize.swift",
"chars": 3112,
"preview": "//\n// CycleSize.swift\n// Rectangle\n//\n// Created by Eskil Gjerde Sviggum on 01/08/2024.\n// Copyright © 2024 Ryan Han"
},
{
"path": "Rectangle/Defaults.swift",
"chars": 18035,
"preview": "//\n// Defaults.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/14/19.\n// Copyright © 2019 Ryan Hanson. All righ"
},
{
"path": "Rectangle/Info.plist",
"chars": 1616,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Rectangle/InternetAccessPolicy.plist",
"chars": 779,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Rectangle/LaunchOnLogin.swift",
"chars": 911,
"preview": "//\n// LaunchOnLogin.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 2/20/23.\n// Copyright © 2023 Ryan Hanson. All"
},
{
"path": "Rectangle/Logging/LogViewer.storyboard",
"chars": 8015,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" t"
},
{
"path": "Rectangle/Logging/LogViewer.swift",
"chars": 3425,
"preview": "//\n// LogViewer.swift\n// Multitouch\n//\n// Created by Ryan Hanson on 8/6/19.\n// Copyright © 2019 Ryan Hanson. All rig"
},
{
"path": "Rectangle/MultiWindow/MultiWindowManager.swift",
"chars": 8712,
"preview": "//\n// MultiWindowManager.swift\n// Rectangle\n//\n// Created by Mikhail (Dirondin) Polubisok on 2/20/22.\n// Copyright ©"
},
{
"path": "Rectangle/MultiWindow/ReverseAllManager.swift",
"chars": 1246,
"preview": "//\n// TodoManager.swift\n// Rectangle\n//\n// Created by Charlie Harding on 7/25/21.\n// Copyright © 2021 Ryan Hanson. A"
},
{
"path": "Rectangle/Popover/MessageView.swift",
"chars": 1070,
"preview": "//\n// MessageView.swift\n// Multitouch\n//\n// Created by Ryan Hanson on 9/10/17.\n// Copyright © 2017-2018 BrassMonkery"
},
{
"path": "Rectangle/Popover/MessageView.xib",
"chars": 2813,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion"
},
{
"path": "Rectangle/PrefsWindow/Config.swift",
"chars": 5254,
"preview": "//\n// Config.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 12/15/20.\n// Copyright © 2020 Ryan Hanson. All right"
},
{
"path": "Rectangle/PrefsWindow/PrefsViewController.swift",
"chars": 7089,
"preview": "//\n// PrefsViewController.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/18/19.\n// Copyright © 2019 Ryan Hanso"
},
{
"path": "Rectangle/PrefsWindow/SettingsViewController.swift",
"chars": 67550,
"preview": "//\n// SettingsViewController.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/24/19.\n// Copyright © 2019 Ryan Ha"
},
{
"path": "Rectangle/PrefsWindow/SnapAreaViewController.swift",
"chars": 7882,
"preview": "//\n// SnapAreaViewController.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/13/22.\n// Copyright © 2022 Ryan Ha"
},
{
"path": "Rectangle/Rectangle-Bridging-Header.h",
"chars": 208,
"preview": "//\n// Use this file to import your target's public headers that you would like to expose to Swift.\n//\n\n#import <AppKit/"
},
{
"path": "Rectangle/Rectangle.entitlements",
"chars": 181,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Rectangle/RectangleRelease.entitlements",
"chars": 181,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Rectangle/RectangleStatusItem.swift",
"chars": 1711,
"preview": "//\n// RectangleStatusItem.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/11/19.\n// Copyright © 2019 Ryan Hanso"
},
{
"path": "Rectangle/ScreenDetection.swift",
"chars": 8294,
"preview": "//\n// ScreenDetection.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/12/19.\n// Copyright © 2019 Ryan Hanson. A"
},
{
"path": "Rectangle/ShortcutManager.swift",
"chars": 4954,
"preview": "//\n// ShortcutManager.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/12/19.\n// Copyright © 2019 Ryan Hanson. A"
},
{
"path": "Rectangle/Snapping/CompoundSnapArea/CompoundSnapArea.swift",
"chars": 5327,
"preview": "//\n// CompoundSnapArea.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/23/22.\n// Copyright © 2022 Ryan Hanson. "
},
{
"path": "Rectangle/Snapping/CompoundSnapArea/EighthsCompoundCalculation.swift",
"chars": 4092,
"preview": "//\n// EighthsCompoundCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n\nimpo"
},
{
"path": "Rectangle/Snapping/CompoundSnapArea/FourthsCompoundCalculation.swift",
"chars": 2402,
"preview": "//\n// FourthsCompoundCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/24/22.\n// Copyright © 2022 Rya"
},
{
"path": "Rectangle/Snapping/CompoundSnapArea/HalvesCompoundCalculation.swift",
"chars": 4564,
"preview": "//\n// HalvesCompoundCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/23/22.\n// Copyright © 2022 Ryan"
},
{
"path": "Rectangle/Snapping/CompoundSnapArea/SixthsCompoundCalculation.swift",
"chars": 3095,
"preview": "//\n// SixthsCompoundCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/23/22.\n// Copyright © 2022 Ryan"
},
{
"path": "Rectangle/Snapping/CompoundSnapArea/ThirdsCompoundCalculation.swift",
"chars": 3804,
"preview": "//\n// ThirdsCompoundCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/23/22.\n// Copyright © 2022 Ryan"
},
{
"path": "Rectangle/Snapping/FootprintWindow.swift",
"chars": 2958,
"preview": "//\n// FootprintWindow.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 10/17/20.\n// Copyright © 2020 Ryan Hanson. "
},
{
"path": "Rectangle/Snapping/SnapAreaModel.swift",
"chars": 5877,
"preview": "//\n// SnapAreaModel.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/19/22.\n// Copyright © 2022 Ryan Hanson. All"
},
{
"path": "Rectangle/Snapping/SnappingManager.swift",
"chars": 19396,
"preview": "//\n// SnappingManager.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 9/4/19.\n// Copyright © 2019 Ryan Hanson. Al"
},
{
"path": "Rectangle/SubsequentExecutionMode.swift",
"chars": 1773,
"preview": "//\n// SubsequentExecutionMode.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 8/15/19.\n// Copyright © 2019 Ryan H"
},
{
"path": "Rectangle/TitleBarManager.swift",
"chars": 3362,
"preview": "//\n// TitleBarManager.swift\n// Rectangle\n//\n// Copyright © 2023 Ryan Hanson. All rights reserved.\n//\n\nimport Foundati"
},
{
"path": "Rectangle/TodoMode/TodoManager.swift",
"chars": 10810,
"preview": "//\n// TodoManager.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 1/18/21.\n// Copyright © 2021 Ryan Hanson. All r"
},
{
"path": "Rectangle/Utilities/AXExtension.swift",
"chars": 3351,
"preview": "//\n// AXExtension.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation\n\n"
},
{
"path": "Rectangle/Utilities/AlertUtil.swift",
"chars": 1422,
"preview": "//\n// AlertUtil.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 4/26/20.\n// Copyright © 2020 Ryan Hanson. All rig"
},
{
"path": "Rectangle/Utilities/CFExtension.swift",
"chars": 548,
"preview": "//\n// CFExtension.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation\n\n"
},
{
"path": "Rectangle/Utilities/CGExtension.swift",
"chars": 948,
"preview": "//\n// CGExtension.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation\n\n"
},
{
"path": "Rectangle/Utilities/CUtil.swift",
"chars": 615,
"preview": "//\n// CUtil.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/12/19.\n// Copyright © 2019 Ryan Hanson. All rights "
},
{
"path": "Rectangle/Utilities/Debounce.swift",
"chars": 532,
"preview": "//\n// Debounce.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 10/7/21.\n// Copyright © 2021 Ryan Hanson. All righ"
},
{
"path": "Rectangle/Utilities/DispatchTimeExtension.swift",
"chars": 226,
"preview": "//\n// DispatchTimeExtension.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Fo"
},
{
"path": "Rectangle/Utilities/EventMonitor.swift",
"chars": 3237,
"preview": "//\n// EventMonitor.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 9/4/19.\n// Copyright © 2019 Ryan Hanson. All r"
},
{
"path": "Rectangle/Utilities/MASShortcutMigration.swift",
"chars": 1015,
"preview": "//\n// MASShortcutMigration.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 12/22/20.\n// Copyright © 2020 Ryan Han"
},
{
"path": "Rectangle/Utilities/MacTilingDefaults.swift",
"chars": 4729,
"preview": "//\n// MacTilingDefaults.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n\nimport Founda"
},
{
"path": "Rectangle/Utilities/NSImageExtension.swift",
"chars": 1308,
"preview": "//\n// NSImageExtension.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 4/9/21.\n// Copyright © 2021 Ryan Hanson. A"
},
{
"path": "Rectangle/Utilities/NotificationExtension.swift",
"chars": 1828,
"preview": "//\n// NotificationExtension.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 12/23/20.\n// Copyright © 2020 Ryan Ha"
},
{
"path": "Rectangle/Utilities/RunLoopThread.swift",
"chars": 937,
"preview": "//\n// RunLoopThread.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation"
},
{
"path": "Rectangle/Utilities/SequenceExtension.swift",
"chars": 495,
"preview": "//\n// SequenceExtension.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Founda"
},
{
"path": "Rectangle/Utilities/StageUtil.swift",
"chars": 3249,
"preview": "//\n// StageUtil.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation\n\ncl"
},
{
"path": "Rectangle/Utilities/StringExtension.swift",
"chars": 384,
"preview": "//\n// StringExtension.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n\nimport Foundati"
},
{
"path": "Rectangle/Utilities/TimeoutCache.swift",
"chars": 2432,
"preview": "//\n// TimeoutCache.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation\n"
},
{
"path": "Rectangle/Utilities/WindowUtil.swift",
"chars": 2441,
"preview": "//\n// WindowUtil.swift\n// Rectangle\n//\n// Copyright © 2022 Ryan Hanson. All rights reserved.\n//\n\nimport Foundation\n\nc"
},
{
"path": "Rectangle/WelcomeWindow/WelcomeViewController.swift",
"chars": 859,
"preview": "//\n// WelcomeViewController.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 4/9/20.\n// Copyright © 2020 Ryan Hans"
},
{
"path": "Rectangle/WindowAction.swift",
"chars": 55786,
"preview": "//\n// WindowAction.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 6/12/19.\n// Copyright © 2019 Ryan Hanson. All "
},
{
"path": "Rectangle/WindowActionCategory.swift",
"chars": 2373,
"preview": "//\n// WindowActionCategory.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 10/3/20.\n// Copyright © 2020 Ryan Hans"
},
{
"path": "Rectangle/WindowCalculation/AlmostMaximizeCalculation.swift",
"chars": 1528,
"preview": "//\n// AlmostMaximizeCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 7/26/19.\n// Copyright © 2019 Ryan"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterLeftEighthCalculation.swift",
"chars": 1981,
"preview": "//\n// BottomCenterLeftEighthCalculation.swift\n// Rectangle\n//\n// Created by Johannes Trussell Rasch on 2022-02-18.\n//"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterLeftSixteenthCalculation.swift",
"chars": 1867,
"preview": "//\n// BottomCenterLeftSixteenthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterLeftTwelfthCalculation.swift",
"chars": 1842,
"preview": "//\n// BottomCenterLeftTwelfthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterNinthCalculation.swift",
"chars": 1898,
"preview": "//\n// BottomCenterNinthCalculation.swift\n// Rectangle\n//\n// Created by Daniel Schultz on 1/2/22.\n// Copyright © 2022"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterRightEighthCalculation.swift",
"chars": 1935,
"preview": "//\n// BottomCenterRightEighthCalculation.swift\n// Rectangle\n//\n// Created by Johannes Trussell Rasch on 2022-02-18.\n/"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterRightSixteenthCalculation.swift",
"chars": 1880,
"preview": "//\n// BottomCenterRightSixteenthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserve"
},
{
"path": "Rectangle/WindowCalculation/BottomCenterRightTwelfthCalculation.swift",
"chars": 1895,
"preview": "//\n// BottomCenterRightTwelfthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved."
},
{
"path": "Rectangle/WindowCalculation/BottomCenterSixthCalculation.swift",
"chars": 3901,
"preview": "//\n// BottomCenterCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 9/16/20.\n// Copyright © 2020 Ryan H"
},
{
"path": "Rectangle/WindowCalculation/BottomHalfCalculation.swift",
"chars": 1099,
"preview": "//\n// BottomHalfCalculation.swift\n// Rectangle, Ported from Spectacle\n//\n// Created by Ryan Hanson on 6/14/19.\n// Co"
},
{
"path": "Rectangle/WindowCalculation/BottomLeftEighthCalculation.swift",
"chars": 1925,
"preview": "//\n// BottomLeftEighthCalculation.swift\n// Rectangle\n//\n// Created by Johannes Trussell Rasch on 2022-02-18.\n// Copy"
},
{
"path": "Rectangle/WindowCalculation/BottomLeftNinthCalculation.swift",
"chars": 1862,
"preview": "//\n// BottomLeftNinthCalculation.swift\n// Rectangle\n//\n// Created by Daniel Schultz on 1/2/22.\n// Copyright © 2022 R"
},
{
"path": "Rectangle/WindowCalculation/BottomLeftSixteenthCalculation.swift",
"chars": 1811,
"preview": "//\n// BottomLeftSixteenthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n\n"
},
{
"path": "Rectangle/WindowCalculation/BottomLeftSixthCalculation.swift",
"chars": 1778,
"preview": "//\n// BottomLeftSixthCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 9/16/20.\n// Copyright © 2020 Rya"
},
{
"path": "Rectangle/WindowCalculation/BottomLeftThirdCalculation.swift",
"chars": 1883,
"preview": "//\n// BottomLeftThirdCalculation.swift\n// Rectangle\n//\n// Created by Daniel Schultz on 1/2/22.\n// Copyright © 2022 R"
},
{
"path": "Rectangle/WindowCalculation/BottomLeftTwelfthCalculation.swift",
"chars": 1842,
"preview": "//\n// BottomLeftTwelfthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n\nim"
},
{
"path": "Rectangle/WindowCalculation/BottomRightEighthCalculation.swift",
"chars": 1918,
"preview": "//\n// BottomRightEighthCalculation.swift\n// Rectangle\n//\n// Created by Johannes Trussell Rasch on 2022-02-18.\n// Cop"
},
{
"path": "Rectangle/WindowCalculation/BottomRightNinthCalculation.swift",
"chars": 1951,
"preview": "//\n// BottomRightNinthCalculation.swift\n// Rectangle\n//\n// Created by Daniel Schultz on 1/2/22.\n// Copyright © 2022 "
},
{
"path": "Rectangle/WindowCalculation/BottomRightSixteenthCalculation.swift",
"chars": 1850,
"preview": "//\n// BottomRightSixteenthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n"
},
{
"path": "Rectangle/WindowCalculation/BottomRightSixthCalculation.swift",
"chars": 1992,
"preview": "//\n// BottomRightSixthCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 9/16/20.\n// Copyright © 2020 Ry"
},
{
"path": "Rectangle/WindowCalculation/BottomRightThirdCalculation.swift",
"chars": 1957,
"preview": "//\n// BottomRightThirdCalculation.swift\n// Rectangle\n//\n// Created by Daniel Schultz on 1/2/22.\n// Copyright © 2022 "
},
{
"path": "Rectangle/WindowCalculation/BottomRightTwelfthCalculation.swift",
"chars": 1900,
"preview": "//\n// BottomRightTwelfthCalculation.swift\n// Rectangle\n//\n// Copyright © 2024 Ryan Hanson. All rights reserved.\n//\n\ni"
},
{
"path": "Rectangle/WindowCalculation/BottomVerticalThirdCalculation.swift",
"chars": 1766,
"preview": "//\n// BottomVerticalThirdCalculation.swift\n// Rectangle\n//\n// Created on 12/22/25.\n//\n\nimport Foundation\n\nclass Botto"
},
{
"path": "Rectangle/WindowCalculation/BottomVerticalTwoThirdsCalculation.swift",
"chars": 1105,
"preview": "//\n// BottomVerticalTwoThirdsCalculation.swift\n// Rectangle\n//\n// Created on 12/22/25.\n//\n\nimport Foundation\n\nclass B"
},
{
"path": "Rectangle/WindowCalculation/CenterCalculation.swift",
"chars": 2325,
"preview": "//\n// CenterCalculation.swift\n// Rectangle, Ported from Spectacle\n//\n// Created by Ryan Hanson on 6/14/19.\n// Copyri"
},
{
"path": "Rectangle/WindowCalculation/CenterHalfCalculation.swift",
"chars": 2540,
"preview": "//\n// AlmostMaximizeCalculation.swift\n// Rectangle\n//\n// Created by Ryan Hanson on 7/26/19.\n// Copyright © 2019 Ryan"
}
]
// ... and 101 more files (download for full content)
About this extraction
This page contains the full source code of the rxhanson/Rectangle GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 301 files (3.0 MB), approximately 817.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.