From a4f87dfe0bc34403104251f2c10659fdc7e92dc7 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 30 May 2023 00:59:01 +0700 Subject: [PATCH] Tweaks --- .swiftlint.yml | 11 +- Color Picker.xcodeproj/project.pbxproj | 14 ++- .../xcschemes/Color Picker.xcscheme | 2 +- Color Picker/App.swift | 5 +- Color Picker/AppState.swift | 7 +- Color Picker/ColorPickerScreen.swift | 6 +- Color Picker/Constants.swift | 18 +-- Color Picker/Events.swift | 22 ++-- Color Picker/SettingsScreen.swift | 10 +- Color Picker/Utilities.swift | 113 ++++++++---------- Intents Extension/Intents.swift | 2 +- readme.md | 3 +- 12 files changed, 102 insertions(+), 111 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index da64edd..9b0fb55 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -80,6 +80,7 @@ only_rules: - no_extension_access_modifier - no_fallthrough_only - no_space_in_method_call + - non_overridable_class_declaration - notification_center_detachment - ns_number_init_as_function_reference - nsobject_prefer_isequal @@ -94,6 +95,7 @@ only_rules: - private_action - private_outlet - private_subject + - private_swiftui_state - private_unit_test - prohibited_super_call - protocol_property_accessors_order @@ -119,6 +121,7 @@ only_rules: - static_operator - strong_iboutlet - superfluous_disable_command + - superfluous_else - switch_case_alignment - switch_case_on_newline - syntactic_sugar @@ -132,6 +135,7 @@ only_rules: - unavailable_condition - unavailable_function - unneeded_break_in_switch + - unneeded_override - unneeded_parentheses_in_closure_argument - unowned_variable_capture - untyped_error_in_catch @@ -165,7 +169,6 @@ identifier_name: min_length: warning: 2 error: 2 - validates_start_with_lowercase: false allowed_symbols: - '_' excluded: @@ -180,7 +183,7 @@ identifier_name: - 'y2' - 'z2' deployment_target: - macOS_deployment_target: '12' + macOS_deployment_target: '13' custom_rules: no_nsrect: regex: '\bNSRect\b' @@ -202,8 +205,8 @@ custom_rules: regex: '\bCGFloat\(' message: 'Use Double instead of CGFloat' swiftui_state_private: - regex: '@(State|StateObject|ObservedObject|EnvironmentObject)\s+var' - message: 'SwiftUI @State/@StateObject/@ObservedObject/@EnvironmentObject properties should be private' + regex: '@(ObservedObject|EnvironmentObject)\s+var' + message: 'SwiftUI @ObservedObject/@EnvironmentObject properties should be private' swiftui_environment_private: regex: '@Environment\(\\\.\w+\)\s+var' message: 'SwiftUI @Environment properties should be private' diff --git a/Color Picker.xcodeproj/project.pbxproj b/Color Picker.xcodeproj/project.pbxproj index a7db588..e258973 100644 --- a/Color Picker.xcodeproj/project.pbxproj +++ b/Color Picker.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 56; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ @@ -235,7 +235,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1420; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1500; TargetAttributes = { E34BFA932988F3AF002AB421 = { CreatedOnToolsVersion = 14.2; @@ -246,7 +246,7 @@ }; }; buildConfigurationList = E3A3B11425904E7B001B4D0C /* Build configuration list for PBXProject "Color Picker" */; - compatibilityVersion = "Xcode 14.0"; + compatibilityVersion = "Xcode 15.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -409,6 +409,7 @@ baseConfigurationReference = E3E7D7AB27218A50009D71F4 /* Config.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -443,6 +444,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -457,7 +459,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 13.3; + MACOSX_DEPLOYMENT_TARGET = 13.5; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -473,6 +475,7 @@ baseConfigurationReference = E3E7D7AB27218A50009D71F4 /* Config.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -507,6 +510,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -515,7 +519,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 13.3; + MACOSX_DEPLOYMENT_TARGET = 13.5; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; diff --git a/Color Picker.xcodeproj/xcshareddata/xcschemes/Color Picker.xcscheme b/Color Picker.xcodeproj/xcshareddata/xcschemes/Color Picker.xcscheme index 4dc1324..2fc01e6 100644 --- a/Color Picker.xcodeproj/xcshareddata/xcschemes/Color Picker.xcscheme +++ b/Color Picker.xcodeproj/xcshareddata/xcschemes/Color Picker.xcscheme @@ -1,6 +1,6 @@ Void ) -> some View { - onReceive(NotificationCenter.default.publisher(for: name, object: object)) { - action($0) - } + onReceive(NotificationCenter.default.publisher(for: name, object: object), perform: action) } } @@ -1346,6 +1349,20 @@ extension NSControl: ControlActionClosureProtocol {} extension NSMenuItem: ControlActionClosureProtocol {} +extension NSMenuItem { + /** + Perform the default action for the menu item (click it). + */ + func performAction() { + guard let menu else { + return + } + + menu.performActionForItem(at: menu.index(of: self)) + } +} + + extension NSWindow { func toggle() { if isVisible, isKeyWindow { @@ -1510,10 +1527,10 @@ extension URL { extension String { /* ``` - "https://sindresorhus.com".openUrl() + "https://sindresorhus.com".openURL() ``` */ - func openUrl() { + func openURL() { URL(string: self)?.open() } } @@ -1621,6 +1638,15 @@ extension View { } +extension NSWindow.Level { + private static func level(for cgLevelKey: CGWindowLevelKey) -> Self { + .init(Int(CGWindowLevelForKey(cgLevelKey))) + } + + public static let utility = level(for: .utilityWindow) +} + + extension NSView { /** Get a subview matching a condition. @@ -2265,11 +2291,11 @@ enum SettingsTabType { fileprivate var label: some View { switch self { case .general: - return Label("General", systemImage: "gearshape") + Label("General", systemImage: "gearshape") case .advanced: - return Label("Advanced", systemImage: "gearshape.2") + Label("Advanced", systemImage: "gearshape.2") case .shortcuts: - return Label("Shortcuts", systemImage: "command") + Label("Shortcuts", systemImage: "command") } } } @@ -2397,28 +2423,7 @@ extension Binding where Value: SetAlgebra, Value.Element: Hashable { } -/** -A picker that supports multiple selections and renders as multiple checkboxes. - -``` -struct ContentView: View { - private var data = [DayOfWeek]() - @State private var selection = Set() - - var body: some View { - Defaults.MultiCheckboxPicker( - data: DayOfWeek.days, - selection: $selection - ) { - Text($0.name) - } - } -} -``` - -It intentionally does not support a `label` parameter as we cannot read `.labelsHidden()`, so we cannot respect that. -*/ -struct MultiCheckboxPicker: View where Data.Element: Hashable & Identifiable { +struct MultiTogglePicker: View where Data.Element: Hashable & Identifiable { let data: Data @Binding var selection: Set @ViewBuilder var elementLabel: (Data.Element) -> ElementLabel @@ -2432,27 +2437,11 @@ struct MultiCheckboxPicker: Vi } } -typealias _OriginalMultiCheckboxPicker = MultiCheckboxPicker +typealias _OriginalMultiTogglePicker = MultiTogglePicker #if !APP_EXTENSION extension Defaults { - /** - A picker that supports multiple selections and renders as multiple checkboxes. - - ``` - struct ContentView: View { - var body: some View { - Defaults.MultiCheckboxPicker( - key: .highlightedDaysInCalendar, - data: DayOfWeek.days(for: calendar) - ) { - Text($0.name(for: calendar)) - } - } - } - ``` - */ - struct MultiCheckboxPicker: View where Data.Element: Hashable & Identifiable & Defaults.Serializable { + struct MultiTogglePicker: View where Data.Element: Hashable & Identifiable & Defaults.Serializable { typealias Element = Data.Element typealias Selection = Set @@ -2472,7 +2461,7 @@ extension Defaults { } var body: some View { - _OriginalMultiCheckboxPicker( + _OriginalMultiTogglePicker( data: data, selection: $selection ) { @@ -2485,7 +2474,7 @@ extension Defaults { } } -extension Defaults.MultiCheckboxPicker { +extension Defaults.MultiTogglePicker { /** Do something when the value changes to a different value. */ @@ -2946,9 +2935,9 @@ extension OperatingSystem { #if os(macOS) if #available(macOS 15, *) { return true - } else { - return false } + + return false #else return false #endif @@ -2961,9 +2950,9 @@ extension OperatingSystem { #if os(macOS) if #available(macOS 14, *) { return true - } else { - return false } + + return false #else return false #endif diff --git a/Intents Extension/Intents.swift b/Intents Extension/Intents.swift index c66f38a..ae4e06a 100644 --- a/Intents Extension/Intents.swift +++ b/Intents Extension/Intents.swift @@ -44,7 +44,7 @@ The color formats Hex, HSL, RGB, and LCH are provided as individual properties. } struct Color_AppEntity: TransientAppEntity { - static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Color") + static let typeDisplayRepresentation: TypeDisplayRepresentation = "Color" @Property(title: "Hex") var hex: String diff --git a/readme.md b/readme.md index f24c420..ca28e11 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ Requires macOS 13 or later. **Non-App Store version** -A special version for users that cannot access the App Store. It won't receive updates. +A special version for users that cannot access the App Store. It won't receive automatic updates. I will update it here once a year. [Download](https://dsc.cloud/sindresorhus/Color-Picker-1.13.0-1679983870.zip) *(1.13.0 · macOS 13+)* @@ -104,7 +104,6 @@ I don't have any immediate plans to localize the app. ## Built with - [Defaults](https://github.com/sindresorhus/Defaults) - Swifty and modern UserDefaults -- [Regex](https://github.com/sindresorhus/Regex) - Swifty regular expressions - [KeyboardShortcuts](https://github.com/sindresorhus/KeyboardShortcuts) - Add user-customizable global keyboard shortcuts to your macOS app - [LaunchAtLogin](https://github.com/sindresorhus/LaunchAtLogin) - Add “Launch at Login” functionality to your macOS app