diff --git a/Loop/Extensions/CGGeometry+Extensions.swift b/Loop/Extensions/CGGeometry+Extensions.swift index 7c57ae17..503673bd 100644 --- a/Loop/Extensions/CGGeometry+Extensions.swift +++ b/Loop/Extensions/CGGeometry+Extensions.swift @@ -65,19 +65,28 @@ extension CGRect { height: self.height) } - mutating func inset(_ side: Edge, amount: CGFloat) { - switch side { - case .top: - self.origin.y += amount - self.size.height -= amount - case .leading: - self.origin.x += amount - self.size.width -= amount - case .bottom: - self.size.height -= amount - case .trailing: - self.size.width -= amount + func padding(_ sides: Edge.Set, _ amount: CGFloat) -> CGRect { + var rect = self + + if sides.contains(.top) { + rect.origin.y += amount + rect.size.height -= amount + } + + if sides.contains(.bottom) { + rect.size.height -= amount + } + + if sides.contains(.leading) { + rect.origin.x += amount + rect.size.width -= amount + } + + if sides.contains(.trailing) { + rect.size.width -= amount } + + return rect } func approximatelyEqual(to rect: CGRect, tolerance: CGFloat = 10) -> Bool { diff --git a/Loop/Window Management/WindowAction.swift b/Loop/Window Management/WindowAction.swift index 9f3fcf5a..906b9bb5 100644 --- a/Loop/Window Management/WindowAction.swift +++ b/Loop/Window Management/WindowAction.swift @@ -324,7 +324,10 @@ extension WindowAction { } if self.direction == .macOSCenter { - let yOffset = WindowEngine.getMacOSCenterYOffset(previewHeight, screenHeight: parentHeight) + let yOffset = WindowEngine.getMacOSCenterYOffset( + previewHeight - (Defaults[.windowPadding] * 2), + screenHeight: parentHeight + ) yLocation = (parentHeight / 2) - (previewHeight / 2) + yOffset } @@ -347,6 +350,7 @@ extension WindowAction { if self.direction == .center || self.direction == .macOSCenter, let window = window { width = window.frame.width + width += Defaults[.windowPadding] * 2 } return width @@ -368,6 +372,7 @@ extension WindowAction { if self.direction == .center || self.direction == .macOSCenter, let window = window { height = window.frame.height + height += Defaults[.windowPadding] * 2 } return height diff --git a/Loop/Window Management/WindowEngine.swift b/Loop/Window Management/WindowEngine.swift index 7532fc5b..7aa6b8af 100644 --- a/Loop/Window Management/WindowEngine.swift +++ b/Loop/Window Management/WindowEngine.swift @@ -289,19 +289,40 @@ struct WindowEngine { /// - direction: The direction the window WILL be resized to /// - Returns: CGRect with padding applied private static func applyPadding(_ windowFrame: CGRect, _ screenFrame: CGRect, _ action: WindowAction) -> CGRect { - var paddedFrame = windowFrame + let padding = Defaults[.windowPadding] + let halfPadding = Defaults[.windowPadding] / 2 - let topPaddingDivisor: CGFloat = windowFrame.minY.approximatelyEquals(to: screenFrame.minY) ? 1 : 2 - let bottomPaddingDivisor: CGFloat = windowFrame.maxY.approximatelyEquals(to: screenFrame.maxY) ? 1 : 2 - let leadingPaddingDivisor: CGFloat = windowFrame.minX.approximatelyEquals(to: screenFrame.minX) ? 1 : 2 - let trailingPaddingDivisor: CGFloat = windowFrame.maxX.approximatelyEquals(to: screenFrame.maxX) ? 1 : 2 + let paddedScreenFrame = screenFrame.padding(.all, padding) + var paddedWindowFrame = windowFrame.intersection(paddedScreenFrame) - paddedFrame.inset(.top, amount: Defaults[.windowPadding] / topPaddingDivisor) - paddedFrame.inset(.bottom, amount: Defaults[.windowPadding] / bottomPaddingDivisor) - paddedFrame.inset(.leading, amount: Defaults[.windowPadding] / leadingPaddingDivisor) - paddedFrame.inset(.trailing, amount: Defaults[.windowPadding] / trailingPaddingDivisor) + if action.direction == .macOSCenter, + windowFrame.height >= paddedScreenFrame.height { - return paddedFrame + paddedWindowFrame.origin.y = paddedScreenFrame.minY + paddedWindowFrame.size.height = paddedScreenFrame.height + } + + if action.direction == .center || action.direction == .macOSCenter { + return paddedWindowFrame + } + + if paddedWindowFrame.minX != paddedScreenFrame.minX { + paddedWindowFrame = paddedWindowFrame.padding(.leading, halfPadding) + } + + if paddedWindowFrame.maxX != paddedScreenFrame.maxX { + paddedWindowFrame = paddedWindowFrame.padding(.trailing, halfPadding) + } + + if paddedWindowFrame.minY != paddedScreenFrame.minY { + paddedWindowFrame = paddedWindowFrame.padding(.top, halfPadding) + } + + if paddedWindowFrame.maxY != paddedScreenFrame.maxY { + paddedWindowFrame = paddedWindowFrame.padding(.bottom, halfPadding) + } + + return paddedWindowFrame } /// Will move a window back onto the screen. To be run AFTER a window has been resized.