From 185b01f0199b6a64f44f76a8348db2ba079c6151 Mon Sep 17 00:00:00 2001 From: Kai Azim <68963405+MrKai77@users.noreply.github.com> Date: Thu, 31 Aug 2023 18:02:18 -0600 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20Add=20function=20to=20add=20pad?= =?UTF-8?q?ding=20to=20windows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Loop/Helpers/WindowDirection.swift | 25 +++++++++++++++ Loop/Helpers/WindowEngine.swift | 50 ++++++++++++++++++++++++------ 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/Loop/Helpers/WindowDirection.swift b/Loop/Helpers/WindowDirection.swift index e405ebb6..dd11480c 100644 --- a/Loop/Helpers/WindowDirection.swift +++ b/Loop/Helpers/WindowDirection.swift @@ -127,4 +127,29 @@ enum WindowDirection: CaseIterable { default: [[]] } } + + var sidesThatTouchScreen: [Edge] { + switch self { + case .maximize: [.top, .bottom, .leading, .trailing] + case .topHalf: [.top, .leading, .trailing] + case .rightHalf: [.top, .bottom, .trailing] + case .bottomHalf: [.bottom, .leading, .trailing] + case .leftHalf: [.top, .bottom, .leading] + case .topLeftQuarter: [.top, .leading] + case .topRightQuarter: [.top, .trailing] + case .bottomRightQuarter: [.bottom, .trailing] + case .bottomLeftQuarter: [.bottom, .leading] + case .rightThird: [.top, .bottom, .trailing] + case .rightTwoThirds: [.top, .bottom, .trailing] + case .horizontalCenterThird: [.top, .bottom] + case .leftThird: [.top, .bottom, .leading] + case .leftTwoThirds: [.top, .bottom, .leading] + case .topThird: [.top, .leading, .trailing] + case .topTwoThirds: [.top, .leading, .trailing] + case .verticalCenterThird: [.leading, .trailing] + case .bottomThird: [.bottom, .leading, .trailing] + case .bottomTwoThirds: [.bottom, .leading, .trailing] + default: [] + } + } } diff --git a/Loop/Helpers/WindowEngine.swift b/Loop/Helpers/WindowEngine.swift index 590c0fad..685a2e7c 100644 --- a/Loop/Helpers/WindowEngine.swift +++ b/Loop/Helpers/WindowEngine.swift @@ -44,17 +44,19 @@ struct WindowEngine { let windowFrame = getRect(element: window) guard let screenFrame = getScreenFrame(screen: screen), - let newWindowFrame = generateWindowFrame(windowFrame, screenFrame, direction) - else { return } + let windowFrame = generateWindowFrame(windowFrame, screenFrame, direction) else { return } - self.setPosition(element: window, position: newWindowFrame.origin) - self.setSize(element: window, size: newWindowFrame.size) + let windowFrameWithPadding = applyPadding(windowFrame, direction) - if self.getRect(element: window) != newWindowFrame { + self.setPosition(element: window, position: windowFrameWithPadding.origin) + self.setSize(element: window, size: windowFrameWithPadding.size) + + if self.getRect(element: window) != windowFrameWithPadding { self.handleSizeConstrainedWindow( element: window, windowFrame: self.getRect(element: window), - screenFrame: screenFrame + screenFrame: screenFrame, + direction: direction ) } @@ -194,7 +196,19 @@ struct WindowEngine { } } - private func handleSizeConstrainedWindow(element: AXUIElement, windowFrame: CGRect, screenFrame: CGRect) { + private func applyPadding(_ windowFrame: CGRect, _ direction: WindowDirection) -> CGRect { + var paddingAppliedRect = windowFrame + for side in [Edge.top, Edge.bottom, Edge.leading, Edge.trailing] { + if direction.sidesThatTouchScreen.contains(side) { + paddingAppliedRect.inset(side, amount: Defaults[.windowPadding]) + } else { + paddingAppliedRect.inset(side, amount: Defaults[.windowPadding] / 2) + } + } + return paddingAppliedRect + } + + private func handleSizeConstrainedWindow(element: AXUIElement, windowFrame: CGRect, screenFrame: CGRect, direction: WindowDirection) { // If the window is fully shown on the screen if (windowFrame.maxX <= screenFrame.maxX) && (windowFrame.maxY <= screenFrame.maxY) { @@ -205,13 +219,31 @@ struct WindowEngine { var fixedWindowFrame = windowFrame if fixedWindowFrame.maxX > screenFrame.maxX { - fixedWindowFrame.origin.x = screenFrame.maxX - fixedWindowFrame.width + fixedWindowFrame.origin.x = screenFrame.maxX - fixedWindowFrame.width - Defaults[.windowPadding] } if fixedWindowFrame.maxY > screenFrame.maxY { - fixedWindowFrame.origin.y = screenFrame.maxY - fixedWindowFrame.height + fixedWindowFrame.origin.y = screenFrame.maxY - fixedWindowFrame.height - Defaults[.windowPadding] } +// fixedWindowFrame = applyPadding(fixedWindowFrame, direction) setPosition(element: element, position: fixedWindowFrame.origin) } } + +extension CGRect { + 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 + } + } +} From accca29fb7c2616dcfc3a74433a444da61cb4290 Mon Sep 17 00:00:00 2001 From: Kai Azim <68963405+MrKai77@users.noreply.github.com> Date: Thu, 31 Aug 2023 18:02:41 -0600 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20Make=20padding=20configurable?= =?UTF-8?q?=20in=20settings=20window?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Loop/Extensions/Defaults+Extensions.swift | 2 ++ Loop/Settings/Views/MoreSettingsView.swift | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/Loop/Extensions/Defaults+Extensions.swift b/Loop/Extensions/Defaults+Extensions.swift index f5814095..09574921 100644 --- a/Loop/Extensions/Defaults+Extensions.swift +++ b/Loop/Extensions/Defaults+Extensions.swift @@ -98,4 +98,6 @@ extension Defaults.Keys { "rightThird", default: [[.kVK_ANSI_L]] ) + + static let windowPadding = Key("windowPadding", default: 0) } diff --git a/Loop/Settings/Views/MoreSettingsView.swift b/Loop/Settings/Views/MoreSettingsView.swift index 21de93e5..48794cbc 100644 --- a/Loop/Settings/Views/MoreSettingsView.swift +++ b/Loop/Settings/Views/MoreSettingsView.swift @@ -7,10 +7,12 @@ import SwiftUI import Sparkle +import Defaults struct MoreSettingsView: View { @EnvironmentObject var updater: SoftwareUpdater + @Default(.windowPadding) var windowPadding var body: some View { Form { @@ -35,6 +37,18 @@ struct MoreSettingsView: View { .foregroundStyle(Color.accentColor) } }) + + Section { + Slider( + value: $windowPadding, + in: 0...25, + step: 1, + minimumValueLabel: Text("0"), + maximumValueLabel: Text("25") + ) { + Text("Window Padding") + } + } } .formStyle(.grouped) } From cbfb9f27b17e1e2644557033ebda5eef94cf03f0 Mon Sep 17 00:00:00 2001 From: Kai Azim <68963405+MrKai77@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:44:33 -0600 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=92=84=20Move=20window=20padding=20se?= =?UTF-8?q?ttings=20to=20"General"=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Loop/Helpers/Views/BetaIndicator.swift | 2 +- Loop/Settings/Views/GeneralSettingsView.swift | 16 ++++++++++++++-- Loop/Settings/Views/MoreSettingsView.swift | 13 ------------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Loop/Helpers/Views/BetaIndicator.swift b/Loop/Helpers/Views/BetaIndicator.swift index 4b653995..df796fcc 100644 --- a/Loop/Helpers/Views/BetaIndicator.swift +++ b/Loop/Helpers/Views/BetaIndicator.swift @@ -20,7 +20,7 @@ struct BetaIndicator: View { Text(text) .font(.caption2) .padding(.horizontal, 4) - .padding(.vertical, 2) + .padding(.vertical, 1) .background { RoundedRectangle(cornerRadius: 50) .stroke(lineWidth: 1) diff --git a/Loop/Settings/Views/GeneralSettingsView.swift b/Loop/Settings/Views/GeneralSettingsView.swift index a70c9afb..282dc9ec 100644 --- a/Loop/Settings/Views/GeneralSettingsView.swift +++ b/Loop/Settings/Views/GeneralSettingsView.swift @@ -21,6 +21,7 @@ struct GeneralSettingsView: View { @Default(.currentIcon) var currentIcon @Default(.timesLooped) var timesLooped @Default(.animateWindowResizes) var animateWindowResizes + @Default(.windowPadding) var windowPadding let iconManager = IconManager() @@ -39,12 +40,23 @@ struct GeneralSettingsView: View { } } - Toggle(isOn: $animateWindowResizes, label: { + Toggle(isOn: $animateWindowResizes) { HStack { Text("Animate windows being resized") BetaIndicator("BETA") } - }) + } + + Slider(value: $windowPadding, + in: 0...25, + step: 5, + minimumValueLabel: Text("0"), + maximumValueLabel: Text("25")) { + HStack { + Text("Window Padding") + BetaIndicator("BETA") + } + } } Section("Loop's icon") { diff --git a/Loop/Settings/Views/MoreSettingsView.swift b/Loop/Settings/Views/MoreSettingsView.swift index 48794cbc..96d4bb15 100644 --- a/Loop/Settings/Views/MoreSettingsView.swift +++ b/Loop/Settings/Views/MoreSettingsView.swift @@ -12,7 +12,6 @@ import Defaults struct MoreSettingsView: View { @EnvironmentObject var updater: SoftwareUpdater - @Default(.windowPadding) var windowPadding var body: some View { Form { @@ -37,18 +36,6 @@ struct MoreSettingsView: View { .foregroundStyle(Color.accentColor) } }) - - Section { - Slider( - value: $windowPadding, - in: 0...25, - step: 1, - minimumValueLabel: Text("0"), - maximumValueLabel: Text("25") - ) { - Text("Window Padding") - } - } } .formStyle(.grouped) } From 5fb9b0d0b46b9346bfa3895999a0ce12ffcc2eda Mon Sep 17 00:00:00 2001 From: Kai Azim <68963405+MrKai77@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:51:03 -0600 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=A8=20Fix=20padding=20on=20size-const?= =?UTF-8?q?rained=20windows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Loop/Helpers/WindowEngine.swift | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Loop/Helpers/WindowEngine.swift b/Loop/Helpers/WindowEngine.swift index cc9d7646..f9e084ec 100644 --- a/Loop/Helpers/WindowEngine.swift +++ b/Loop/Helpers/WindowEngine.swift @@ -15,21 +15,20 @@ struct WindowEngine { let oldWindowFrame = window.frame guard let screenFrame = screen.safeScreenFrame else { return } guard var targetWindowFrame = WindowEngine.generateWindowFrame(oldWindowFrame, screenFrame, direction) else { return } + targetWindowFrame = WindowEngine.applyPadding(targetWindowFrame, direction) // Calculate the window's minimum window size and change the target accordingly window.getMinSize(screen: screen) { minSize in if (targetWindowFrame.minX + minSize.width) > screen.frame.maxX { - targetWindowFrame.origin.x = screen.frame.maxX - minSize.width + targetWindowFrame.origin.x = screen.frame.maxX - minSize.width - Defaults[.windowPadding] } if (targetWindowFrame.minY + minSize.height) > screen.frame.maxY { - targetWindowFrame.origin.y = screen.frame.maxY - minSize.height + targetWindowFrame.origin.y = screen.frame.maxY - minSize.height - Defaults[.windowPadding] } - targetWindowFrame = WindowEngine.applyPadding(targetWindowFrame, direction) - // Resize window - window.setFrame(targetWindowFrame, animate: true) + window.setFrame(targetWindowFrame, animate: Defaults[.animateWindowResizes]) } }