Skip to content

Commit

Permalink
🔀 Merge remote-tracking branch mrkai77/develop into develop
Browse files Browse the repository at this point in the history
# Conflicts:
#	Loop/Extensions/Defaults+Extensions.swift
  • Loading branch information
MrKai77 committed Jul 5, 2024
2 parents f566a34 + bc858fd commit 5ad3d79
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 73 deletions.
6 changes: 4 additions & 2 deletions Loop.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
A88E83C42B37B354009D332F /* CGEvent+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGEvent+Extensions.swift"; sourceTree = "<group>"; };
A89307302BAE6D0100566AEE /* CustomWindowActionUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomWindowActionUnit.swift; sourceTree = "<group>"; };
A893D3632BD3299000063510 /* IconConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconConfiguration.swift; sourceTree = "<group>"; };
A89E84592C3713B50039D220 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
A8A1C51D2BD3705A00515A14 /* PaddingConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingConfigurationView.swift; sourceTree = "<group>"; };
A8A1C5202BD4863B00515A14 /* KeybindingsConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeybindingsConfiguration.swift; sourceTree = "<group>"; };
A8A2ABE62A3FB0370067B5A9 /* KeybindMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeybindMonitor.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -417,6 +418,7 @@
A8E59C37297F5E9A0064D4BA /* Loop */ = {
isa = PBXGroup;
children = (
A89E84592C3713B50039D220 /* Info.plist */,
A80521312A84878200BF7E22 /* Config.xcconfig */,
A8E59C38297F5E9A0064D4BA /* LoopApp.swift */,
A85CB5842ACFA5F700BF63E6 /* AppDelegate.swift */,
Expand Down Expand Up @@ -788,7 +790,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "";
INFOPLIST_FILE = Loop/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Loop;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Loop";
Expand Down Expand Up @@ -823,7 +825,7 @@
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "";
INFOPLIST_FILE = Loop/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Loop;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Loop";
Expand Down
4 changes: 4 additions & 0 deletions Loop/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationDidFinishLaunching(_: Notification) {
Task {
await Defaults.iCloud.waitForSyncCompletion()
}

// Check & ask for accessibility access
AccessibilityManager.requestAccess()
UNUserNotificationCenter.current().delegate = self
Expand Down
141 changes: 72 additions & 69 deletions Loop/Extensions/Defaults+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,88 +11,91 @@ import SwiftUI
// Add variables for default values (which are stored even then the app is closed)
extension Defaults.Keys {
// Icon
static let currentIcon = Key<String>("currentIcon", default: "AppIcon-Classic")
static let timesLooped = Key<Int>("timesLooped", default: 0)
static let showDockIcon = Key<Bool>("showDockIcon", default: false)
static let notificationWhenIconUnlocked = Key<Bool>("notificationWhenIconUnlocked", default: true)
static let currentIcon = Key<String>("currentIcon", default: "AppIcon-Classic", iCloud: true)
static let timesLooped = Key<Int>("timesLooped", default: 0, iCloud: true)
static let showDockIcon = Key<Bool>("showDockIcon", default: false, iCloud: true)
static let notificationWhenIconUnlocked = Key<Bool>("notificationWhenIconUnlocked", default: true, iCloud: true)

// Accent Color
static let useSystemAccentColor = Key<Bool>("useSystemAccentColor", default: true)
static let customAccentColor = Key<Color>("customAccentColor", default: Color(.white))
static let useGradient = Key<Bool>("useGradient", default: true)
static let gradientColor = Key<Color>("gradientColor", default: Color(.black))
static let processWallpaper = Key<Bool>("processWallpaper", default: false)
static let useSystemAccentColor = Key<Bool>("useSystemAccentColor", default: true, iCloud: true)
static let customAccentColor = Key<Color>("customAccentColor", default: Color(.white), iCloud: true)
static let useGradient = Key<Bool>("useGradient", default: true, iCloud: true)
static let gradientColor = Key<Color>("gradientColor", default: Color(.black), iCloud: true)
static let processWallpaper = Key<Bool>("processWallpaper", default: false, iCloud: true)

// Radial Menu
static let radialMenuVisibility = Key<Bool>("radialMenuVisibility", default: true)
static let disableCursorInteraction = Key<Bool>("disableCursorInteraction", default: false)
static let radialMenuCornerRadius = Key<CGFloat>("radialMenuCornerRadius", default: 50)
static let radialMenuThickness = Key<CGFloat>("radialMenuThickness", default: 22)
static let radialMenuVisibility = Key<Bool>("radialMenuVisibility", default: true, iCloud: true)
static let disableCursorInteraction = Key<Bool>("disableCursorInteraction", default: false, iCloud: true)
static let radialMenuCornerRadius = Key<CGFloat>("radialMenuCornerRadius", default: 50, iCloud: true)
static let radialMenuThickness = Key<CGFloat>("radialMenuThickness", default: 22, iCloud: true)

// Preview
static let previewVisibility = Key<Bool>("previewVisibility", default: true)
static let previewPadding = Key<CGFloat>("previewPadding", default: 10)
static let previewCornerRadius = Key<CGFloat>("previewCornerRadius", default: 10)
static let previewBorderThickness = Key<CGFloat>("previewBorderThickness", default: 5)
static let previewVisibility = Key<Bool>("previewVisibility", default: true, iCloud: true)
static let previewPadding = Key<CGFloat>("previewPadding", default: 10, iCloud: true)
static let previewCornerRadius = Key<CGFloat>("previewCornerRadius", default: 10, iCloud: true)
static let previewBorderThickness = Key<CGFloat>("previewBorderThickness", default: 5, iCloud: true)

// Behavior
static let launchAtLogin = Key<Bool>("launchAtLogin", default: false)
static let hideMenuBarIcon = Key<Bool>("hideMenuBarIcon", default: false)
static let animationConfiguration = Key<AnimationConfiguration>("animationConfiguration", default: .fast)
static let windowSnapping = Key<Bool>("windowSnapping", default: false)
static let restoreWindowFrameOnDrag = Key<Bool>("restoreWindowFrameOnDrag", default: false)
static let enablePadding = Key<Bool>("enablePadding", default: false)
static let padding = Key<PaddingModel>("padding", default: .zero)
static let useScreenWithCursor = Key<Bool>("useScreenWithCursor", default: true)
static let moveCursorWithWindow = Key<Bool>("moveCursorWithWindow", default: false)
static let resizeWindowUnderCursor = Key<Bool>("resizeWindowUnderCursor", default: false)
static let focusWindowOnResize = Key<Bool>("focusWindowOnResize", default: true)
static let respectStageManager = Key<Bool>("respectStageManager", default: true)
static let stageStripSize = Key<CGFloat>("stageStripSize", default: 150)
static let launchAtLogin = Key<Bool>("launchAtLogin", default: false, iCloud: true)
static let hideMenuBarIcon = Key<Bool>("hideMenuBarIcon", default: false, iCloud: true)
static let animationConfiguration = Key<AnimationConfiguration>("animationConfiguration", default: .fast, iCloud: true)
static let windowSnapping = Key<Bool>("windowSnapping", default: false, iCloud: true)
static let restoreWindowFrameOnDrag = Key<Bool>("restoreWindowFrameOnDrag", default: false, iCloud: true)
static let enablePadding = Key<Bool>("enablePadding", default: false, iCloud: true)
static let padding = Key<PaddingModel>("padding", default: .zero, iCloud: true)
static let useScreenWithCursor = Key<Bool>("useScreenWithCursor", default: true, iCloud: true)
static let moveCursorWithWindow = Key<Bool>("moveCursorWithWindow", default: false, iCloud: true)
static let resizeWindowUnderCursor = Key<Bool>("resizeWindowUnderCursor", default: false, iCloud: true)
static let focusWindowOnResize = Key<Bool>("focusWindowOnResize", default: true, iCloud: true)
static let respectStageManager = Key<Bool>("respectStageManager", default: true, iCloud: true)
static let stageStripSize = Key<CGFloat>("stageStripSize", default: 150, iCloud: true)

// Keybindings
static let triggerKey = Key<Set<CGKeyCode>>("trigger", default: [.kVK_Function])
static let triggerDelay = Key<Double>("triggerDelay", default: 0)
static let doubleClickToTrigger = Key<Bool>("doubleClickToTrigger", default: false)
static let middleClickTriggersLoop = Key<Bool>("middleClickTriggersLoop", default: false)
static let keybinds = Key<[WindowAction]>("keybinds", default: [
WindowAction(.maximize, keybind: [.kVK_Space]),
WindowAction(.center, keybind: [.kVK_Return]),
WindowAction(.init(localized: "Top Cycle"), [
.init(.topHalf),
.init(.topThird),
.init(.topTwoThirds)
], [.kVK_UpArrow]),
WindowAction(.init(localized: "Bottom Cycle"), [
.init(.bottomHalf),
.init(.bottomThird),
.init(.bottomTwoThirds)
], [.kVK_DownArrow]),
WindowAction(.init(localized: "Right Cycle"), [
.init(.rightHalf),
.init(.rightThird),
.init(.rightTwoThirds)
], [.kVK_RightArrow]),
WindowAction(.init(localized: "Left Cycle"), [
.init(.leftHalf),
.init(.leftThird),
.init(.leftTwoThirds)
], [.kVK_LeftArrow]),

WindowAction(.topLeftQuarter, keybind: [.kVK_UpArrow, .kVK_LeftArrow]),
WindowAction(.topRightQuarter, keybind: [.kVK_UpArrow, .kVK_RightArrow]),
WindowAction(.bottomRightQuarter, keybind: [.kVK_DownArrow, .kVK_RightArrow]),
WindowAction(.bottomLeftQuarter, keybind: [.kVK_DownArrow, .kVK_LeftArrow])
])
static let triggerKey = Key<Set<CGKeyCode>>("trigger", default: [.kVK_Function], iCloud: true)
static let triggerDelay = Key<Double>("triggerDelay", default: 0, iCloud: true)
static let doubleClickToTrigger = Key<Bool>("doubleClickToTrigger", default: false, iCloud: true)
static let middleClickTriggersLoop = Key<Bool>("middleClickTriggersLoop", default: false, iCloud: true)
static let keybinds = Key<[WindowAction]>(
"keybinds",
default: [
WindowAction(.maximize, keybind: [.kVK_Space]),
WindowAction(.center, keybind: [.kVK_Return]),
WindowAction(.init(localized: "Top Cycle"), [
.init(.topHalf),
.init(.topThird),
.init(.topTwoThirds)
], [.kVK_UpArrow]),
WindowAction(.init(localized: "Bottom Cycle"), [
.init(.bottomHalf),
.init(.bottomThird),
.init(.bottomTwoThirds)
], [.kVK_DownArrow]),
WindowAction(.init(localized: "Right Cycle"), [
.init(.rightHalf),
.init(.rightThird),
.init(.rightTwoThirds)
], [.kVK_RightArrow]),
WindowAction(.init(localized: "Left Cycle"), [
.init(.leftHalf),
.init(.leftThird),
.init(.leftTwoThirds)
], [.kVK_LeftArrow]),
WindowAction(.topLeftQuarter, keybind: [.kVK_UpArrow, .kVK_LeftArrow]),
WindowAction(.topRightQuarter, keybind: [.kVK_UpArrow, .kVK_RightArrow]),
WindowAction(.bottomRightQuarter, keybind: [.kVK_DownArrow, .kVK_RightArrow]),
WindowAction(.bottomLeftQuarter, keybind: [.kVK_DownArrow, .kVK_LeftArrow])
],
iCloud: true
)

// Advanced
static let animateWindowResizes = Key<Bool>("animateWindowResizes", default: false) // BETA
static let hideUntilDirectionIsChosen = Key<Bool>("hideUntilDirectionIsChosen", default: false)
static let hapticFeedback = Defaults.Key<Bool>("hapticFeedback", default: true)
static let animateWindowResizes = Key<Bool>("animateWindowResizes", default: false, iCloud: true) // BETA
static let hideUntilDirectionIsChosen = Key<Bool>("hideUntilDirectionIsChosen", default: false, iCloud: true)
static let hapticFeedback = Defaults.Key<Bool>("hapticFeedback", default: true, iCloud: true)

// About
static let includeDevelopmentVersions = Key<Bool>("includeDevelopmentVersions", default: false)
static let includeDevelopmentVersions = Key<Bool>("includeDevelopmentVersions", default: false, iCloud: true)

static let excludedApps = Key<[URL]>("excludedApps", default: [])
static let sizeIncrement = Key<CGFloat>("sizeIncrement", default: 20)
static let excludedApps = Key<[URL]>("excludedApps", default: [], iCloud: true)
static let sizeIncrement = Key<CGFloat>("sizeIncrement", default: 20, iCloud: true)
}
5 changes: 5 additions & 0 deletions Loop/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
3 changes: 3 additions & 0 deletions Loop/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -6834,6 +6834,9 @@
},
"Unlocking this icon is just a matter of time and loops." : {

},
"Update…" : {

},
"Updates? In this economy?" : {

Expand Down
7 changes: 6 additions & 1 deletion Loop/Loop.entitlements
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>com.apple.developer.icloud-container-identifiers</key>
<array/>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
</dict>
</plist>
10 changes: 10 additions & 0 deletions Loop/Luminare/Loop/AboutConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ struct AboutConfigurationView: View {
.contentTransition(.numericText())
.animation(LuminareSettingsWindow.animation, value: model.updateButtonTitle)
}
.onAppear {
if updater.updateState == .available {
model.updateButtonTitle = "Update…"
}
}
.onChange(of: updater.updateState) { _ in
if updater.updateState == .available {
model.updateButtonTitle = "Update…"
}
}

// LuminareToggle("Automatically check for updates", isOn: $updater.automaticallyChecksForUpdates)
LuminareToggle("Include development versions", isOn: $updater.includeDevelopmentVersions)
Expand Down
2 changes: 1 addition & 1 deletion Loop/Luminare/LuminareManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class LuminareManager {

static let advancedConfiguration = SettingsTab("Advanced", Image(._18PxFaceNerdSmile), AdvancedConfigurationView())
static let excludedAppsConfiguration = SettingsTab("Excluded Apps", Image(._18PxWindowLock), ExcludedAppsConfigurationView())
static let aboutConfiguration = SettingsTab("About", Image(._18PxMsgSmile2), AboutConfigurationView())
static let aboutConfiguration = SettingsTab("About", Image(._18PxMsgSmile2), AboutConfigurationView(), showIndicator: { AppDelegate.updater.updateState == .available })

static var luminare: LuminareSettingsWindow?

Expand Down

0 comments on commit 5ad3d79

Please sign in to comment.