diff --git a/Rectangle/WindowAction.swift b/Rectangle/WindowAction.swift index 19fee3c8..06009261 100644 --- a/Rectangle/WindowAction.swift +++ b/Rectangle/WindowAction.swift @@ -92,13 +92,16 @@ enum WindowAction: Int, Codable { halveHeightUp = 76, halveHeightDown = 77, halveWidthLeft = 78, - halveWidthRight = 79 + halveWidthRight = 79, + largerWidth = 80, + smallerWidth = 81 // Order matters here - it's used in the menu static let active = [leftHalf, rightHalf, centerHalf, topHalf, bottomHalf, topLeft, topRight, bottomLeft, bottomRight, firstThird, centerThird, lastThird, firstTwoThirds, lastTwoThirds, - maximize, almostMaximize, maximizeHeight, smaller, larger, center, centerProminently, restore, + maximize, almostMaximize, maximizeHeight, larger, smaller, largerWidth, smallerWidth, + center, centerProminently, restore, nextDisplay, previousDisplay, moveLeft, moveRight, moveUp, moveDown, firstFourth, secondFourth, thirdFourth, lastFourth, firstThreeFourths, lastThreeFourths, @@ -225,6 +228,8 @@ enum WindowAction: Int, Codable { case .rightTodo: return "rightTodo" case .cascadeActiveApp: return "cascadeActiveApp" case .centerProminently: return "centerProminently" + case .largerWidth: return "largerWidth" + case .smallerWidth: return "smallerWidth" } } @@ -361,7 +366,7 @@ enum WindowAction: Int, Codable { return nil case .specified, .reverseAll, .tileAll, .cascadeAll, .leftTodo, .rightTodo, .cascadeActiveApp: return nil - case .centerProminently: + case .centerProminently, .largerWidth, .smallerWidth: return nil } @@ -398,7 +403,7 @@ enum WindowAction: Int, Codable { var isDragSnappable: Bool { switch self { - case .restore, .previousDisplay, .nextDisplay, .moveUp, .moveDown, .moveLeft, .moveRight, .specified, .reverseAll, .tileAll, .cascadeAll, .smaller, .larger, .cascadeActiveApp, + case .restore, .previousDisplay, .nextDisplay, .moveUp, .moveDown, .moveLeft, .moveRight, .specified, .reverseAll, .tileAll, .cascadeAll, .larger, .smaller, .largerWidth, .smallerWidth, .cascadeActiveApp, // Ninths .topLeftNinth, .topCenterNinth, .topRightNinth, .middleLeftNinth, .middleCenterNinth, .middleRightNinth, .bottomLeftNinth, .bottomCenterNinth, .bottomRightNinth, // Corner thirds @@ -537,6 +542,8 @@ enum WindowAction: Int, Codable { case .rightTodo: return NSImage() case .cascadeActiveApp: return NSImage() case .centerProminently: return NSImage() + case .largerWidth: return NSImage() + case .smallerWidth: return NSImage() } } @@ -579,7 +586,7 @@ enum WindowAction: Int, Codable { return Defaults.applyGapsToMaximize.userDisabled ? .none : .both; case .maximizeHeight: return Defaults.applyGapsToMaximizeHeight.userDisabled ? .none : .vertical; - case .almostMaximize, .previousDisplay, .nextDisplay, .larger, .smaller, .center, .centerProminently, .restore, .specified, .reverseAll, .tileAll, .cascadeAll, .cascadeActiveApp: + case .almostMaximize, .previousDisplay, .nextDisplay, .larger, .smaller, .largerWidth, .smallerWidth, .center, .centerProminently, .restore, .specified, .reverseAll, .tileAll, .cascadeAll, .cascadeActiveApp: return .none } } diff --git a/Rectangle/WindowCalculation/ChangeSizeCalculation.swift b/Rectangle/WindowCalculation/ChangeSizeCalculation.swift index baf877f2..3df9389a 100644 --- a/Rectangle/WindowCalculation/ChangeSizeCalculation.swift +++ b/Rectangle/WindowCalculation/ChangeSizeCalculation.swift @@ -25,33 +25,62 @@ class ChangeSizeCalculation: WindowCalculation, ChangeWindowDimensionCalculation } override func calculateRect(_ params: RectCalculationParameters) -> RectResult { - let sizeOffset: CGFloat = params.action == .smaller ? -sizeOffsetAbs : sizeOffsetAbs + + let sizeOffset: CGFloat + switch params.action { + case .larger, .largerWidth: + sizeOffset = sizeOffsetAbs + case .smaller, .smallerWidth: + sizeOffset = -sizeOffsetAbs + default: + sizeOffset = 0 + } let visibleFrameOfScreen = params.visibleFrameOfScreen let window = params.window + // Calculate Width + var resizedWindowRect = window.rect - resizedWindowRect.size.width = resizedWindowRect.width + sizeOffset - resizedWindowRect.origin.x = resizedWindowRect.minX - floor(sizeOffset / 2.0) - - if curtainChangeSize { - resizedWindowRect = againstLeftAndRightScreenEdges(originalWindowRect: window.rect, resizedWindowRect: resizedWindowRect, visibleFrameOfScreen: visibleFrameOfScreen) - } - if resizedWindowRect.width >= visibleFrameOfScreen.width { - resizedWindowRect.size.width = visibleFrameOfScreen.width - } - resizedWindowRect.size.height = resizedWindowRect.height + sizeOffset - resizedWindowRect.origin.y = resizedWindowRect.minY - floor(sizeOffset / 2.0) - - if curtainChangeSize { - resizedWindowRect = againstTopAndBottomScreenEdges(originalWindowRect: window.rect, resizedWindowRect: resizedWindowRect, visibleFrameOfScreen: visibleFrameOfScreen) + if [.larger, .smaller, .largerWidth, .smallerWidth].contains(params.action) { + resizedWindowRect.size.width = resizedWindowRect.width + sizeOffset + resizedWindowRect.origin.x = resizedWindowRect.minX - floor(sizeOffset / 2.0) + + if curtainChangeSize { + resizedWindowRect = againstLeftAndRightScreenEdges( + originalWindowRect: window.rect, + resizedWindowRect: resizedWindowRect, + visibleFrameOfScreen: visibleFrameOfScreen + ) + } + + if resizedWindowRect.width >= visibleFrameOfScreen.width { + resizedWindowRect.size.width = visibleFrameOfScreen.width + } } - - if resizedWindowRect.height >= visibleFrameOfScreen.height { - resizedWindowRect.size.height = visibleFrameOfScreen.height - resizedWindowRect.origin.y = params.window.rect.minY + + // Calculate Height + + if [.larger, .smaller].contains(params.action) { + resizedWindowRect.size.height = resizedWindowRect.height + sizeOffset + resizedWindowRect.origin.y = resizedWindowRect.minY - floor(sizeOffset / 2.0) + + if curtainChangeSize { + resizedWindowRect = againstTopAndBottomScreenEdges( + originalWindowRect: window.rect, + resizedWindowRect: resizedWindowRect, + visibleFrameOfScreen: visibleFrameOfScreen + ) + } + + if resizedWindowRect.height >= visibleFrameOfScreen.height { + resizedWindowRect.size.height = visibleFrameOfScreen.height + resizedWindowRect.origin.y = params.window.rect.minY + } } + + if againstAllScreenEdges(windowRect: window.rect, visibleFrameOfScreen: visibleFrameOfScreen) && (sizeOffset < 0) { resizedWindowRect.size.width = params.window.rect.width + sizeOffset resizedWindowRect.origin.x = params.window.rect.origin.x - floor(sizeOffset / 2.0) @@ -59,9 +88,10 @@ class ChangeSizeCalculation: WindowCalculation, ChangeWindowDimensionCalculation resizedWindowRect.origin.y = params.window.rect.origin.y - floor(sizeOffset / 2.0) } - if params.action == .smaller, resizedWindowRectIsTooSmall(windowRect: resizedWindowRect, visibleFrameOfScreen: visibleFrameOfScreen) { + if [.smaller, .smallerWidth].contains(params.action), resizedWindowRectIsTooSmall(windowRect: resizedWindowRect, visibleFrameOfScreen: visibleFrameOfScreen) { resizedWindowRect = window.rect } + return RectResult(resizedWindowRect) } diff --git a/Rectangle/WindowCalculation/WindowCalculation.swift b/Rectangle/WindowCalculation/WindowCalculation.swift index 581b208c..fcfbc3a1 100644 --- a/Rectangle/WindowCalculation/WindowCalculation.swift +++ b/Rectangle/WindowCalculation/WindowCalculation.swift @@ -193,6 +193,8 @@ class WindowCalculationFactory { .nextDisplay: nextPrevDisplayCalculation, .larger: changeSizeCalculation, .smaller: changeSizeCalculation, + .largerWidth: changeSizeCalculation, + .smallerWidth: changeSizeCalculation, .bottomHalf: bottomHalfCalculation, .topHalf: topHalfCalculation, .center: centerCalculation, diff --git a/TerminalCommands.md b/TerminalCommands.md index 314e92fd..42b127db 100644 --- a/TerminalCommands.md +++ b/TerminalCommands.md @@ -23,6 +23,7 @@ The preferences window is purposefully slim, but there's a lot that can be modif - [Make Smaller limits](#make-smaller-limits) - [Make Smaller/Make Larger size increments](#make-smallermake-larger-size-increments) - [Make Smaller/Make Larger "curtain resize" with gaps](#make-smallermake-larger-curtain-resize-with-gaps) +- [Make Smaller/Make Larger width only](#make-smallermake-larger-width-only) - [Disabling window restore when moving windows](#disabling-window-restore-when-moving-windows) - [Changing the margin for the snap areas](#changing-the-margin-for-the-snap-areas) - [Setting gaps at the screen edges](#setting-gaps-at-the-screen-edges) @@ -333,6 +334,17 @@ By default, windows touching the edge of the screen will keep those shared edges defaults write com.knollsoft.Rectangle curtainChangeSize -int 2 ``` +## Make Smaller/Make Larger width only + +By default, "Make Smaller" and "Make Larger" change both, the window height and the window width. If you only want to change the window width without changing window height, configure shortcuts for the _largerWidth_ and _smallerWidth_ commands. + +For example, if you want to assign `ctrl option ]` to _largerWidth_ and `ctrl option [` to _smallerWidth_, the commands would be: + +```bash +defaults write com.knollsoft.Rectangle largerWidth -dict-add keyCode -float 30 modifierFlags -float 786432 +defaults write com.knollsoft.Rectangle smallerWidth -dict-add keyCode -float 33 modifierFlags -float 786432 +``` + ## Disabling window restore when moving windows ```bash