├── .DS_Store ├── Cartfile ├── Cartfile.resolved ├── Carthage ├── Build │ ├── .HotKey.version │ └── Mac │ │ ├── HotKey.framework.dSYM │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ └── DWARF │ │ │ └── HotKey │ │ └── HotKey.framework │ │ ├── Headers │ │ ├── HotKey │ │ ├── Modules │ │ ├── Resources │ │ └── Versions │ │ ├── A │ │ ├── Headers │ │ │ ├── HotKey-Swift.h │ │ │ └── HotKey.h │ │ ├── HotKey │ │ ├── Modules │ │ │ ├── HotKey.swiftmodule │ │ │ │ ├── x86_64.swiftdoc │ │ │ │ └── x86_64.swiftmodule │ │ │ └── module.modulemap │ │ └── Resources │ │ │ └── Info.plist │ │ └── Current └── Checkouts │ └── HotKey │ ├── .gitignore │ ├── .swift-version │ ├── .travis.yml │ ├── Example │ ├── Sources │ │ ├── AppDelegate.swift │ │ └── ViewController.swift │ └── Support │ │ ├── Base.lproj │ │ └── Main.storyboard │ │ └── Info.plist │ ├── HotKey.podspec │ ├── LICENSE │ ├── Package.swift │ ├── README.md │ ├── Sources │ └── HotKey │ │ ├── HotKey.swift │ │ ├── HotKeysController.swift │ │ ├── Key.swift │ │ ├── KeyCombo.swift │ │ └── NSEventModifierFlags+HotKey.swift │ ├── Support │ ├── HotKey.h │ ├── Info.plist │ └── Tests-Info.plist │ └── Tests │ └── HotKeyTests │ ├── KeyComboTests.swift │ └── ModifierFlagsTests.swift ├── LICENSE ├── Open Figma.dmg ├── Open Figma.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ ├── jdunsterville.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings │ │ └── neversitdull.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── jdunsterville.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ └── xcschememanagement.plist │ └── neversitdull.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── Open Figma ├── .DS_Store ├── AppDelegate.swift ├── Assets.xcassets │ ├── .DS_Store │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-1024.png │ │ ├── Icon-128.png │ │ ├── Icon-16.png │ │ ├── Icon-256.png │ │ ├── Icon-32.png │ │ ├── Icon-512.png │ │ └── Icon-64.png │ ├── Contents.json │ └── figma-icon.imageset │ │ ├── Contents.json │ │ └── figma-icon@2x.png ├── Base.lproj │ └── Main.storyboard ├── Info.plist ├── Open_Figma.entitlements ├── StatusMenuController.swift └── ViewController.swift └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/.DS_Store -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "soffes/HotKey" -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "soffes/HotKey" "v0.1.1" 2 | -------------------------------------------------------------------------------- /Carthage/Build/.HotKey.version: -------------------------------------------------------------------------------- 1 | { 2 | "Mac" : [ 3 | { 4 | "name" : "HotKey", 5 | "hash" : "c382f7f4f16762e2469da001a28bf292f205941a53bb1135940c79a163f68aa0" 6 | } 7 | ], 8 | "watchOS" : [ 9 | 10 | ], 11 | "tvOS" : [ 12 | 13 | ], 14 | "commitish" : "v0.1.1", 15 | "iOS" : [ 16 | 17 | ] 18 | } -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.com.samsoffes.HotKey 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 0.1.1 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework.dSYM/Contents/Resources/DWARF/HotKey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Carthage/Build/Mac/HotKey.framework.dSYM/Contents/Resources/DWARF/HotKey -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/HotKey: -------------------------------------------------------------------------------- 1 | Versions/Current/HotKey -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Modules: -------------------------------------------------------------------------------- 1 | Versions/Current/Modules -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/Headers/HotKey-Swift.h: -------------------------------------------------------------------------------- 1 | // Generated by Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1) 2 | #pragma clang diagnostic push 3 | #pragma clang diagnostic ignored "-Wgcc-compat" 4 | 5 | #if !defined(__has_include) 6 | # define __has_include(x) 0 7 | #endif 8 | #if !defined(__has_attribute) 9 | # define __has_attribute(x) 0 10 | #endif 11 | #if !defined(__has_feature) 12 | # define __has_feature(x) 0 13 | #endif 14 | #if !defined(__has_warning) 15 | # define __has_warning(x) 0 16 | #endif 17 | 18 | #if __has_include() 19 | # include 20 | #endif 21 | 22 | #pragma clang diagnostic ignored "-Wauto-import" 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #if !defined(SWIFT_TYPEDEFS) 29 | # define SWIFT_TYPEDEFS 1 30 | # if __has_include() 31 | # include 32 | # elif !defined(__cplusplus) 33 | typedef uint_least16_t char16_t; 34 | typedef uint_least32_t char32_t; 35 | # endif 36 | typedef float swift_float2 __attribute__((__ext_vector_type__(2))); 37 | typedef float swift_float3 __attribute__((__ext_vector_type__(3))); 38 | typedef float swift_float4 __attribute__((__ext_vector_type__(4))); 39 | typedef double swift_double2 __attribute__((__ext_vector_type__(2))); 40 | typedef double swift_double3 __attribute__((__ext_vector_type__(3))); 41 | typedef double swift_double4 __attribute__((__ext_vector_type__(4))); 42 | typedef int swift_int2 __attribute__((__ext_vector_type__(2))); 43 | typedef int swift_int3 __attribute__((__ext_vector_type__(3))); 44 | typedef int swift_int4 __attribute__((__ext_vector_type__(4))); 45 | typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); 46 | typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); 47 | typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); 48 | #endif 49 | 50 | #if !defined(SWIFT_PASTE) 51 | # define SWIFT_PASTE_HELPER(x, y) x##y 52 | # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) 53 | #endif 54 | #if !defined(SWIFT_METATYPE) 55 | # define SWIFT_METATYPE(X) Class 56 | #endif 57 | #if !defined(SWIFT_CLASS_PROPERTY) 58 | # if __has_feature(objc_class_property) 59 | # define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ 60 | # else 61 | # define SWIFT_CLASS_PROPERTY(...) 62 | # endif 63 | #endif 64 | 65 | #if __has_attribute(objc_runtime_name) 66 | # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) 67 | #else 68 | # define SWIFT_RUNTIME_NAME(X) 69 | #endif 70 | #if __has_attribute(swift_name) 71 | # define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) 72 | #else 73 | # define SWIFT_COMPILE_NAME(X) 74 | #endif 75 | #if __has_attribute(objc_method_family) 76 | # define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) 77 | #else 78 | # define SWIFT_METHOD_FAMILY(X) 79 | #endif 80 | #if __has_attribute(noescape) 81 | # define SWIFT_NOESCAPE __attribute__((noescape)) 82 | #else 83 | # define SWIFT_NOESCAPE 84 | #endif 85 | #if __has_attribute(warn_unused_result) 86 | # define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 87 | #else 88 | # define SWIFT_WARN_UNUSED_RESULT 89 | #endif 90 | #if __has_attribute(noreturn) 91 | # define SWIFT_NORETURN __attribute__((noreturn)) 92 | #else 93 | # define SWIFT_NORETURN 94 | #endif 95 | #if !defined(SWIFT_CLASS_EXTRA) 96 | # define SWIFT_CLASS_EXTRA 97 | #endif 98 | #if !defined(SWIFT_PROTOCOL_EXTRA) 99 | # define SWIFT_PROTOCOL_EXTRA 100 | #endif 101 | #if !defined(SWIFT_ENUM_EXTRA) 102 | # define SWIFT_ENUM_EXTRA 103 | #endif 104 | #if !defined(SWIFT_CLASS) 105 | # if __has_attribute(objc_subclassing_restricted) 106 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA 107 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 108 | # else 109 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 110 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 111 | # endif 112 | #endif 113 | 114 | #if !defined(SWIFT_PROTOCOL) 115 | # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 116 | # define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 117 | #endif 118 | 119 | #if !defined(SWIFT_EXTENSION) 120 | # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) 121 | #endif 122 | 123 | #if !defined(OBJC_DESIGNATED_INITIALIZER) 124 | # if __has_attribute(objc_designated_initializer) 125 | # define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 126 | # else 127 | # define OBJC_DESIGNATED_INITIALIZER 128 | # endif 129 | #endif 130 | #if !defined(SWIFT_ENUM_ATTR) 131 | # if defined(__has_attribute) && __has_attribute(enum_extensibility) 132 | # define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) 133 | # else 134 | # define SWIFT_ENUM_ATTR(_extensibility) 135 | # endif 136 | #endif 137 | #if !defined(SWIFT_ENUM) 138 | # define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type 139 | # if __has_feature(generalized_swift_name) 140 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type 141 | # else 142 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) 143 | # endif 144 | #endif 145 | #if !defined(SWIFT_UNAVAILABLE) 146 | # define SWIFT_UNAVAILABLE __attribute__((unavailable)) 147 | #endif 148 | #if !defined(SWIFT_UNAVAILABLE_MSG) 149 | # define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) 150 | #endif 151 | #if !defined(SWIFT_AVAILABILITY) 152 | # define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) 153 | #endif 154 | #if !defined(SWIFT_DEPRECATED) 155 | # define SWIFT_DEPRECATED __attribute__((deprecated)) 156 | #endif 157 | #if !defined(SWIFT_DEPRECATED_MSG) 158 | # define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) 159 | #endif 160 | #if __has_feature(attribute_diagnose_if_objc) 161 | # define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) 162 | #else 163 | # define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) 164 | #endif 165 | #if __has_feature(modules) 166 | #endif 167 | 168 | #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" 169 | #pragma clang diagnostic ignored "-Wduplicate-method-arg" 170 | #if __has_warning("-Wpragma-clang-attribute") 171 | # pragma clang diagnostic ignored "-Wpragma-clang-attribute" 172 | #endif 173 | #pragma clang diagnostic ignored "-Wunknown-pragmas" 174 | #pragma clang diagnostic ignored "-Wnullability" 175 | 176 | #if __has_attribute(external_source_symbol) 177 | # pragma push_macro("any") 178 | # undef any 179 | # pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="HotKey",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) 180 | # pragma pop_macro("any") 181 | #endif 182 | 183 | #if __has_attribute(external_source_symbol) 184 | # pragma clang attribute pop 185 | #endif 186 | #pragma clang diagnostic pop 187 | -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/Headers/HotKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // HotKey.h 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | //! Project version number for HotKey. 12 | FOUNDATION_EXPORT double HotKeyVersionNumber; 13 | 14 | //! Project version string for HotKey. 15 | FOUNDATION_EXPORT const unsigned char HotKeyVersionString[]; 16 | -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/HotKey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Carthage/Build/Mac/HotKey.framework/Versions/A/HotKey -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/Modules/HotKey.swiftmodule/x86_64.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Carthage/Build/Mac/HotKey.framework/Versions/A/Modules/HotKey.swiftmodule/x86_64.swiftdoc -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/Modules/HotKey.swiftmodule/x86_64.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Carthage/Build/Mac/HotKey.framework/Versions/A/Modules/HotKey.swiftmodule/x86_64.swiftmodule -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module HotKey { 2 | umbrella header "HotKey.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | 8 | module HotKey.Swift { 9 | header "HotKey-Swift.h" 10 | requires objc 11 | } 12 | -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 18A389 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | HotKey 11 | CFBundleIdentifier 12 | com.samsoffes.HotKey 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | HotKey 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 0.1.1 21 | CFBundleSupportedPlatforms 22 | 23 | MacOSX 24 | 25 | CFBundleVersion 26 | 1 27 | DTCompiler 28 | com.apple.compilers.llvm.clang.1_0 29 | DTPlatformBuild 30 | 10B61 31 | DTPlatformVersion 32 | GM 33 | DTSDKBuild 34 | 18B71 35 | DTSDKName 36 | macosx10.14 37 | DTXcode 38 | 1010 39 | DTXcodeBuild 40 | 10B61 41 | NSHumanReadableCopyright 42 | Copyright © 2017 Sam Soffes. All rights reserved. 43 | 44 | 45 | -------------------------------------------------------------------------------- /Carthage/Build/Mac/HotKey.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | *.zip 6 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/.swift-version: -------------------------------------------------------------------------------- 1 | 4.2 2 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - osx 3 | language: swift 4 | osx_image: xcode9 5 | script: 6 | - swift build 7 | - swift test 8 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Example/Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | 11 | @NSApplicationMain final class AppDelegate: NSObject, NSApplicationDelegate {} 12 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Example/Sources/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import HotKey 11 | import Carbon 12 | 13 | final class ViewController: NSViewController { 14 | 15 | // MARK: - Properties 16 | 17 | @IBOutlet var pressedLabel: NSTextField! 18 | 19 | private var hotKey: HotKey? { 20 | didSet { 21 | guard let hotKey = hotKey else { 22 | pressedLabel.stringValue = "Unregistered" 23 | return 24 | } 25 | 26 | pressedLabel.stringValue = "Registered" 27 | 28 | hotKey.keyDownHandler = { [weak self] in 29 | self?.pressedLabel.stringValue = "Pressed at \(Date())" 30 | } 31 | } 32 | } 33 | 34 | 35 | // MARK: - NSViewController 36 | 37 | override func viewDidLoad() { 38 | super.viewDidLoad() 39 | register(self) 40 | } 41 | 42 | 43 | // MARK: - Actions 44 | 45 | @IBAction func unregister(_ sender: Any?) { 46 | hotKey = nil 47 | } 48 | 49 | @IBAction func register(_ sender: Any?) { 50 | hotKey = HotKey(keyCombo: KeyCombo(key: .r, modifiers: [.command, .option])) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Example/Support/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | Default 510 | 511 | 512 | 513 | 514 | 515 | 516 | Left to Right 517 | 518 | 519 | 520 | 521 | 522 | 523 | Right to Left 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | Default 535 | 536 | 537 | 538 | 539 | 540 | 541 | Left to Right 542 | 543 | 544 | 545 | 546 | 547 | 548 | Right to Left 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 714 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Example/Support/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Sam Soffes. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/HotKey.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'HotKey' 3 | spec.version = '0.1.1' 4 | spec.authors = {'Sam Soffes' => 'sam@soff.es'} 5 | spec.homepage = 'https://github.com/soffes/HotKey' 6 | spec.summary = 'Simple global shortcuts in macOS.' 7 | spec.source = {:git => 'https://github.com/soffes/HotKey.git', :tag => "v#{spec.version}"} 8 | spec.license = { :type => 'MIT', :file => 'LICENSE' } 9 | 10 | spec.osx.deployment_target = '10.9' 11 | 12 | spec.frameworks = 'Appkit', 'Carbon' 13 | spec.source_files = 'Sources/HotKey/**/*.{h,m,swift}' 14 | end 15 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Sam Soffes, http://soff.es 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.2 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "HotKey", 7 | products: [ 8 | .library(name: "HotKey", targets: ["HotKey"]) 9 | ], 10 | targets: [ 11 | .target(name: "HotKey"), 12 | .testTarget(name: "HotKeyTests", dependencies: ["HotKey"]) 13 | ] 14 | ) 15 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/README.md: -------------------------------------------------------------------------------- 1 | # HotKey 2 | 3 | [![Version](https://img.shields.io/github/release/soffes/HotKey.svg)](https://github.com/soffes/HotKey/releases) 4 | [![Build Status](https://travis-ci.org/soffes/HotKey.svg?branch=master)](https://travis-ci.org/soffes/HotKey) 5 | ![Swift Version](https://img.shields.io/badge/swift-4.0-orange.svg) 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | [![CocoaPods compatible](https://img.shields.io/cocoapods/v/HotKey.svg)](https://cocoapods.org/pods/HotKey) 8 | 9 | Simple global shortcuts in macOS. HotKey wraps the Carbon APIs for dealing with global hot keys to make it easy to use in Swift. 10 | 11 | **HotKey, along with [Color](https://github.com/soffes/Color), were created for use in [Contrast](https://usecontrast.com), a macOS app for checking designs for accessible color combinations.** 12 | 13 | ## Installation 14 | 15 | ### Carthage 16 | 17 | For installation with [Carthage](https://github.com/carthage/carthage), simply add the following to your `Cartfile`: 18 | 19 | ``` ruby 20 | github "soffes/HotKey" 21 | ``` 22 | 23 | ### Swift Package Manager 24 | 25 | For installation with [Swift Package Manager](https://github.com/apple/swift-package-manager), simply add the following to your `Package.swift`: 26 | 27 | ``` swift 28 | .package(url: "https://github.com/soffes/HotKey", from: "0.1.0") 29 | ``` 30 | 31 | ### CocoaPods 32 | 33 | For installation with [CocoaPods](http://cocoapods.org), simply add the following to your `Podfile`: 34 | 35 | ```ruby 36 | pod 'HotKey' 37 | ``` 38 | 39 | 40 | ## Usage 41 | 42 | Simply initialize a `HotKey` with a key and modifiers: 43 | 44 | ```swift 45 | // Setup hot key for ⌥⌘R 46 | let hotKey = HotKey(key: .r, modifiers: [.command, .option]) 47 | ``` 48 | 49 | This is a convenice initializer that creates a `KeyCombo` for you. You can also initialize with a Carbon key code and Carbon modifier flags if you’re feeling old school. 50 | 51 | Now you can set the `keyDownHandler` and get callbacks for when your hot key is pressed: 52 | 53 | ```swift 54 | hotKey.keyDownHandler = { 55 | print("Pressed at \(Date())") 56 | } 57 | ``` 58 | 59 | You can also implement `hotKey.keyUpHandler` if you’d like. 60 | 61 | You don’t need to think about when handlers are registered and unregistered. This all happens automatically based on the `HotKey` object’s lifecycle. 62 | 63 | 64 | ## Thanks 65 | 66 | HotKey was heavily inspired by PTHotKey. 67 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Sources/HotKey/HotKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HotKey.swift 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import Carbon 11 | 12 | public final class HotKey { 13 | 14 | // MARK: - Types 15 | 16 | public typealias Handler = () -> Void 17 | 18 | 19 | // MARK: - Properties 20 | 21 | let identifier = UUID() 22 | 23 | public let keyCombo: KeyCombo 24 | public var keyDownHandler: Handler? 25 | public var keyUpHandler: Handler? 26 | public var isPaused = false { 27 | didSet { 28 | if isPaused { 29 | HotKeysController.unregister(self) 30 | } else { 31 | HotKeysController.register(self) 32 | } 33 | } 34 | } 35 | 36 | 37 | // MARK: - Initializers 38 | 39 | public init(keyCombo: KeyCombo, keyDownHandler: Handler? = nil, keyUpHandler: Handler? = nil) { 40 | self.keyCombo = keyCombo 41 | self.keyDownHandler = keyDownHandler 42 | self.keyUpHandler = keyUpHandler 43 | 44 | HotKeysController.register(self) 45 | } 46 | 47 | public convenience init(carbonKeyCode: UInt32, carbonModifiers: UInt32, keyDownHandler: Handler? = nil, keyUpHandler: Handler? = nil) { 48 | let keyCombo = KeyCombo(carbonKeyCode: carbonKeyCode, carbonModifiers: carbonModifiers) 49 | self.init(keyCombo: keyCombo, keyDownHandler: keyDownHandler, keyUpHandler: keyUpHandler) 50 | } 51 | 52 | public convenience init(key: Key, modifiers: NSEvent.ModifierFlags, keyDownHandler: Handler? = nil, keyUpHandler: Handler? = nil) { 53 | let keyCombo = KeyCombo(key: key, modifiers: modifiers) 54 | self.init(keyCombo: keyCombo, keyDownHandler: keyDownHandler, keyUpHandler: keyUpHandler) 55 | } 56 | 57 | deinit { 58 | HotKeysController.unregister(self) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Sources/HotKey/HotKeysController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HotKeysController.swift 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import Carbon 10 | 11 | final class HotKeysController { 12 | 13 | // MARK: - Types 14 | 15 | final class HotKeyBox { 16 | let identifier: UUID 17 | weak var hotKey: HotKey? 18 | let carbonHotKeyID: UInt32 19 | var carbonEventHotKey: EventHotKeyRef? 20 | 21 | init(hotKey: HotKey, carbonHotKeyID: UInt32) { 22 | self.identifier = hotKey.identifier 23 | self.hotKey = hotKey 24 | self.carbonHotKeyID = carbonHotKeyID 25 | } 26 | } 27 | 28 | 29 | // MARK: - Properties 30 | 31 | static var hotKeys = [UInt32: HotKeyBox]() 32 | static private var hotKeysCount: UInt32 = 0 33 | 34 | static let eventHotKeySignature: UInt32 = { 35 | let string = "SSHk" 36 | var result: FourCharCode = 0 37 | for char in string.utf16 { 38 | result = (result << 8) + FourCharCode(char) 39 | } 40 | return result 41 | }() 42 | 43 | private static let eventSpec = [ 44 | EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed)), 45 | EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyReleased)) 46 | ] 47 | 48 | private static var eventHandler: EventHandlerRef? 49 | 50 | 51 | // MARK: - Registration 52 | 53 | static func register(_ hotKey: HotKey) { 54 | // Don't register an already registered HotKey 55 | if hotKeys.values.first(where: { $0.identifier == hotKey.identifier }) != nil { 56 | return 57 | } 58 | 59 | // Increment the count which will become out next ID 60 | hotKeysCount += 1 61 | 62 | // Create a box for our metadata and weak HotKey 63 | let box = HotKeyBox(hotKey: hotKey, carbonHotKeyID: hotKeysCount) 64 | hotKeys[box.carbonHotKeyID] = box 65 | 66 | // Register with the system 67 | var eventHotKey: EventHotKeyRef? 68 | let hotKeyID = EventHotKeyID(signature: eventHotKeySignature, id: box.carbonHotKeyID) 69 | let registerError = RegisterEventHotKey( 70 | hotKey.keyCombo.carbonKeyCode, 71 | hotKey.keyCombo.carbonModifiers, 72 | hotKeyID, 73 | GetEventDispatcherTarget(), 74 | 0, 75 | &eventHotKey 76 | ) 77 | 78 | // Ensure registration worked 79 | guard registerError == noErr, eventHotKey != nil else { 80 | return 81 | } 82 | 83 | // Store the event so we can unregister it later 84 | box.carbonEventHotKey = eventHotKey 85 | 86 | // Setup the event handler if needed 87 | updateEventHandler() 88 | } 89 | 90 | static func unregister(_ hotKey: HotKey) { 91 | // Find the box 92 | guard let box = self.box(for: hotKey) else { 93 | return 94 | } 95 | 96 | // Unregister the hot key 97 | UnregisterEventHotKey(box.carbonEventHotKey) 98 | 99 | // Destroy the box 100 | box.hotKey = nil 101 | hotKeys.removeValue(forKey: box.carbonHotKeyID) 102 | } 103 | 104 | 105 | // MARK: - Events 106 | 107 | static func handleCarbonEvent(_ event: EventRef?) -> OSStatus { 108 | // Ensure we have an event 109 | guard let event = event else { 110 | return OSStatus(eventNotHandledErr) 111 | } 112 | 113 | // Get the hot key ID from the event 114 | var hotKeyID = EventHotKeyID() 115 | let error = GetEventParameter( 116 | event, 117 | UInt32(kEventParamDirectObject), 118 | UInt32(typeEventHotKeyID), 119 | nil, 120 | MemoryLayout.size, 121 | nil, 122 | &hotKeyID 123 | ) 124 | 125 | if error != noErr { 126 | return error 127 | } 128 | 129 | // Ensure we have a HotKey registered for this ID 130 | guard hotKeyID.signature == eventHotKeySignature, 131 | let hotKey = self.hotKey(for: hotKeyID.id) 132 | else { 133 | return OSStatus(eventNotHandledErr) 134 | } 135 | 136 | // Call the handler 137 | switch GetEventKind(event) { 138 | case UInt32(kEventHotKeyPressed): 139 | if !hotKey.isPaused, let handler = hotKey.keyDownHandler { 140 | handler() 141 | return noErr 142 | } 143 | case UInt32(kEventHotKeyReleased): 144 | if !hotKey.isPaused, let handler = hotKey.keyUpHandler { 145 | handler() 146 | return noErr 147 | } 148 | default: 149 | break 150 | } 151 | 152 | return OSStatus(eventNotHandledErr) 153 | } 154 | 155 | private static func updateEventHandler() { 156 | if hotKeysCount == 0 || eventHandler != nil { 157 | return 158 | } 159 | 160 | // Register for key down and key up 161 | let eventSpec = [ 162 | EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyPressed)), 163 | EventTypeSpec(eventClass: OSType(kEventClassKeyboard), eventKind: UInt32(kEventHotKeyReleased)) 164 | ] 165 | 166 | // Install the handler 167 | InstallEventHandler(GetEventDispatcherTarget(), hotKeyEventHandler, 2, eventSpec, nil, &eventHandler) 168 | } 169 | 170 | 171 | // MARK: - Querying 172 | 173 | private static func hotKey(for carbonHotKeyID: UInt32) -> HotKey? { 174 | if let hotKey = hotKeys[carbonHotKeyID]?.hotKey { 175 | return hotKey 176 | } 177 | 178 | hotKeys.removeValue(forKey: carbonHotKeyID) 179 | return nil 180 | } 181 | 182 | private static func box(for hotKey: HotKey) -> HotKeyBox? { 183 | for box in hotKeys.values { 184 | if box.identifier == hotKey.identifier { 185 | return box 186 | } 187 | } 188 | 189 | return nil 190 | } 191 | } 192 | 193 | 194 | private func hotKeyEventHandler(eventHandlerCall: EventHandlerCallRef?, event: EventRef?, userData: UnsafeMutableRawPointer?) -> OSStatus { 195 | return HotKeysController.handleCarbonEvent(event) 196 | } 197 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Sources/HotKey/Key.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Key.swift 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import Carbon 10 | 11 | public enum Key { 12 | case a 13 | case s 14 | case d 15 | case f 16 | case h 17 | case g 18 | case z 19 | case x 20 | case c 21 | case v 22 | case b 23 | case q 24 | case w 25 | case e 26 | case r 27 | case y 28 | case t 29 | case one 30 | case two 31 | case three 32 | case four 33 | case six 34 | case five 35 | case equal 36 | case nine 37 | case seven 38 | case minus 39 | case eight 40 | case zero 41 | case rightBracket 42 | case o 43 | case u 44 | case leftBracket 45 | case i 46 | case p 47 | case l 48 | case j 49 | case quote 50 | case k 51 | case semicolon 52 | case backslash 53 | case comma 54 | case slash 55 | case n 56 | case m 57 | case period 58 | case grave 59 | case keypadDecimal 60 | case keypadMultiply 61 | case keypadPlus 62 | case keypadClear 63 | case keypadDivide 64 | case keypadEnter 65 | case keypadMinus 66 | case keypadEquals 67 | case keypad0 68 | case keypad1 69 | case keypad2 70 | case keypad3 71 | case keypad4 72 | case keypad5 73 | case keypad6 74 | case keypad7 75 | case keypad8 76 | case keypad9 77 | case `return` 78 | case tab 79 | case space 80 | case delete 81 | case escape 82 | case command 83 | case shift 84 | case capsLock 85 | case option 86 | case control 87 | case rightCommand 88 | case rightShift 89 | case rightOption 90 | case rightControl 91 | case function 92 | case f17 93 | case volumeUp 94 | case volumeDown 95 | case mute 96 | case f18 97 | case f19 98 | case f20 99 | case f5 100 | case f6 101 | case f7 102 | case f3 103 | case f8 104 | case f9 105 | case f11 106 | case f13 107 | case f16 108 | case f14 109 | case f10 110 | case f12 111 | case f15 112 | case help 113 | case home 114 | case pageUp 115 | case forwardDelete 116 | case f4 117 | case end 118 | case f2 119 | case pageDown 120 | case f1 121 | case leftArrow 122 | case rightArrow 123 | case downArrow 124 | case upArrow 125 | 126 | public init?(string: String) { 127 | switch string.lowercased() { 128 | case "a": self = .a 129 | case "s": self = .s 130 | case "d": self = .d 131 | case "f": self = .f 132 | case "h": self = .h 133 | case "g": self = .g 134 | case "z": self = .z 135 | case "x": self = .x 136 | case "c": self = .c 137 | case "v": self = .v 138 | case "b": self = .b 139 | case "q": self = .q 140 | case "w": self = .w 141 | case "e": self = .e 142 | case "r": self = .r 143 | case "y": self = .y 144 | case "t": self = .t 145 | case "one", "1": self = .one 146 | case "two", "2": self = .two 147 | case "three", "3": self = .three 148 | case "four", "4": self = .four 149 | case "six", "6": self = .six 150 | case "five", "5": self = .five 151 | case "equal", "=": self = .equal 152 | case "nine", "9": self = .nine 153 | case "seven", "7": self = .seven 154 | case "minus", "-": self = .minus 155 | case "eight", "8": self = .eight 156 | case "zero", "0": self = .zero 157 | case "rightBracket": self = .rightBracket 158 | case "o": self = .o 159 | case "u": self = .u 160 | case "leftBracket": self = .leftBracket 161 | case "i": self = .i 162 | case "p": self = .p 163 | case "l": self = .l 164 | case "j": self = .j 165 | case "quote", "\"": self = .quote 166 | case "k": self = .k 167 | case "semicolon", ";": self = .semicolon 168 | case "backslash", "\\": self = .backslash 169 | case "comma", ",": self = .comma 170 | case "slash", "/": self = .slash 171 | case "n": self = .n 172 | case "m": self = .m 173 | case "period", ".": self = .period 174 | case "grave": self = .grave 175 | case "keypaddecimal": self = .keypadDecimal 176 | case "keypadmultiply": self = .keypadMultiply 177 | case "keypadplus": self = .keypadPlus 178 | case "keypadclear": self = .keypadClear 179 | case "keypaddivide": self = .keypadDivide 180 | case "keypadenter": self = .keypadEnter 181 | case "keypadminus": self = .keypadMinus 182 | case "keypadequals": self = .keypadEquals 183 | case "keypad0": self = .keypad0 184 | case "keypad1": self = .keypad1 185 | case "keypad2": self = .keypad2 186 | case "keypad3": self = .keypad3 187 | case "keypad4": self = .keypad4 188 | case "keypad5": self = .keypad5 189 | case "keypad6": self = .keypad6 190 | case "keypad7": self = .keypad7 191 | case "keypad8": self = .keypad8 192 | case "keypad9": self = .keypad9 193 | case "return", "\r": self = .return 194 | case "tab", "\t": self = .tab 195 | case "space", " ": self = .space 196 | case "delete": self = .delete 197 | case "escape": self = .escape 198 | case "command": self = .command 199 | case "shift": self = .shift 200 | case "capsLock": self = .capsLock 201 | case "option": self = .option 202 | case "control": self = .control 203 | case "rightcommand": self = .rightCommand 204 | case "rightshift": self = .rightShift 205 | case "rightoption": self = .rightOption 206 | case "rightcontrol": self = .rightControl 207 | case "function": self = .function 208 | case "f17": self = .f17 209 | case "volumeup": self = .volumeUp 210 | case "volumedown": self = .volumeDown 211 | case "mute": self = .mute 212 | case "f18": self = .f18 213 | case "f19": self = .f19 214 | case "f20": self = .f20 215 | case "f5": self = .f5 216 | case "f6": self = .f6 217 | case "f7": self = .f7 218 | case "f3": self = .f3 219 | case "f8": self = .f8 220 | case "f9": self = .f9 221 | case "f11": self = .f11 222 | case "f13": self = .f13 223 | case "f16": self = .f16 224 | case "f14": self = .f14 225 | case "f10": self = .f10 226 | case "f12": self = .f12 227 | case "f15": self = .f15 228 | case "help": self = .help 229 | case "home": self = .home 230 | case "pageup": self = .pageUp 231 | case "forwarddelete": self = .forwardDelete 232 | case "f4": self = .f4 233 | case "end": self = .end 234 | case "f2": self = .f2 235 | case "pagedown": self = .pageDown 236 | case "f1": self = .f1 237 | case "leftarrow": self = .leftArrow 238 | case "rightarrow": self = .rightArrow 239 | case "downarrow": self = .downArrow 240 | case "uparrow": self = .upArrow 241 | default: return nil 242 | } 243 | } 244 | 245 | public init?(carbonKeyCode: UInt32) { 246 | switch carbonKeyCode { 247 | case UInt32(kVK_ANSI_A): self = .a 248 | case UInt32(kVK_ANSI_S): self = .s 249 | case UInt32(kVK_ANSI_D): self = .d 250 | case UInt32(kVK_ANSI_F): self = .f 251 | case UInt32(kVK_ANSI_H): self = .h 252 | case UInt32(kVK_ANSI_G): self = .g 253 | case UInt32(kVK_ANSI_Z): self = .z 254 | case UInt32(kVK_ANSI_X): self = .x 255 | case UInt32(kVK_ANSI_C): self = .c 256 | case UInt32(kVK_ANSI_V): self = .v 257 | case UInt32(kVK_ANSI_B): self = .b 258 | case UInt32(kVK_ANSI_Q): self = .q 259 | case UInt32(kVK_ANSI_W): self = .w 260 | case UInt32(kVK_ANSI_E): self = .e 261 | case UInt32(kVK_ANSI_R): self = .r 262 | case UInt32(kVK_ANSI_Y): self = .y 263 | case UInt32(kVK_ANSI_T): self = .t 264 | case UInt32(kVK_ANSI_1): self = .one 265 | case UInt32(kVK_ANSI_2): self = .two 266 | case UInt32(kVK_ANSI_3): self = .three 267 | case UInt32(kVK_ANSI_4): self = .four 268 | case UInt32(kVK_ANSI_6): self = .six 269 | case UInt32(kVK_ANSI_5): self = .five 270 | case UInt32(kVK_ANSI_Equal): self = .equal 271 | case UInt32(kVK_ANSI_9): self = .nine 272 | case UInt32(kVK_ANSI_7): self = .seven 273 | case UInt32(kVK_ANSI_Minus): self = .minus 274 | case UInt32(kVK_ANSI_8): self = .eight 275 | case UInt32(kVK_ANSI_0): self = .zero 276 | case UInt32(kVK_ANSI_RightBracket): self = .rightBracket 277 | case UInt32(kVK_ANSI_O): self = .o 278 | case UInt32(kVK_ANSI_U): self = .u 279 | case UInt32(kVK_ANSI_LeftBracket): self = .leftBracket 280 | case UInt32(kVK_ANSI_I): self = .i 281 | case UInt32(kVK_ANSI_P): self = .p 282 | case UInt32(kVK_ANSI_L): self = .l 283 | case UInt32(kVK_ANSI_J): self = .j 284 | case UInt32(kVK_ANSI_Quote): self = .quote 285 | case UInt32(kVK_ANSI_K): self = .k 286 | case UInt32(kVK_ANSI_Semicolon): self = .semicolon 287 | case UInt32(kVK_ANSI_Backslash): self = .backslash 288 | case UInt32(kVK_ANSI_Comma): self = .comma 289 | case UInt32(kVK_ANSI_Slash): self = .slash 290 | case UInt32(kVK_ANSI_N): self = .n 291 | case UInt32(kVK_ANSI_M): self = .m 292 | case UInt32(kVK_ANSI_Period): self = .period 293 | case UInt32(kVK_ANSI_Grave): self = .grave 294 | case UInt32(kVK_ANSI_KeypadDecimal): self = .keypadDecimal 295 | case UInt32(kVK_ANSI_KeypadMultiply): self = .keypadMultiply 296 | case UInt32(kVK_ANSI_KeypadPlus): self = .keypadPlus 297 | case UInt32(kVK_ANSI_KeypadClear): self = .keypadClear 298 | case UInt32(kVK_ANSI_KeypadDivide): self = .keypadDivide 299 | case UInt32(kVK_ANSI_KeypadEnter): self = .keypadEnter 300 | case UInt32(kVK_ANSI_KeypadMinus): self = .keypadMinus 301 | case UInt32(kVK_ANSI_KeypadEquals): self = .keypadEquals 302 | case UInt32(kVK_ANSI_Keypad0): self = .keypad0 303 | case UInt32(kVK_ANSI_Keypad1): self = .keypad1 304 | case UInt32(kVK_ANSI_Keypad2): self = .keypad2 305 | case UInt32(kVK_ANSI_Keypad3): self = .keypad3 306 | case UInt32(kVK_ANSI_Keypad4): self = .keypad4 307 | case UInt32(kVK_ANSI_Keypad5): self = .keypad5 308 | case UInt32(kVK_ANSI_Keypad6): self = .keypad6 309 | case UInt32(kVK_ANSI_Keypad7): self = .keypad7 310 | case UInt32(kVK_ANSI_Keypad8): self = .keypad8 311 | case UInt32(kVK_ANSI_Keypad9): self = .keypad9 312 | case UInt32(kVK_Return): self = .`return` 313 | case UInt32(kVK_Tab): self = .tab 314 | case UInt32(kVK_Space): self = .space 315 | case UInt32(kVK_Delete): self = .delete 316 | case UInt32(kVK_Escape): self = .escape 317 | case UInt32(kVK_Command): self = .command 318 | case UInt32(kVK_Shift): self = .shift 319 | case UInt32(kVK_CapsLock): self = .capsLock 320 | case UInt32(kVK_Option): self = .option 321 | case UInt32(kVK_Control): self = .control 322 | case UInt32(kVK_RightCommand): self = .rightCommand 323 | case UInt32(kVK_RightShift): self = .rightShift 324 | case UInt32(kVK_RightOption): self = .rightOption 325 | case UInt32(kVK_RightControl): self = .rightControl 326 | case UInt32(kVK_Function): self = .function 327 | case UInt32(kVK_F17): self = .f17 328 | case UInt32(kVK_VolumeUp): self = .volumeUp 329 | case UInt32(kVK_VolumeDown): self = .volumeDown 330 | case UInt32(kVK_Mute): self = .mute 331 | case UInt32(kVK_F18): self = .f18 332 | case UInt32(kVK_F19): self = .f19 333 | case UInt32(kVK_F20): self = .f20 334 | case UInt32(kVK_F5): self = .f5 335 | case UInt32(kVK_F6): self = .f6 336 | case UInt32(kVK_F7): self = .f7 337 | case UInt32(kVK_F3): self = .f3 338 | case UInt32(kVK_F8): self = .f8 339 | case UInt32(kVK_F9): self = .f9 340 | case UInt32(kVK_F11): self = .f11 341 | case UInt32(kVK_F13): self = .f13 342 | case UInt32(kVK_F16): self = .f16 343 | case UInt32(kVK_F14): self = .f14 344 | case UInt32(kVK_F10): self = .f10 345 | case UInt32(kVK_F12): self = .f12 346 | case UInt32(kVK_F15): self = .f15 347 | case UInt32(kVK_Help): self = .help 348 | case UInt32(kVK_Home): self = .home 349 | case UInt32(kVK_PageUp): self = .pageUp 350 | case UInt32(kVK_ForwardDelete): self = .forwardDelete 351 | case UInt32(kVK_F4): self = .f4 352 | case UInt32(kVK_End): self = .end 353 | case UInt32(kVK_F2): self = .f2 354 | case UInt32(kVK_PageDown): self = .pageDown 355 | case UInt32(kVK_F1): self = .f1 356 | case UInt32(kVK_LeftArrow): self = .leftArrow 357 | case UInt32(kVK_RightArrow): self = .rightArrow 358 | case UInt32(kVK_DownArrow): self = .downArrow 359 | case UInt32(kVK_UpArrow): self = .upArrow 360 | default: return nil 361 | } 362 | } 363 | 364 | public var carbonKeyCode: UInt32 { 365 | switch self { 366 | case .a: return UInt32(kVK_ANSI_A) 367 | case .s: return UInt32(kVK_ANSI_S) 368 | case .d: return UInt32(kVK_ANSI_D) 369 | case .f: return UInt32(kVK_ANSI_F) 370 | case .h: return UInt32(kVK_ANSI_H) 371 | case .g: return UInt32(kVK_ANSI_G) 372 | case .z: return UInt32(kVK_ANSI_Z) 373 | case .x: return UInt32(kVK_ANSI_X) 374 | case .c: return UInt32(kVK_ANSI_C) 375 | case .v: return UInt32(kVK_ANSI_V) 376 | case .b: return UInt32(kVK_ANSI_B) 377 | case .q: return UInt32(kVK_ANSI_Q) 378 | case .w: return UInt32(kVK_ANSI_W) 379 | case .e: return UInt32(kVK_ANSI_E) 380 | case .r: return UInt32(kVK_ANSI_R) 381 | case .y: return UInt32(kVK_ANSI_Y) 382 | case .t: return UInt32(kVK_ANSI_T) 383 | case .one: return UInt32(kVK_ANSI_1) 384 | case .two: return UInt32(kVK_ANSI_2) 385 | case .three: return UInt32(kVK_ANSI_3) 386 | case .four: return UInt32(kVK_ANSI_4) 387 | case .six: return UInt32(kVK_ANSI_6) 388 | case .five: return UInt32(kVK_ANSI_5) 389 | case .equal: return UInt32(kVK_ANSI_Equal) 390 | case .nine: return UInt32(kVK_ANSI_9) 391 | case .seven: return UInt32(kVK_ANSI_7) 392 | case .minus: return UInt32(kVK_ANSI_Minus) 393 | case .eight: return UInt32(kVK_ANSI_8) 394 | case .zero: return UInt32(kVK_ANSI_0) 395 | case .rightBracket: return UInt32(kVK_ANSI_RightBracket) 396 | case .o: return UInt32(kVK_ANSI_O) 397 | case .u: return UInt32(kVK_ANSI_U) 398 | case .leftBracket: return UInt32(kVK_ANSI_LeftBracket) 399 | case .i: return UInt32(kVK_ANSI_I) 400 | case .p: return UInt32(kVK_ANSI_P) 401 | case .l: return UInt32(kVK_ANSI_L) 402 | case .j: return UInt32(kVK_ANSI_J) 403 | case .quote: return UInt32(kVK_ANSI_Quote) 404 | case .k: return UInt32(kVK_ANSI_K) 405 | case .semicolon: return UInt32(kVK_ANSI_Semicolon) 406 | case .backslash: return UInt32(kVK_ANSI_Backslash) 407 | case .comma: return UInt32(kVK_ANSI_Comma) 408 | case .slash: return UInt32(kVK_ANSI_Slash) 409 | case .n: return UInt32(kVK_ANSI_N) 410 | case .m: return UInt32(kVK_ANSI_M) 411 | case .period: return UInt32(kVK_ANSI_Period) 412 | case .grave: return UInt32(kVK_ANSI_Grave) 413 | case .keypadDecimal: return UInt32(kVK_ANSI_KeypadDecimal) 414 | case .keypadMultiply: return UInt32(kVK_ANSI_KeypadMultiply) 415 | case .keypadPlus: return UInt32(kVK_ANSI_KeypadPlus) 416 | case .keypadClear: return UInt32(kVK_ANSI_KeypadClear) 417 | case .keypadDivide: return UInt32(kVK_ANSI_KeypadDivide) 418 | case .keypadEnter: return UInt32(kVK_ANSI_KeypadEnter) 419 | case .keypadMinus: return UInt32(kVK_ANSI_KeypadMinus) 420 | case .keypadEquals: return UInt32(kVK_ANSI_KeypadEquals) 421 | case .keypad0: return UInt32(kVK_ANSI_Keypad0) 422 | case .keypad1: return UInt32(kVK_ANSI_Keypad1) 423 | case .keypad2: return UInt32(kVK_ANSI_Keypad2) 424 | case .keypad3: return UInt32(kVK_ANSI_Keypad3) 425 | case .keypad4: return UInt32(kVK_ANSI_Keypad4) 426 | case .keypad5: return UInt32(kVK_ANSI_Keypad5) 427 | case .keypad6: return UInt32(kVK_ANSI_Keypad6) 428 | case .keypad7: return UInt32(kVK_ANSI_Keypad7) 429 | case .keypad8: return UInt32(kVK_ANSI_Keypad8) 430 | case .keypad9: return UInt32(kVK_ANSI_Keypad9) 431 | case .`return`: return UInt32(kVK_Return) 432 | case .tab: return UInt32(kVK_Tab) 433 | case .space: return UInt32(kVK_Space) 434 | case .delete: return UInt32(kVK_Delete) 435 | case .escape: return UInt32(kVK_Escape) 436 | case .command: return UInt32(kVK_Command) 437 | case .shift: return UInt32(kVK_Shift) 438 | case .capsLock: return UInt32(kVK_CapsLock) 439 | case .option: return UInt32(kVK_Option) 440 | case .control: return UInt32(kVK_Control) 441 | case .rightCommand: return UInt32(kVK_RightCommand) 442 | case .rightShift: return UInt32(kVK_RightShift) 443 | case .rightOption: return UInt32(kVK_RightOption) 444 | case .rightControl: return UInt32(kVK_RightControl) 445 | case .function: return UInt32(kVK_Function) 446 | case .f17: return UInt32(kVK_F17) 447 | case .volumeUp: return UInt32(kVK_VolumeUp) 448 | case .volumeDown: return UInt32(kVK_VolumeDown) 449 | case .mute: return UInt32(kVK_Mute) 450 | case .f18: return UInt32(kVK_F18) 451 | case .f19: return UInt32(kVK_F19) 452 | case .f20: return UInt32(kVK_F20) 453 | case .f5: return UInt32(kVK_F5) 454 | case .f6: return UInt32(kVK_F6) 455 | case .f7: return UInt32(kVK_F7) 456 | case .f3: return UInt32(kVK_F3) 457 | case .f8: return UInt32(kVK_F8) 458 | case .f9: return UInt32(kVK_F9) 459 | case .f11: return UInt32(kVK_F11) 460 | case .f13: return UInt32(kVK_F13) 461 | case .f16: return UInt32(kVK_F16) 462 | case .f14: return UInt32(kVK_F14) 463 | case .f10: return UInt32(kVK_F10) 464 | case .f12: return UInt32(kVK_F12) 465 | case .f15: return UInt32(kVK_F15) 466 | case .help: return UInt32(kVK_Help) 467 | case .home: return UInt32(kVK_Home) 468 | case .pageUp: return UInt32(kVK_PageUp) 469 | case .forwardDelete: return UInt32(kVK_ForwardDelete) 470 | case .f4: return UInt32(kVK_F4) 471 | case .end: return UInt32(kVK_End) 472 | case .f2: return UInt32(kVK_F2) 473 | case .pageDown: return UInt32(kVK_PageDown) 474 | case .f1: return UInt32(kVK_F1) 475 | case .leftArrow: return UInt32(kVK_LeftArrow) 476 | case .rightArrow: return UInt32(kVK_RightArrow) 477 | case .downArrow: return UInt32(kVK_DownArrow) 478 | case .upArrow: return UInt32(kVK_UpArrow) 479 | } 480 | } 481 | } 482 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Sources/HotKey/KeyCombo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarbonKeyCombo.swift 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | 11 | public struct KeyCombo { 12 | 13 | // MARK: - Properties 14 | 15 | public var carbonKeyCode: UInt32 16 | public var carbonModifiers: UInt32 17 | 18 | public var key: Key? { 19 | get { 20 | return Key(carbonKeyCode: carbonKeyCode) 21 | } 22 | 23 | set { 24 | carbonKeyCode = newValue?.carbonKeyCode ?? 0 25 | } 26 | } 27 | 28 | public var modifiers: NSEvent.ModifierFlags { 29 | get { 30 | return NSEvent.ModifierFlags(carbonFlags: carbonModifiers) 31 | } 32 | 33 | set { 34 | carbonModifiers = modifiers.carbonFlags 35 | } 36 | } 37 | 38 | public var isValid: Bool { 39 | return carbonKeyCode >= 0 40 | } 41 | 42 | 43 | // MARK: - Initializers 44 | 45 | public init(carbonKeyCode: UInt32, carbonModifiers: UInt32 = 0) { 46 | self.carbonKeyCode = carbonKeyCode 47 | self.carbonModifiers = carbonModifiers 48 | } 49 | 50 | public init(key: Key, modifiers: NSEvent.ModifierFlags = []) { 51 | self.carbonKeyCode = key.carbonKeyCode 52 | self.carbonModifiers = modifiers.carbonFlags 53 | } 54 | 55 | 56 | // MARK: - Converting Keys 57 | 58 | public static func carbonKeyCodeToString(_ carbonKeyCode: UInt32) -> String? { 59 | return nil 60 | } 61 | } 62 | 63 | 64 | extension KeyCombo { 65 | public var dictionary: [String: Any] { 66 | return [ 67 | "keyCode": Int(carbonKeyCode), 68 | "modifiers": Int(carbonModifiers) 69 | ] 70 | } 71 | 72 | public init?(dictionary: [String: Any]) { 73 | guard let keyCode = dictionary["keyCode"] as? Int, 74 | let modifiers = dictionary["modifiers"] as? Int 75 | else { 76 | return nil 77 | } 78 | 79 | self.init(carbonKeyCode: UInt32(keyCode), carbonModifiers: UInt32(modifiers)) 80 | } 81 | } 82 | 83 | 84 | extension KeyCombo: Equatable { 85 | public static func == (lhs: KeyCombo, rhs: KeyCombo) -> Bool { 86 | return lhs.carbonKeyCode == rhs.carbonKeyCode && lhs.carbonModifiers == rhs.carbonModifiers 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Sources/HotKey/NSEventModifierFlags+HotKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSEventModifierFlags+HotKey.swift 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import Carbon 11 | 12 | extension NSEvent.ModifierFlags { 13 | public var carbonFlags: UInt32 { 14 | var carbonFlags: UInt32 = 0 15 | 16 | if contains(.command) { 17 | carbonFlags |= UInt32(cmdKey) 18 | } 19 | 20 | if contains(.option) { 21 | carbonFlags |= UInt32(optionKey) 22 | } 23 | 24 | if contains(.control) { 25 | carbonFlags |= UInt32(controlKey) 26 | } 27 | 28 | if contains(.shift) { 29 | carbonFlags |= UInt32(shiftKey) 30 | } 31 | 32 | return carbonFlags 33 | } 34 | 35 | public init(carbonFlags: UInt32) { 36 | self.init() 37 | 38 | if carbonFlags & UInt32(cmdKey) == UInt32(cmdKey) { 39 | insert(.command) 40 | } 41 | 42 | if carbonFlags & UInt32(optionKey) == UInt32(optionKey) { 43 | insert(.option) 44 | } 45 | 46 | if carbonFlags & UInt32(controlKey) == UInt32(controlKey) { 47 | insert(.control) 48 | } 49 | 50 | if carbonFlags & UInt32(shiftKey) == UInt32(shiftKey) { 51 | insert(.shift) 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Support/HotKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // HotKey.h 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | //! Project version number for HotKey. 12 | FOUNDATION_EXPORT double HotKeyVersionNumber; 13 | 14 | //! Project version string for HotKey. 15 | FOUNDATION_EXPORT const unsigned char HotKeyVersionString[]; 16 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Support/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.1 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2017 Sam Soffes. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Support/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Tests/HotKeyTests/KeyComboTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyComboTests.swift 3 | // HotKeyTests 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import HotKey 11 | 12 | final class KeyComboTests: XCTestCase { 13 | func testSerialization() { 14 | let keyCombo = KeyCombo(key: .c, modifiers: .command) 15 | 16 | let dictionary = keyCombo.dictionary 17 | XCTAssertEqual(8, dictionary["keyCode"] as! Int) 18 | XCTAssertEqual(256, dictionary["modifiers"] as! Int) 19 | 20 | let keyCombo2 = KeyCombo(dictionary: dictionary)! 21 | XCTAssertEqual(keyCombo.key, keyCombo2.key) 22 | XCTAssertEqual(keyCombo.modifiers, keyCombo2.modifiers) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Carthage/Checkouts/HotKey/Tests/HotKeyTests/ModifierFlagsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ModifierFlagsTests.swift 3 | // HotKey 4 | // 5 | // Created by Sam Soffes on 7/21/17. 6 | // Copyright © 2017 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import AppKit 11 | import Carbon 12 | import HotKey 13 | 14 | final class ModiferFlagsTests: XCTestCase { 15 | func testCarbonToCocoaConversion() { 16 | var cocoa = NSEvent.ModifierFlags() 17 | cocoa.insert(.command) 18 | XCTAssertEqual(NSEvent.ModifierFlags(carbonFlags: UInt32(cmdKey)), cocoa) 19 | 20 | cocoa.insert(.control) 21 | cocoa.insert(.option) 22 | XCTAssertEqual(NSEvent.ModifierFlags(carbonFlags: UInt32(cmdKey|controlKey|optionKey)), cocoa) 23 | } 24 | 25 | func testCocoaToCarbonConversion() { 26 | var cocoa = NSEvent.ModifierFlags() 27 | cocoa.insert(.command) 28 | XCTAssertEqual(UInt32(cmdKey), cocoa.carbonFlags) 29 | 30 | cocoa.insert(.control) 31 | cocoa.insert(.option) 32 | XCTAssertEqual(UInt32(cmdKey|controlKey|optionKey), cocoa.carbonFlags) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Josh Dunsterville 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Open Figma.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma.dmg -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CC709A80219E3B560051DCAB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC709A7F219E3B560051DCAB /* AppDelegate.swift */; }; 11 | CC709A82219E3B560051DCAB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC709A81219E3B560051DCAB /* ViewController.swift */; }; 12 | CC709A84219E3B580051DCAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CC709A83219E3B580051DCAB /* Assets.xcassets */; }; 13 | CC709A87219E3B580051DCAB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CC709A85219E3B580051DCAB /* Main.storyboard */; }; 14 | CCDF76E621A3D79D0084C06D /* HotKey.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = CCDF76E421A3D79D0084C06D /* HotKey.framework.dSYM */; }; 15 | CCDF76E721A3D79D0084C06D /* HotKey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCDF76E521A3D79D0084C06D /* HotKey.framework */; }; 16 | CCDF76E921A3D9430084C06D /* HotKey.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCDF76E521A3D79D0084C06D /* HotKey.framework */; }; 17 | CCDF76EA21A3D9430084C06D /* HotKey.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = CCDF76E521A3D79D0084C06D /* HotKey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | CCDF76ED21A3D9A40084C06D /* HotKey.framework.dSYM in CopyFiles */ = {isa = PBXBuildFile; fileRef = CCDF76E421A3D79D0084C06D /* HotKey.framework.dSYM */; }; 19 | CCDF76EF21A3EAE50084C06D /* StatusMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCDF76EE21A3EAE50084C06D /* StatusMenuController.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | CCDF76EB21A3D9430084C06D /* Embed Frameworks */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 10; 28 | files = ( 29 | CCDF76EA21A3D9430084C06D /* HotKey.framework in Embed Frameworks */, 30 | ); 31 | name = "Embed Frameworks"; 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | CCDF76EC21A3D9940084C06D /* CopyFiles */ = { 35 | isa = PBXCopyFilesBuildPhase; 36 | buildActionMask = 2147483647; 37 | dstPath = ""; 38 | dstSubfolderSpec = 16; 39 | files = ( 40 | CCDF76ED21A3D9A40084C06D /* HotKey.framework.dSYM in CopyFiles */, 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXCopyFilesBuildPhase section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | CC709A7C219E3B560051DCAB /* Open Figma.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Open Figma.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | CC709A7F219E3B560051DCAB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 49 | CC709A81219E3B560051DCAB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 50 | CC709A83219E3B580051DCAB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | CC709A86219E3B580051DCAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 52 | CC709A88219E3B580051DCAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | CC709A89219E3B580051DCAB /* Open_Figma.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Open_Figma.entitlements; sourceTree = ""; }; 54 | CCDF76E421A3D79D0084C06D /* HotKey.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = HotKey.framework.dSYM; path = Carthage/Build/Mac/HotKey.framework.dSYM; sourceTree = ""; }; 55 | CCDF76E521A3D79D0084C06D /* HotKey.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HotKey.framework; path = Carthage/Build/Mac/HotKey.framework; sourceTree = ""; }; 56 | CCDF76EE21A3EAE50084C06D /* StatusMenuController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusMenuController.swift; sourceTree = ""; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | CC709A79219E3B560051DCAB /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | CCDF76E921A3D9430084C06D /* HotKey.framework in Frameworks */, 65 | CCDF76E721A3D79D0084C06D /* HotKey.framework in Frameworks */, 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | /* End PBXFrameworksBuildPhase section */ 70 | 71 | /* Begin PBXGroup section */ 72 | CC709A73219E3B560051DCAB = { 73 | isa = PBXGroup; 74 | children = ( 75 | CC709A7E219E3B560051DCAB /* Open Figma */, 76 | CC709A7D219E3B560051DCAB /* Products */, 77 | CCDF76E521A3D79D0084C06D /* HotKey.framework */, 78 | CCDF76E421A3D79D0084C06D /* HotKey.framework.dSYM */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | CC709A7D219E3B560051DCAB /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | CC709A7C219E3B560051DCAB /* Open Figma.app */, 86 | ); 87 | name = Products; 88 | sourceTree = ""; 89 | }; 90 | CC709A7E219E3B560051DCAB /* Open Figma */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | CC709A7F219E3B560051DCAB /* AppDelegate.swift */, 94 | CCDF76EE21A3EAE50084C06D /* StatusMenuController.swift */, 95 | CC709A81219E3B560051DCAB /* ViewController.swift */, 96 | CC709A83219E3B580051DCAB /* Assets.xcassets */, 97 | CC709A85219E3B580051DCAB /* Main.storyboard */, 98 | CC709A88219E3B580051DCAB /* Info.plist */, 99 | CC709A89219E3B580051DCAB /* Open_Figma.entitlements */, 100 | ); 101 | path = "Open Figma"; 102 | sourceTree = ""; 103 | }; 104 | /* End PBXGroup section */ 105 | 106 | /* Begin PBXNativeTarget section */ 107 | CC709A7B219E3B560051DCAB /* Open Figma */ = { 108 | isa = PBXNativeTarget; 109 | buildConfigurationList = CC709A8C219E3B580051DCAB /* Build configuration list for PBXNativeTarget "Open Figma" */; 110 | buildPhases = ( 111 | CC709A78219E3B560051DCAB /* Sources */, 112 | CC709A79219E3B560051DCAB /* Frameworks */, 113 | CC709A7A219E3B560051DCAB /* Resources */, 114 | CCDF76E821A3D7C10084C06D /* ShellScript */, 115 | CCDF76EB21A3D9430084C06D /* Embed Frameworks */, 116 | CCDF76EC21A3D9940084C06D /* CopyFiles */, 117 | ); 118 | buildRules = ( 119 | ); 120 | dependencies = ( 121 | ); 122 | name = "Open Figma"; 123 | productName = "Open Figma"; 124 | productReference = CC709A7C219E3B560051DCAB /* Open Figma.app */; 125 | productType = "com.apple.product-type.application"; 126 | }; 127 | /* End PBXNativeTarget section */ 128 | 129 | /* Begin PBXProject section */ 130 | CC709A74219E3B560051DCAB /* Project object */ = { 131 | isa = PBXProject; 132 | attributes = { 133 | LastSwiftUpdateCheck = 1010; 134 | LastUpgradeCheck = 1010; 135 | ORGANIZATIONNAME = "Josh Dunsterville"; 136 | TargetAttributes = { 137 | CC709A7B219E3B560051DCAB = { 138 | CreatedOnToolsVersion = 10.1; 139 | SystemCapabilities = { 140 | com.apple.HardenedRuntime = { 141 | enabled = 1; 142 | }; 143 | }; 144 | }; 145 | }; 146 | }; 147 | buildConfigurationList = CC709A77219E3B560051DCAB /* Build configuration list for PBXProject "Open Figma" */; 148 | compatibilityVersion = "Xcode 9.3"; 149 | developmentRegion = en; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | en, 153 | Base, 154 | ); 155 | mainGroup = CC709A73219E3B560051DCAB; 156 | productRefGroup = CC709A7D219E3B560051DCAB /* Products */; 157 | projectDirPath = ""; 158 | projectRoot = ""; 159 | targets = ( 160 | CC709A7B219E3B560051DCAB /* Open Figma */, 161 | ); 162 | }; 163 | /* End PBXProject section */ 164 | 165 | /* Begin PBXResourcesBuildPhase section */ 166 | CC709A7A219E3B560051DCAB /* Resources */ = { 167 | isa = PBXResourcesBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | CC709A84219E3B580051DCAB /* Assets.xcassets in Resources */, 171 | CCDF76E621A3D79D0084C06D /* HotKey.framework.dSYM in Resources */, 172 | CC709A87219E3B580051DCAB /* Main.storyboard in Resources */, 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | /* End PBXResourcesBuildPhase section */ 177 | 178 | /* Begin PBXShellScriptBuildPhase section */ 179 | CCDF76E821A3D7C10084C06D /* ShellScript */ = { 180 | isa = PBXShellScriptBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | ); 184 | inputFileListPaths = ( 185 | ); 186 | inputPaths = ( 187 | ); 188 | outputFileListPaths = ( 189 | ); 190 | outputPaths = ( 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | shellPath = /bin/sh; 194 | shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\n"; 195 | }; 196 | /* End PBXShellScriptBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | CC709A78219E3B560051DCAB /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | CCDF76EF21A3EAE50084C06D /* StatusMenuController.swift in Sources */, 204 | CC709A82219E3B560051DCAB /* ViewController.swift in Sources */, 205 | CC709A80219E3B560051DCAB /* AppDelegate.swift in Sources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXSourcesBuildPhase section */ 210 | 211 | /* Begin PBXVariantGroup section */ 212 | CC709A85219E3B580051DCAB /* Main.storyboard */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | CC709A86219E3B580051DCAB /* Base */, 216 | ); 217 | name = Main.storyboard; 218 | sourceTree = ""; 219 | }; 220 | /* End PBXVariantGroup section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | CC709A8A219E3B580051DCAB /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | CLANG_ANALYZER_NONNULL = YES; 228 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 229 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 230 | CLANG_CXX_LIBRARY = "libc++"; 231 | CLANG_ENABLE_MODULES = YES; 232 | CLANG_ENABLE_OBJC_ARC = YES; 233 | CLANG_ENABLE_OBJC_WEAK = YES; 234 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 235 | CLANG_WARN_BOOL_CONVERSION = YES; 236 | CLANG_WARN_COMMA = YES; 237 | CLANG_WARN_CONSTANT_CONVERSION = YES; 238 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 239 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 240 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 241 | CLANG_WARN_EMPTY_BODY = YES; 242 | CLANG_WARN_ENUM_CONVERSION = YES; 243 | CLANG_WARN_INFINITE_RECURSION = YES; 244 | CLANG_WARN_INT_CONVERSION = YES; 245 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 246 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 247 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 248 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 249 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 250 | CLANG_WARN_STRICT_PROTOTYPES = YES; 251 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 252 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 253 | CLANG_WARN_UNREACHABLE_CODE = YES; 254 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 255 | CODE_SIGN_IDENTITY = "Mac Developer"; 256 | COPY_PHASE_STRIP = NO; 257 | DEBUG_INFORMATION_FORMAT = dwarf; 258 | ENABLE_STRICT_OBJC_MSGSEND = YES; 259 | ENABLE_TESTABILITY = YES; 260 | GCC_C_LANGUAGE_STANDARD = gnu11; 261 | GCC_DYNAMIC_NO_PIC = NO; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_OPTIMIZATION_LEVEL = 0; 264 | GCC_PREPROCESSOR_DEFINITIONS = ( 265 | "DEBUG=1", 266 | "$(inherited)", 267 | ); 268 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 269 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 270 | GCC_WARN_UNDECLARED_SELECTOR = YES; 271 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 272 | GCC_WARN_UNUSED_FUNCTION = YES; 273 | GCC_WARN_UNUSED_VARIABLE = YES; 274 | MACOSX_DEPLOYMENT_TARGET = 10.14; 275 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 276 | MTL_FAST_MATH = YES; 277 | ONLY_ACTIVE_ARCH = YES; 278 | SDKROOT = macosx; 279 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 280 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 281 | }; 282 | name = Debug; 283 | }; 284 | CC709A8B219E3B580051DCAB /* Release */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ALWAYS_SEARCH_USER_PATHS = NO; 288 | CLANG_ANALYZER_NONNULL = YES; 289 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_ENABLE_OBJC_WEAK = YES; 295 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 296 | CLANG_WARN_BOOL_CONVERSION = YES; 297 | CLANG_WARN_COMMA = YES; 298 | CLANG_WARN_CONSTANT_CONVERSION = YES; 299 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 301 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 302 | CLANG_WARN_EMPTY_BODY = YES; 303 | CLANG_WARN_ENUM_CONVERSION = YES; 304 | CLANG_WARN_INFINITE_RECURSION = YES; 305 | CLANG_WARN_INT_CONVERSION = YES; 306 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 307 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 308 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 310 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 311 | CLANG_WARN_STRICT_PROTOTYPES = YES; 312 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 313 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 314 | CLANG_WARN_UNREACHABLE_CODE = YES; 315 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 316 | CODE_SIGN_IDENTITY = "Mac Developer"; 317 | COPY_PHASE_STRIP = NO; 318 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 319 | ENABLE_NS_ASSERTIONS = NO; 320 | ENABLE_STRICT_OBJC_MSGSEND = YES; 321 | GCC_C_LANGUAGE_STANDARD = gnu11; 322 | GCC_NO_COMMON_BLOCKS = YES; 323 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 324 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 325 | GCC_WARN_UNDECLARED_SELECTOR = YES; 326 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 327 | GCC_WARN_UNUSED_FUNCTION = YES; 328 | GCC_WARN_UNUSED_VARIABLE = YES; 329 | MACOSX_DEPLOYMENT_TARGET = 10.14; 330 | MTL_ENABLE_DEBUG_INFO = NO; 331 | MTL_FAST_MATH = YES; 332 | SDKROOT = macosx; 333 | SWIFT_COMPILATION_MODE = wholemodule; 334 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 335 | }; 336 | name = Release; 337 | }; 338 | CC709A8D219E3B580051DCAB /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 342 | CODE_SIGN_ENTITLEMENTS = "Open Figma/Open_Figma.entitlements"; 343 | CODE_SIGN_STYLE = Automatic; 344 | COMBINE_HIDPI_IMAGES = YES; 345 | DEVELOPMENT_TEAM = 7ZJ5MR5T68; 346 | ENABLE_HARDENED_RUNTIME = YES; 347 | FRAMEWORK_SEARCH_PATHS = ( 348 | "$(inherited)", 349 | "$(PROJECT_DIR)/Carthage/Build/Mac", 350 | ); 351 | INFOPLIST_FILE = "Open Figma/Info.plist"; 352 | LD_RUNPATH_SEARCH_PATHS = ( 353 | "$(inherited)", 354 | "@executable_path/../Frameworks", 355 | ); 356 | PRODUCT_BUNDLE_IDENTIFIER = "com.neversitdull.Open-Figma"; 357 | PRODUCT_NAME = "$(TARGET_NAME)"; 358 | SWIFT_VERSION = 4.2; 359 | }; 360 | name = Debug; 361 | }; 362 | CC709A8E219E3B580051DCAB /* Release */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 366 | CODE_SIGN_ENTITLEMENTS = "Open Figma/Open_Figma.entitlements"; 367 | CODE_SIGN_STYLE = Automatic; 368 | COMBINE_HIDPI_IMAGES = YES; 369 | DEVELOPMENT_TEAM = 7ZJ5MR5T68; 370 | ENABLE_HARDENED_RUNTIME = YES; 371 | FRAMEWORK_SEARCH_PATHS = ( 372 | "$(inherited)", 373 | "$(PROJECT_DIR)/Carthage/Build/Mac", 374 | ); 375 | INFOPLIST_FILE = "Open Figma/Info.plist"; 376 | LD_RUNPATH_SEARCH_PATHS = ( 377 | "$(inherited)", 378 | "@executable_path/../Frameworks", 379 | ); 380 | PRODUCT_BUNDLE_IDENTIFIER = "com.neversitdull.Open-Figma"; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | SWIFT_VERSION = 4.2; 383 | }; 384 | name = Release; 385 | }; 386 | /* End XCBuildConfiguration section */ 387 | 388 | /* Begin XCConfigurationList section */ 389 | CC709A77219E3B560051DCAB /* Build configuration list for PBXProject "Open Figma" */ = { 390 | isa = XCConfigurationList; 391 | buildConfigurations = ( 392 | CC709A8A219E3B580051DCAB /* Debug */, 393 | CC709A8B219E3B580051DCAB /* Release */, 394 | ); 395 | defaultConfigurationIsVisible = 0; 396 | defaultConfigurationName = Release; 397 | }; 398 | CC709A8C219E3B580051DCAB /* Build configuration list for PBXNativeTarget "Open Figma" */ = { 399 | isa = XCConfigurationList; 400 | buildConfigurations = ( 401 | CC709A8D219E3B580051DCAB /* Debug */, 402 | CC709A8E219E3B580051DCAB /* Release */, 403 | ); 404 | defaultConfigurationIsVisible = 0; 405 | defaultConfigurationName = Release; 406 | }; 407 | /* End XCConfigurationList section */ 408 | }; 409 | rootObject = CC709A74219E3B560051DCAB /* Project object */; 410 | } 411 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.xcworkspace/xcuserdata/jdunsterville.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma.xcodeproj/project.xcworkspace/xcuserdata/jdunsterville.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.xcworkspace/xcuserdata/jdunsterville.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | EnabledFullIndexStoreVisibility 12 | 13 | IssueFilterStyle 14 | ShowActiveSchemeOnly 15 | LiveSourceIssuesEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/project.xcworkspace/xcuserdata/neversitdull.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma.xcodeproj/project.xcworkspace/xcuserdata/neversitdull.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Open Figma.xcodeproj/xcuserdata/jdunsterville.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/xcuserdata/jdunsterville.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Open Figma.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Open Figma.xcodeproj/xcuserdata/neversitdull.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Open Figma.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Open Figma/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/.DS_Store -------------------------------------------------------------------------------- /Open Figma/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Open Figma 4 | // 5 | // Created by Josh Dunsterville on 11/15/18. 6 | // Copyright © 2018 Josh Dunsterville. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | func applicationDidFinishLaunching(_ aNotification: Notification) { 15 | 16 | 17 | } 18 | 19 | func applicationWillTerminate(_ aNotification: Notification) { 20 | // Insert code here to tear down your application 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/.DS_Store -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "Icon-16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "Icon-32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "Icon-32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "Icon-64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "Icon-128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "Icon-256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "Icon-256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "Icon-512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "Icon-512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "Icon-1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | }, 68 | "properties" : { 69 | "pre-rendered" : true 70 | } 71 | } -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-128.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-16.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-256.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-32.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-512.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/AppIcon.appiconset/Icon-64.png -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/figma-icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "figma-icon@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "template" 23 | } 24 | } -------------------------------------------------------------------------------- /Open Figma/Assets.xcassets/figma-icon.imageset/figma-icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neversitdull/Open-Figma-Desktop/7131d60ea832e973ac8d50b27d173348cd6a2647/Open Figma/Assets.xcassets/figma-icon.imageset/figma-icon@2x.png -------------------------------------------------------------------------------- /Open Figma/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | -------------------------------------------------------------------------------- /Open Figma/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSApplicationCategoryType 24 | public.app-category.graphics-design 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | LSUIElement 28 | 29 | NSHumanReadableCopyright 30 | Copyright © 2018 Josh Dunsterville. All rights reserved. 31 | NSMainStoryboardFile 32 | Main 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /Open Figma/Open_Figma.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.temporary-exception.apple-events 10 | com.Figma.Desktop 11 | 12 | 13 | -------------------------------------------------------------------------------- /Open Figma/StatusMenuController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatusMenuController.swift 3 | // Open Figma 4 | // 5 | // Created by Josh Dunsterville on 11/19/18. 6 | // Copyright © 2018 Josh Dunsterville. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import HotKey 11 | 12 | class StatusMenuController: NSObject { 13 | 14 | /* 15 | ------------------- 16 | Constants 17 | ------------------- 18 | */ 19 | 20 | let hotKey = HotKey(key: .f, modifiers: [.control, .option, .command]) 21 | let pasteboard = NSPasteboard.general 22 | let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength) 23 | let figmaURLType = "figma.com/file" 24 | 25 | /* 26 | ------------------- 27 | Variables 28 | ------------------- 29 | */ 30 | 31 | var bundleIdentifier = "" 32 | var fileURL = "" 33 | var notificationTitle = "" 34 | var notificationSubTitle = "" 35 | var originalURL = "" 36 | 37 | 38 | /* 39 | ------------------- 40 | Outlets 41 | ------------------- 42 | */ 43 | 44 | //Outlet to Menu in Storyboard 45 | @IBOutlet weak var figmaMenu: NSMenu! 46 | 47 | 48 | 49 | /* 50 | ------------------- 51 | Actions 52 | ------------------- 53 | */ 54 | 55 | //Action that runs openFigma 56 | @IBAction func openFigma(_ sender: Any) { 57 | openFigma() 58 | } 59 | 60 | //Action that quits the app 61 | @IBAction func quitApp(_ sender: Any) { 62 | NSApplication.shared.terminate(self) 63 | } 64 | 65 | 66 | 67 | /* 68 | ------------------- 69 | View 70 | ------------------- 71 | */ 72 | 73 | //Sets up the menu 74 | override func awakeFromNib() { 75 | 76 | statusItem.menu = figmaMenu 77 | let icon = NSImage(named: "figma-icon") 78 | 79 | if let button = statusItem.button { 80 | button.image = icon 81 | } 82 | 83 | //Looks for key command to be pressed then calls openFigma 84 | hotKey.keyDownHandler = { 85 | self.openFigma() 86 | } 87 | } 88 | 89 | 90 | /* 91 | ------------------- 92 | Functions 93 | ------------------- 94 | */ 95 | 96 | //Opens a Figma URL in the Desktop APP 97 | func openFigma() { 98 | //Checks to see if clipboard contains any data 99 | if pasteboard.pasteboardItems != nil { 100 | 101 | // Takes clipboard data and adds it to a String 102 | originalURL = pasteboard.string(forType: .string)! 103 | let filePrefix = "figma://" 104 | 105 | // Checks to see if what was copied contains a Figma or Staging URL 106 | if originalURL.localizedStandardContains(figmaURLType) { 107 | // Looks in originalURL up to the index of the word file 108 | if let index = (originalURL.range(of: "file/")?.lowerBound) { 109 | 110 | //Takes everthing starting with the word file and adds it to a new String 111 | let shortenedURL = String(originalURL.suffix(from: index)) 112 | 113 | let customCharacterSet = (CharacterSet(charactersIn: "%").inverted).self 114 | if let encodedURL = shortenedURL.addingPercentEncoding(withAllowedCharacters: customCharacterSet) { 115 | 116 | //Adds filePrefix to the shortenedURL to open inside Figma 117 | fileURL = "\(filePrefix)\(encodedURL)" 118 | 119 | 120 | //Adds string to URL 121 | if let finalURL = URL(string: fileURL) { 122 | 123 | //Show Notification - Opening Figma URL 124 | notificationTitle = "Opening in Figma Desktop" 125 | notificationSubTitle = fileURL 126 | 127 | showNotification() 128 | //Open Figma Desktop 129 | NSWorkspace.shared.open(finalURL) 130 | 131 | } 132 | } 133 | } 134 | 135 | } else { 136 | 137 | //Show notification - No Figma URL Detected 138 | notificationTitle = "No Figma URL Detected" 139 | notificationSubTitle = "Copy a Figma URL to your clipboard and try again" 140 | 141 | showNotification() 142 | 143 | } 144 | } 145 | } 146 | 147 | func openApp(_ named: String, autoLaunch: Bool) -> Bool { 148 | return NSWorkspace.shared.launchApplication(named) 149 | } 150 | 151 | 152 | //Shows Notification 153 | func showNotification() -> Void { 154 | let notification = NSUserNotification() 155 | notification.title = notificationTitle 156 | notification.subtitle = notificationSubTitle 157 | NSUserNotificationCenter.default.deliver(notification) 158 | } 159 | } 160 | 161 | -------------------------------------------------------------------------------- /Open Figma/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Open Figma 4 | // 5 | // Created by Josh Dunsterville on 11/15/18. 6 | // Copyright © 2018 Josh Dunsterville. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override var representedObject: Any? { 20 | didSet { 21 | // Update the view, if already loaded. 22 | } 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This now exists as native functionality within Figma: https://www.figma.com/blog/figma-desktop-app-improvements/ 2 | 3 | 4 | # Open-Figma-Desktop 5 | A Mac Menubar App that helps open Figma URLs in the Figma Desktop App 6 |
7 | _*Note: This is a personal project and not affiliated with Figma_ 8 |
9 |
10 | 11 | ## Installation 12 | 13 | Requires OSX 10.14 or later 14 | 15 | Download the latest release [here](https://github.com/neversitdull/Open-Figma-Desktop/releases). 16 | 17 | Double-click on the .dmg file and drag Open Figma into your Applications folder 18 |
19 |
20 | 21 | ## How to use 22 | Note: Open Figma only works if you have the desktop app installed. You can download it from [here](https://www.figma.com/downloads/). 23 | 24 | 1. Open `Open Figma.app` 25 | 26 | 2. Copy a Figma File URL to your clipboard. You can get this in the share dialogue or by copying it directly from the browser. 27 | Example: `https://wwww.figma.com/file/file-key` 28 | 29 | 3. Click `Open in Desktop App` from the dropdown in the menubar or use the keyboard shortcut `control+option+command+f` 30 | 31 | 4. Voila! The link you just copied should now open in the Desktop App 32 | 33 | 34 | --------------------------------------------------------------------------------