├── Dock Plugin ├── Sources │ ├── SCMCAction.h │ ├── SCMCClickHandler.h │ ├── SCMCCore.h │ ├── Dock.h │ ├── SCMCActionStore.h │ ├── Info.plist │ ├── SCMCActions.h │ ├── SCMCActionStore.m │ ├── SCMCClickHandler.m │ ├── SCMCActions.m │ ├── Init.m │ └── SCMCCore.m └── Dock Plugin.xcodeproj │ └── project.pbxproj ├── .gitignore ├── Preference Pane ├── Sources │ ├── PreferencePane.m │ ├── PreferencePane.h │ ├── Info.plist │ └── Base.lproj │ │ └── PreferencePane.xib └── Preference Pane.xcodeproj │ └── project.pbxproj ├── Shared ├── Sources │ ├── PrefixHeader.pch │ ├── PreferencePaneNames.h │ ├── SCMCEventTapListener.h │ ├── SCMCEventSpec.h │ ├── SCMCHidListener.h │ ├── SCMCConfiguration.h │ ├── SCMCEventSpec.m │ ├── SCMCConfiguration.m │ ├── SCMCEventTapListener.m │ └── SCMCHidListener.m └── Shared.xcodeproj │ └── project.pbxproj ├── Loader Scripting Addition ├── Sources │ ├── SCMC Loader.sdef │ ├── Info.plist │ └── main.m └── Loader Scripting Addition.xcodeproj │ └── project.pbxproj ├── SCMC.xcworkspace └── contents.xcworkspacedata ├── Configuration ├── Generic Mouse │ └── deej.SCMC.plist ├── Template │ └── deej.SCMC.plist ├── Sculpt Comfort 1 │ └── deej.SCMC.plist ├── Sculpt Comfort 2 │ └── deej.SCMC.plist ├── Sculpt Comfort 3 │ └── deej.SCMC.plist └── README.md ├── Loader App ├── Sources │ ├── Info.plist │ └── main.m └── Loader App.xcodeproj │ └── project.pbxproj ├── LICENSE └── README.md /Dock Plugin/Sources/SCMCAction.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCAction.h 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 15.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | typedef void(^SCMCAction)(void); 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pbxuser 3 | !default.pbxuser 4 | *.mode1v3 5 | !default.mode1v3 6 | *.mode2v3 7 | !default.mode2v3 8 | *.perspectivev3 9 | !default.perspectivev3 10 | xcuserdata 11 | *.xccheckout 12 | profile 13 | *.moved-aside 14 | DerivedData 15 | *.hmap 16 | *.ipa 17 | uncrustify.cfg 18 | .idea 19 | -------------------------------------------------------------------------------- /Preference Pane/Sources/PreferencePane.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencePane.m 3 | // Preference Pane 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #import "PreferencePane.h" 10 | 11 | @implementation DeejScmcPreferencePane 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Preference Pane/Sources/PreferencePane.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencePane.h 3 | // Preference Pane 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import PreferencePanes; 10 | 11 | @interface DeejScmcPreferencePane : NSPreferencePane 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Shared/Sources/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | #ifdef FOR_PREFERENCE_PANE 13 | #import "PreferencePaneNames.h" 14 | #endif 15 | 16 | #endif /* PrefixHeader_pch */ 17 | -------------------------------------------------------------------------------- /Loader Scripting Addition/Sources/SCMC Loader.sdef: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Shared/Sources/PreferencePaneNames.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencePaneNames.h 3 | // SharedForPreferencePane 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #define PREF_PANE_NAME(name) DeejScmcPreference ## name 10 | 11 | #define SCMCConfiguration PREF_PANE_NAME(Configuration) 12 | #define SCMCEventSpec PREF_PANE_NAME(EventSpec) 13 | #define SCMCHidListener PREF_PANE_NAME(HidListener) 14 | #define SCMCEventTapListener PREF_PANE_NAME(EventTapListener) 15 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCClickHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCClickHandler.h 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 16.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | @class SCMCActionStore; 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /// @brief Does the actual click handling (including long-click logic). Performs actions. 16 | @interface SCMCClickHandler : NSObject 17 | 18 | - (void)handleClickWithCode:(NSNumber *)code pressed:(BOOL)pressed actionStore:(SCMCActionStore *)actionStore; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /SCMC.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Configuration/Generic Mouse/deej.SCMC.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mission-control 6 | 7 | code 8 | 2 9 | 10 | application-windows 11 | 12 | code 13 | 2 14 | long 15 | 16 | 17 | next-space 18 | 19 | code 20 | 3 21 | 22 | previous-space 23 | 24 | code 25 | 4 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCCore.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCCore.h 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | @class SCMCConfiguration; 12 | @class SCMCActions; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | /** 17 | @brief Main application logic. 18 | @discussion Ties everything together. 19 | Reads configuration, listens to mouse events, and performs actions. 20 | */ 21 | @interface SCMCCore : NSObject 22 | 23 | - (instancetype)init NS_UNAVAILABLE; 24 | + (instancetype)new NS_UNAVAILABLE; 25 | 26 | + (instancetype)startWithConfiguration:(SCMCConfiguration *)configuration actions:(SCMCActions *)actions; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/Dock.h: -------------------------------------------------------------------------------- 1 | // 2 | // Dock.h 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 15.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | // Due to dynamic nature of Objective-C real classes can be casted 12 | // to the protocols below, which is convenient. 13 | // There's no classes that conform to these protocols. 14 | 15 | @protocol SCMCDockSpaces 16 | 17 | - (BOOL)switchToNextSpace:(BOOL)arg; 18 | - (BOOL)switchToPreviousSpace:(BOOL)arg; 19 | 20 | @end 21 | 22 | @protocol SCMCDockExpose 23 | 24 | - (void)MissionControlSwitchToNextSpace:(CGDirectDisplayID)display; 25 | - (void)MissionControlSwitchToPreviousSpace:(CGDirectDisplayID)display; 26 | 27 | @property(nonatomic) unsigned char mode; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCActionStore.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCActionStore.h 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 16.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | #import "SCMCAction.h" 12 | 13 | @class SCMCEventSpec; 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | /// Stores actions. Provides @c empty and @c addedEventCodes convenience properties. 18 | @interface SCMCActionStore : NSObject 19 | 20 | @property(nonatomic, readonly) BOOL empty; 21 | @property(nonatomic, readonly) NSArray *addedEventCodes; 22 | 23 | @property(nonatomic, readonly) NSDictionary *regularActions; 24 | @property(nonatomic, readonly) NSDictionary *longClickActions; 25 | 26 | - (void)addAction:(SCMCAction)action forEvent:(SCMCEventSpec *)eventSpec; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 2.0-alpha.1 19 | CFBundleVersion 20 | 1 21 | NSHumanReadableCopyright 22 | Copyright © 2018 deej. All rights reserved. 23 | 24 | 25 | -------------------------------------------------------------------------------- /Configuration/Template/deej.SCMC.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product-id 6 | PID 7 | vendor-id 8 | VID 9 | 10 | mission-control 11 | 12 | type 13 | 0 for Event Tap, 1 for HID 14 | code 15 | BUTTON CODE (HID usage, or button number for Event Tap) 16 | long 17 | 18 | 19 | application-windows 20 | 21 | show-desktop 22 | 23 | launchpad 24 | 25 | next-space 26 | 27 | previous-space 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Configuration/Sculpt Comfort 1/deej.SCMC.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product-id 6 | 0x07A2 7 | vendor-id 8 | 0x045E 9 | 10 | mission-control 11 | 12 | type 13 | 1 14 | code 15 | 227 16 | 17 | application-windows 18 | 19 | type 20 | 1 21 | code 22 | 227 23 | long 24 | 25 | 26 | next-space 27 | 28 | code 29 | 3 30 | 31 | previous-space 32 | 33 | code 34 | 4 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCEventTapListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCEventTapListener.h 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | typedef void(^SCMCEventTapListenerCallback)(int64_t code, BOOL pressed); 14 | 15 | /** 16 | Low-level Event Tap listener. 17 | Does all the dirty work like calling C APIs and discarding unwanted events. 18 | */ 19 | @interface SCMCEventTapListener : NSObject 20 | 21 | - (instancetype)init NS_UNAVAILABLE; 22 | + (instancetype)new NS_UNAVAILABLE; 23 | 24 | /// @param acceptedCodes Codes that are allowed to be passed to the callback. 25 | /// @param callback Invoked whenever an appropriate event occurs. 26 | - (instancetype)initWithAcceptedCodes:(NSArray *)acceptedCodes callback:(SCMCEventTapListenerCallback)callback; 27 | 28 | - (void)start; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Configuration/Sculpt Comfort 2/deej.SCMC.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product-id 6 | 0x07A2 7 | vendor-id 8 | 0x045E 9 | 10 | mission-control 11 | 12 | type 13 | 1 14 | code 15 | 227 16 | 17 | application-windows 18 | 19 | type 20 | 1 21 | code 22 | 227 23 | long 24 | 25 | 26 | next-space 27 | 28 | type 29 | 1 30 | code 31 | 43 32 | 33 | previous-space 34 | 35 | type 36 | 1 37 | code 38 | 42 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Configuration/Sculpt Comfort 3/deej.SCMC.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product-id 6 | 0x07A2 7 | vendor-id 8 | 0x045E 9 | 10 | mission-control 11 | 12 | type 13 | 1 14 | code 15 | 64817 16 | 17 | application-windows 18 | 19 | type 20 | 1 21 | code 22 | 64817 23 | long 24 | 25 | 26 | next-space 27 | 28 | type 29 | 1 30 | code 31 | 64816 32 | 33 | previous-space 34 | 35 | type 36 | 1 37 | code 38 | 64809 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Loader App/Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 2.0-alpha.1 19 | CFBundleVersion 20 | 1 21 | LSMinimumSystemVersion 22 | $(MACOSX_DEPLOYMENT_TARGET) 23 | LSUIElement 24 | 25 | NSHumanReadableCopyright 26 | Copyright © 2018 deej. All rights reserved. 27 | 28 | 29 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCActions.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCActions.h 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 15.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | #import "SCMCAction.h" 12 | 13 | @protocol SCMCDockSpaces; 14 | @protocol SCMCDockExpose; 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | /// @brief A collection of actions available to user. 19 | @interface SCMCActions : NSObject 20 | 21 | + (instancetype)new NS_UNAVAILABLE; 22 | - (instancetype)init NS_UNAVAILABLE; 23 | 24 | - (instancetype)initWithSpaces:(__weak id)spaces expose:(__weak id)expose; 25 | 26 | @property(nonatomic, readonly) SCMCAction missionControl; 27 | @property(nonatomic, readonly) SCMCAction applicationWindows; 28 | @property(nonatomic, readonly) SCMCAction showDesktop; 29 | @property(nonatomic, readonly) SCMCAction launchpad; 30 | @property(nonatomic, readonly) SCMCAction nextSpace; 31 | @property(nonatomic, readonly) SCMCAction previousSpace; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCEventSpec.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCEventSpec.h 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | typedef NS_ENUM(NSInteger, SCMCEventType) { 14 | SCMCEventTypeEventTap = 0, 15 | SCMCEventTypeHid = 1, 16 | }; 17 | 18 | /// @brief Describes an event which will trigger an action 19 | @interface SCMCEventSpec : NSObject 20 | 21 | + (instancetype)new NS_UNAVAILABLE; 22 | - (instancetype)init NS_UNAVAILABLE; 23 | 24 | /// @brief Constructs a @c SCMCEventSpec object described by a dictionary 25 | /// @param specDictionary Dictionary representation of the spec 26 | /// @return @c SCMCEventSpec or @c nil, if dictionary is in an invalid format 27 | + (nullable instancetype)eventSpecWithDictionary:(NSDictionary *)specDictionary; 28 | 29 | @property(nonatomic, readonly) SCMCEventType type; 30 | @property(nonatomic, readonly) NSNumber *code; 31 | @property(nonatomic, readonly) BOOL longClick; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Preference Pane/Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 2.0 19 | CFBundleVersion 20 | 1 21 | NSHumanReadableCopyright 22 | Copyright © 2018 deej. All rights reserved. 23 | NSMainNibFile 24 | PreferencePane 25 | NSPrefPaneIconLabel 26 | SCMC 27 | NSPrincipalClass 28 | DeejScmcPreferencePane 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Maxim Naumov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Configuration/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | * Pick a .plist 4 | * Put the file into `~/Library/Preferences` 5 | * Restart Dock: `killall Dock` 6 | * Launch the app 7 | 8 | # Editing 9 | 10 | ## File Format 11 | 12 | A config is a regular .plist file. 13 | Its root element is a dictionary which may contain the following keys: 14 | 15 | * product-id: `integer` 16 | * vendor-id: `integer` 17 | * mission-control: `dict` 18 | * application-windows: `dict` 19 | * show-desktop: `dict` 20 | * launchpad: `dict` 21 | * next-space: `dict` 22 | * previous-space: `dict` 23 | 24 | All of them are optional. 25 | 26 | `product-id` and `vendor-id` are only needed if you use HID for any of the events. 27 | 28 | The rest of the keys describe events on which the corresponding action will run. For example, `mission-control` key describes which button should toggle Mission Control and so on. 29 | Here's the event description format: 30 | ```plist 31 | 32 | type 33 | 0|1 34 | code 35 | 0..MAX 36 | long 37 | 38 | 39 | ``` 40 | See also the [template](Template/deej.SCMC.plist) config. 41 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCHidListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCHidListener.h 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | typedef void(^SCMCHidListenerCallback)(uint32_t code, BOOL pressed); 14 | 15 | /** 16 | Low-level HID listener. 17 | Does all the dirty work like calling C APIs and discarding unwanted events. 18 | 19 | @note Only one button can be pressed at a time. While pressed, other buttons are ignored. 20 | */ 21 | @interface SCMCHidListener : NSObject 22 | 23 | - (instancetype)init NS_UNAVAILABLE; 24 | + (instancetype)new NS_UNAVAILABLE; 25 | 26 | /// @param acceptedCodes Codes that are allowed to be passed to the callback. 27 | /// @param callback Invoked whenever an appropriate event occurs. 28 | - (instancetype)initWithAcceptedCodes:(NSArray *)acceptedCodes callback:(SCMCHidListenerCallback)callback; 29 | 30 | /// @param match `NSDictionary` containing device matching criteria. 31 | - (void)startForDeviceMatching:(NSDictionary *)match; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCConfiguration.h 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | #import "SCMCEventSpec.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | /// Having a strongly typed object instead of a NSDictionary or NSUserDefaults is the sole purpose of this class 15 | @interface SCMCConfiguration : NSObject 16 | 17 | + (instancetype)new NS_UNAVAILABLE; 18 | - (instancetype)init NS_UNAVAILABLE; 19 | 20 | + (instancetype)configuration; 21 | 22 | @property(nonatomic, readonly, nullable) NSNumber *vendorId; 23 | @property(nonatomic, readonly, nullable) NSNumber *productId; 24 | 25 | @property(nonatomic, readonly, nullable) SCMCEventSpec *missionControl; 26 | @property(nonatomic, readonly, nullable) SCMCEventSpec *applicationWindows; 27 | @property(nonatomic, readonly, nullable) SCMCEventSpec *showDesktop; 28 | @property(nonatomic, readonly, nullable) SCMCEventSpec *launchpad; 29 | @property(nonatomic, readonly, nullable) SCMCEventSpec *nextSpace; 30 | @property(nonatomic, readonly, nullable) SCMCEventSpec *previousSpace; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Loader Scripting Addition/Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundleShortVersionString 16 | 2.0 17 | CFBundleVersion 18 | 1 19 | NSHumanReadableCopyright 20 | Copyright © 2018 deej. All rights reserved. 21 | OSAXHandlers 22 | 23 | Events 24 | 25 | SCMCinjt 26 | 27 | Context 28 | Process 29 | Handler 30 | SCMCLoadDockPlugin 31 | ThreadSafe 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCEventSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCEventSpec.m 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #import "SCMCEventSpec.h" 10 | 11 | @implementation SCMCEventSpec 12 | 13 | - (instancetype)initWithType:(SCMCEventType)type code:(NSNumber *)code longClick:(BOOL)longClick { 14 | if (self = [super init]) { 15 | _type = type; 16 | _code = code; 17 | _longClick = longClick; 18 | } 19 | return self; 20 | } 21 | 22 | + (nullable instancetype)eventSpecWithDictionary:(NSDictionary *)specDictionary { 23 | if (specDictionary.count == 0) { 24 | return nil; 25 | } 26 | 27 | SCMCEventType type = specDictionary[@"type"].integerValue; 28 | if (type != SCMCEventTypeEventTap && type != SCMCEventTypeHid) { 29 | return nil; 30 | } 31 | 32 | NSNumber *code = specDictionary[@"code"]; 33 | if (code == nil) { 34 | return nil; 35 | } 36 | 37 | BOOL longClick = specDictionary[@"long"].boolValue; 38 | 39 | return [[self alloc] initWithType:type code:code longClick:longClick]; 40 | } 41 | 42 | - (NSString *)description { 43 | return [NSString stringWithFormat:@"%ld:%@%@", (NSInteger)self.type, self.code, self.longClick ? @"[long]" : @""]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCActionStore.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCActionStore.m 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 16.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #import "SCMCActionStore.h" 10 | #import "SCMCEventSpec.h" 11 | 12 | @interface SCMCActionStore () 13 | 14 | @property(nonatomic) NSMutableDictionary *regularActions; 15 | @property(nonatomic) NSMutableDictionary *longClickActions; 16 | 17 | @end 18 | 19 | @implementation SCMCActionStore 20 | 21 | - (instancetype)init { 22 | if (self = [super init]) { 23 | _regularActions = [[NSMutableDictionary alloc] init]; 24 | _longClickActions = [[NSMutableDictionary alloc] init]; 25 | } 26 | return self; 27 | } 28 | 29 | - (BOOL)empty { 30 | return (self.regularActions.count + self.longClickActions.count) == 0; 31 | } 32 | 33 | - (NSArray *)addedEventCodes { 34 | NSSet *codes = [NSSet setWithArray:self.regularActions.allKeys]; 35 | codes = [codes setByAddingObjectsFromArray:self.longClickActions.allKeys]; 36 | return codes.allObjects; 37 | } 38 | 39 | - (void)addAction:(SCMCAction)action forEvent:(SCMCEventSpec *)eventSpec { 40 | if (eventSpec.longClick) { 41 | _longClickActions[eventSpec.code] = action; 42 | } else { 43 | _regularActions[eventSpec.code] = action; 44 | } 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Loader App/Sources/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Loader App 4 | // 5 | // Created by Maxim Naumov on 07.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import AppKit; 10 | 11 | static NSString *FormatError(NSDictionary *error) { 12 | return error[NSAppleScriptErrorBriefMessage]; 13 | } 14 | 15 | static void ErrorAlert(NSDictionary *error) { 16 | // TODO: provide the user with instructions on what to do 17 | NSAlert *alert = [NSAlert new]; 18 | // Make it wider 19 | alert.accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 400, 0)]; 20 | alert.alertStyle = NSAlertStyleCritical; 21 | alert.messageText = @"Sculpt Comfort Mission Control"; 22 | alert.informativeText = FormatError(error); 23 | [alert runModal]; 24 | } 25 | 26 | int main(int argc, const char * argv[]) { 27 | NSURL *dockPluginUrl = [NSBundle.mainBundle.bundleURL URLByAppendingPathComponent:@"Contents/Dock Plugin/Dock Plugin.bundle"]; 28 | NSString *scriptSource = [NSString stringWithFormat:@"tell application \"Dock\" to «event SCMCinjt» \"%@\"", dockPluginUrl.path]; 29 | NSAppleScript *triggerOsaxScript = [[NSAppleScript alloc] initWithSource:scriptSource]; 30 | NSDictionary *error = nil; 31 | [triggerOsaxScript executeAndReturnError:&error]; 32 | if (error != nil) { 33 | ErrorAlert(error); 34 | return 1; 35 | } else { 36 | return 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Preference Pane/Sources/Base.lproj/PreferencePane.xib: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCConfiguration.m 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 09.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #import "SCMCConfiguration.h" 10 | 11 | static NSString *const VendorIdKey = @"vendor-id"; 12 | static NSString *const ProductIdKey = @"product-id"; 13 | 14 | static NSString *const MissionControlKey = @"mission-control"; 15 | static NSString *const ApplicationWindowsKey = @"application-windows"; 16 | static NSString *const ShowDesktopKey = @"show-desktop"; 17 | static NSString *const LaunchpadKey = @"launchpad"; 18 | static NSString *const NextSpaceKey = @"next-space"; 19 | static NSString *const PreviousSpaceKey = @"previous-space"; 20 | 21 | @interface SCMCConfiguration () 22 | 23 | @property(nonatomic, readonly) NSUserDefaults *userDefaults; 24 | 25 | @end 26 | 27 | @implementation SCMCConfiguration 28 | 29 | - (instancetype)initPrivate { 30 | if (self = [super init]) { 31 | [self forceInvalidateUserDefaults]; 32 | _userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"deej.SCMC"]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)forceInvalidateUserDefaults { 38 | // If you replace the config file, the app will keep reading previous data 39 | // This is a workaround for that 40 | system("defaults read deej.SCMC"); 41 | } 42 | 43 | + (instancetype)configuration { 44 | return [[self alloc] initPrivate]; 45 | } 46 | 47 | // MARK: - Optional values needed for HID listener 48 | 49 | - (NSNumber *)vendorId { 50 | return [self.userDefaults objectForKey:VendorIdKey]; 51 | } 52 | 53 | - (NSNumber *)productId { 54 | return [self.userDefaults objectForKey:ProductIdKey]; 55 | } 56 | 57 | // MARK: - Actions 58 | 59 | - (SCMCEventSpec *)missionControl { 60 | return [self specForKey:MissionControlKey]; 61 | } 62 | 63 | - (SCMCEventSpec *)applicationWindows { 64 | return [self specForKey:ApplicationWindowsKey]; 65 | } 66 | 67 | - (SCMCEventSpec *)showDesktop { 68 | return [self specForKey:ShowDesktopKey]; 69 | } 70 | 71 | - (SCMCEventSpec *)launchpad { 72 | return [self specForKey:LaunchpadKey]; 73 | } 74 | 75 | - (SCMCEventSpec *)nextSpace { 76 | return [self specForKey:NextSpaceKey]; 77 | } 78 | 79 | - (SCMCEventSpec *)previousSpace { 80 | return [self specForKey:PreviousSpaceKey]; 81 | } 82 | 83 | // MARK: Parsing Spec 84 | 85 | - (SCMCEventSpec *)specForKey:(NSString *)key { 86 | NSDictionary *specDictionary = [self.userDefaults dictionaryForKey:key]; 87 | return [SCMCEventSpec eventSpecWithDictionary:specDictionary]; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCEventTapListener.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCEventTapListener.m 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #import "SCMCEventTapListener.h" 10 | 11 | @implementation SCMCEventTapListener { 12 | SCMCEventTapListenerCallback _callback; 13 | /// A zero-terminated array of the codes that are allowed to be passed to the callback. 14 | // It will be accessed at a much lower rate than a similar array of HID listener. 15 | // Anyway, I'll stick to this implementation to keep it fast. 16 | int64_t *_acceptedCodes; 17 | CFMachPortRef _eventTap; 18 | CFRunLoopSourceRef _source; 19 | } 20 | 21 | - (instancetype)initWithAcceptedCodes:(NSArray *)acceptedCodes callback:(SCMCEventTapListenerCallback)callback { 22 | if (self = [super init]) { 23 | _callback = callback; 24 | [self initializeAcceptedCodes:acceptedCodes]; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)initializeAcceptedCodes:(NSArray *)acceptedCodes { 30 | _acceptedCodes = calloc(acceptedCodes.count + 1, sizeof(*_acceptedCodes)); 31 | for (NSUInteger i = 0; i < acceptedCodes.count; i++) { 32 | _acceptedCodes[i] = acceptedCodes[i].longLongValue; 33 | } 34 | } 35 | 36 | - (void)dealloc { 37 | CFRunLoopRemoveSource(CFRunLoopGetMain(), _source, kCFRunLoopDefaultMode); 38 | CFRelease(_eventTap); 39 | free(_acceptedCodes); 40 | } 41 | 42 | // MARK: - CGEventTap 43 | 44 | static BOOL Contains(const int64_t *const acceptedCodes, const int64_t buttonNumber) { 45 | int64_t code; 46 | for (NSUInteger i = 0; (code = acceptedCodes[i]) != 0; i++) { 47 | if (buttonNumber == code) return YES; 48 | } 49 | 50 | return NO; 51 | } 52 | 53 | static CGEventRef MouseCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, SCMCEventTapListener *listener) { 54 | const int64_t buttonNumber = CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber); 55 | if (!Contains(listener->_acceptedCodes, buttonNumber)) return event; 56 | 57 | BOOL pressed = (type == kCGEventOtherMouseDown); 58 | listener->_callback(buttonNumber, pressed); 59 | return NULL; 60 | } 61 | 62 | - (void)start { 63 | CGEventMask eventMask = CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp); 64 | _eventTap = CGEventTapCreate(kCGSessionEventTap, 0, kCGEventTapOptionDefault, eventMask, (CGEventTapCallBack)MouseCallback, (__bridge void *)self); 65 | _source = CFMachPortCreateRunLoopSource(NULL, _eventTap, 0); 66 | CFRunLoopAddSource(CFRunLoopGetMain(), _source, kCFRunLoopDefaultMode); 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCClickHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCClickHandler.m 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 16.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | #import "SCMCClickHandler.h" 10 | #import "SCMCActionStore.h" 11 | 12 | static const NSTimeInterval LONG_CLICK_DELAY = 0.2; 13 | 14 | @interface SCMCClickHandler () 15 | 16 | @property(nonatomic) NSTimer *timer; 17 | 18 | // Code and action store together allow to distinguish a button from others 19 | @property(nonatomic) NSNumber *pressedButtonCode; 20 | @property(nonatomic) SCMCActionStore *pressedButtonActionStore; 21 | 22 | @property(nonatomic) SCMCAction longClickAction; 23 | @property(nonatomic, nullable) SCMCAction releaseAction; 24 | 25 | @end 26 | 27 | @implementation SCMCClickHandler 28 | 29 | - (void)handleClickWithCode:(NSNumber *)code pressed:(BOOL)pressed actionStore:(SCMCActionStore *)actionStore { 30 | if (pressed) { 31 | SCMCAction longClickAction = actionStore.longClickActions[code]; 32 | SCMCAction regularAction = actionStore.regularActions[code]; 33 | 34 | if (longClickAction) { 35 | [self startWithCode:code actionStore:actionStore longClickAction:longClickAction releaseAction:regularAction]; 36 | } else if (regularAction) { 37 | regularAction(); 38 | } 39 | } else { 40 | [self cancelWithCode:code actionStore:actionStore]; 41 | } 42 | } 43 | 44 | - (void)startWithCode:(NSNumber *)code actionStore:(SCMCActionStore *)actionStore longClickAction:(SCMCAction)longClickAction releaseAction:(SCMCAction)releaseAction { 45 | if (self.timer != nil) return; // Ignore if already started 46 | 47 | self.pressedButtonCode = code; 48 | self.pressedButtonActionStore = actionStore; 49 | 50 | self.longClickAction = longClickAction; 51 | self.releaseAction = releaseAction; 52 | self.timer = [NSTimer scheduledTimerWithTimeInterval:LONG_CLICK_DELAY target:self selector:@selector(executeLongClickAction:) userInfo:nil repeats:NO]; 53 | } 54 | 55 | /// @note @c code and @c actionStore are needed to check if we are releasing the same button that was pressed initially. 56 | - (void)cancelWithCode:(NSNumber *)code actionStore:(SCMCActionStore *)actionStore { 57 | if (self.timer == nil) return; // Nothing to cancel 58 | 59 | BOOL releasingPressedButton = [self.pressedButtonCode isEqualToNumber:code] && (self.pressedButtonActionStore == actionStore); 60 | if (self.releaseAction != nil && releasingPressedButton) { 61 | self.releaseAction(); 62 | } 63 | 64 | [self reset]; 65 | } 66 | 67 | - (void)executeLongClickAction:(__unused NSTimer *)timer { 68 | self.longClickAction(); 69 | [self reset]; 70 | } 71 | 72 | - (void)reset { 73 | [self.timer invalidate]; 74 | self.timer = nil; 75 | 76 | self.pressedButtonCode = nil; 77 | self.pressedButtonActionStore = nil; 78 | 79 | self.longClickAction = nil; 80 | self.releaseAction = nil; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is it? 2 | It's an app that lets you switch between virtual desktops on your Mac. With a mouse! And not only with Sculpt Comfort, any mouse will do. But you really want a mouse with at least two additional buttons. 3 | 4 | # Note for Catalina users 5 | Since SCMC doesn't support Catalina at the moment, you might want to use a solution by [@ephemient](//github.com/ephemient). See [this](//github.com/ultimate-deej/Sculpt-Comfort-Mission-Control/issues/20#issuecomment-638209672) comment. 6 | 7 | # Important 10.14 Mojave information 8 | Due to security enhancements in Mojave, it's not currently possible to use SCMC with SIP enabled. You must keep it disabled to continue using this app. 9 | 10 | # Installation 11 | 1. Install Loader. This is probably a one-time setup as this component is unlikely to change soon. 12 | 1. Disable SIP 13 | 2. Copy `SCMC Loader.osax` to `/System/Library/ScriptingAdditions` 14 | 3. *[pre-10.14 only]* Enable SIP 15 | 2. Install a config (see [Configuration folder](/Configuration)) 16 | 3. Run `Sculpt Comfort Mission Control.app` 17 | 18 | # Contributing 19 | **Contributions are highly welcomed.** You can help the project by: 20 | - Adding more details to readme 21 | - Fixing typos, grammar and spelling mistakes etc. 22 | - Code contributions. Take a thorough approach here. The best way to make a code contribution is to discuss the idea before actually starting to code. 23 | - **Tell me if it works with your mouse**. Just: 24 | 1. Either create a pull request. It should contain a config and an update to the readme. 25 | 2. Or create an issue. I will then add a config to the repo, and the model name to the readme. 26 | 27 | While the above are direct contributions, there are other ways to help the project: 28 | - Star this repo ⭐. It really motivates me to continue improving the app! 29 | - Tell a friend 30 | 31 | # Which macOS versions are supported? 32 | 10.12+. Support for earlier versions is dropped. 33 | 34 | # Which mice are supported? 35 | As stated earlier, the app should be able to work with any mouse, there are no artificial restrictions to this. However, here's the list of tested models: 36 | - Microsoft Sculpt Comfort Mouse (of course) 37 | - Microsoft Sculpt Ergonomic Mouse (a config is missing though, contact me and we'll make one) 38 | - A 5-button No Name mouse 39 | 40 | # What happened here, an update? 41 | This is version 2, a complete rewrite of the app. 42 | 43 | Although it's a minimal working release which lacks some important features, it can already do everything v1 can but better! To be specific, you will benefit from moving to v2 because: 44 | 45 | - You don't need `lldb` and developer tools 46 | - Because of the above, it starts much faster. You won't even notice 47 | - You only need to disable SIP for an initial installation 48 | - If the app handles a mouse event, other apps don't receive it anymore (with a proper config). With the previous version, it happened for some button configurations. No more unwanted navigation in browsers or wherever else. 49 | 50 | # Have questions? 51 | Read the issues. Or submit one. 52 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCActions.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCActions.m 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 15.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import AppKit; 10 | 11 | #import "SCMCActions.h" 12 | #import "Dock.h" 13 | 14 | @interface SCMCActions () 15 | 16 | @property(weak, nonatomic, readonly) id spaces; 17 | @property(weak, nonatomic, readonly) id expose; 18 | 19 | @end 20 | 21 | @implementation SCMCActions 22 | 23 | - (instancetype)initWithSpaces:(__weak id)spaces expose:(__weak id)expose { 24 | if (self = [super init]) { 25 | _spaces = spaces; 26 | _expose = expose; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | - (SCMCAction)missionControl { 33 | return ^{ 34 | [NSWorkspace.sharedWorkspace launchApplication:@"Mission Control"]; 35 | }; 36 | } 37 | 38 | - (SCMCAction)applicationWindows { 39 | return ^{ 40 | NSString *missionControlPath = [NSWorkspace.sharedWorkspace fullPathForApplication:@"Mission Control"]; 41 | NSURL *missionControlUrl = [NSURL fileURLWithPath:missionControlPath]; 42 | [NSWorkspace.sharedWorkspace launchApplicationAtURL:missionControlUrl options:NSWorkspaceLaunchDefault configuration:@{NSWorkspaceLaunchConfigurationArguments : @[@"2"]} error:nil]; 43 | }; 44 | } 45 | 46 | - (SCMCAction)showDesktop { 47 | return ^{ 48 | NSString *missionControlPath = [NSWorkspace.sharedWorkspace fullPathForApplication:@"Mission Control"]; 49 | NSURL *missionControlUrl = [NSURL fileURLWithPath:missionControlPath]; 50 | [NSWorkspace.sharedWorkspace launchApplicationAtURL:missionControlUrl options:NSWorkspaceLaunchDefault configuration:@{NSWorkspaceLaunchConfigurationArguments : @[@"1"]} error:nil]; 51 | }; 52 | } 53 | 54 | - (SCMCAction)launchpad { 55 | return ^{ 56 | [NSWorkspace.sharedWorkspace launchApplication:@"Launchpad"]; 57 | }; 58 | } 59 | 60 | // Unlike Spaces, Expose requires a display ID as an argument 61 | static CGDirectDisplayID CurrentDisplayId() { 62 | CGEventRef dummyEvent = CGEventCreate(NULL); 63 | CGPoint mouseLocation = CGEventGetLocation(dummyEvent); 64 | CFRelease(dummyEvent); 65 | 66 | CGDirectDisplayID currentDisplay; 67 | if (CGGetDisplaysWithPoint(mouseLocation, 1, ¤tDisplay, NULL) != kCGErrorSuccess) { 68 | return kCGNullDirectDisplay; 69 | } 70 | 71 | return currentDisplay; 72 | } 73 | 74 | - (SCMCAction)nextSpace { 75 | id spaces = self.spaces; 76 | id expose = self.expose; 77 | return ^{ 78 | if (expose.mode == 0) { 79 | [spaces switchToNextSpace:YES]; 80 | } else { 81 | [expose MissionControlSwitchToNextSpace:CurrentDisplayId()]; 82 | } 83 | }; 84 | } 85 | 86 | - (SCMCAction)previousSpace { 87 | id spaces = self.spaces; 88 | id expose = self.expose; 89 | return ^{ 90 | if (expose.mode == 0) { 91 | [spaces switchToPreviousSpace:YES]; 92 | } else { 93 | [expose MissionControlSwitchToPreviousSpace:CurrentDisplayId()]; 94 | } 95 | }; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/Init.m: -------------------------------------------------------------------------------- 1 | // 2 | // Init.m 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 15.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Darwin.malloc; 10 | @import ObjectiveC.runtime; 11 | 12 | #import "Dock.h" 13 | #import "SCMCActions.h" 14 | #import "SCMCConfiguration.h" 15 | #import "SCMCCore.h" 16 | 17 | // MARK: - Searching for Required Objects 18 | 19 | // MARK: Search Context 20 | 21 | typedef struct SearchContext { 22 | const Class spacesClass; 23 | const size_t spacesInstanceSize; 24 | const Class exposeClass; 25 | const size_t exposeInstanceSize; 26 | 27 | __unsafe_unretained id outSpaces; 28 | __unsafe_unretained id outExpose; 29 | } SearchContext; 30 | 31 | static SearchContext MakeSearchContext(void) { 32 | Class spacesClass = objc_getClass("Dock.Spaces"); 33 | Class exposeClass = objc_getClass("Dock.WVExpose"); 34 | 35 | return (SearchContext) { 36 | .spacesClass = spacesClass, 37 | .spacesInstanceSize = class_getInstanceSize(spacesClass), 38 | .exposeClass = exposeClass, 39 | .exposeInstanceSize = class_getInstanceSize(exposeClass), 40 | }; 41 | } 42 | 43 | // MARK: Search routines 44 | 45 | static void EnumeratorBody(__unused task_t task, SearchContext *const context, __unused unsigned type, vm_range_t *ranges, unsigned numberOfRanges) { 46 | if (context->outSpaces && context->outExpose) return; // It is impossible to interrupt enumeration as per source code 47 | 48 | for (unsigned i = 0; i < numberOfRanges; i++) { 49 | vm_range_t range = ranges[i]; 50 | // Don't bother checking class if `range` is too small for the searched object 51 | if (nil == context->outSpaces && range.size >= context->spacesInstanceSize) { 52 | __unsafe_unretained id maybeObject = (__bridge id)(void *)range.address; 53 | if (object_getClass(maybeObject) == context->spacesClass) { 54 | context->outSpaces = maybeObject; 55 | } 56 | } 57 | if (nil == context->outExpose && range.size >= context->exposeInstanceSize) { 58 | __unsafe_unretained id maybeObject = (__bridge id)(void *)range.address; 59 | if (object_getClass(maybeObject) == context->exposeClass) { 60 | context->outExpose = maybeObject; 61 | } 62 | } 63 | } 64 | } 65 | 66 | static void FindRequiredInstances(SearchContext *const context) { 67 | vm_address_t zoneAddress = (vm_address_t)malloc_default_zone(); 68 | vm_range_recorder_t *rangeRecorder = (vm_range_recorder_t *)&EnumeratorBody; 69 | malloc_default_zone()->introspect->enumerator(0, context, MALLOC_PTR_IN_USE_RANGE_TYPE, zoneAddress, NULL, *rangeRecorder); 70 | } 71 | 72 | // MARK: - Initializing 73 | 74 | static SCMCCore *Core; 75 | 76 | __attribute__((constructor)) 77 | static void StartCore(void) { 78 | SearchContext context = MakeSearchContext(); 79 | FindRequiredInstances(&context); 80 | SCMCActions *actions = [[SCMCActions alloc] initWithSpaces:context.outSpaces expose:context.outExpose]; 81 | SCMCConfiguration *configuration = [SCMCConfiguration configuration]; 82 | Core = [SCMCCore startWithConfiguration:configuration actions:actions]; 83 | } 84 | -------------------------------------------------------------------------------- /Dock Plugin/Sources/SCMCCore.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCCore.m 3 | // Dock Plugin 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import IOKit.hid; 10 | 11 | #import "SCMCCore.h" 12 | #import "SCMCConfiguration.h" 13 | #import "SCMCActions.h" 14 | #import "SCMCHidListener.h" 15 | #import "SCMCEventTapListener.h" 16 | #import "SCMCActionStore.h" 17 | #import "SCMCClickHandler.h" 18 | 19 | @interface SCMCCore () 20 | 21 | @property(nonatomic, readonly) SCMCClickHandler *clickHandler; 22 | 23 | @property(nonatomic, readonly) SCMCHidListener *hidListener; 24 | @property(nonatomic, readonly) SCMCEventTapListener *eventTapListener; 25 | 26 | @end 27 | 28 | @implementation SCMCCore 29 | 30 | + (instancetype)startWithConfiguration:(SCMCConfiguration *)configuration actions:(SCMCActions *)actions { 31 | SCMCCore *core = [[SCMCCore alloc] initPrivate]; 32 | [core startWithConfiguration:configuration actions:actions]; 33 | return core; 34 | } 35 | 36 | - (instancetype)initPrivate { 37 | if (self = [super init]) { 38 | _clickHandler = [[SCMCClickHandler alloc] init]; 39 | } 40 | return self; 41 | } 42 | 43 | - (void)startWithConfiguration:(SCMCConfiguration *)configuration actions:(SCMCActions *)actions { 44 | SCMCActionStore *hidActions = [[SCMCActionStore alloc] init]; 45 | SCMCActionStore *eventTapActions = [[SCMCActionStore alloc] init]; 46 | 47 | void (^putAction)(SCMCAction, SCMCEventSpec *) = ^(SCMCAction action, SCMCEventSpec *eventSpec) { 48 | [self putAction:action forEvent:eventSpec toHidActions:hidActions orEventTapActions:eventTapActions]; 49 | }; 50 | 51 | putAction(actions.missionControl, configuration.missionControl); 52 | putAction(actions.applicationWindows, configuration.applicationWindows); 53 | putAction(actions.showDesktop, configuration.showDesktop); 54 | putAction(actions.launchpad, configuration.launchpad); 55 | putAction(actions.nextSpace, configuration.nextSpace); 56 | putAction(actions.previousSpace, configuration.previousSpace); 57 | 58 | SCMCClickHandler *clickHandler = self.clickHandler; 59 | 60 | if (!hidActions.empty) { 61 | _hidListener = [[SCMCHidListener alloc] initWithAcceptedCodes:hidActions.addedEventCodes callback:^(uint32_t code, BOOL pressed) { 62 | [clickHandler handleClickWithCode:@(code) pressed:pressed actionStore:hidActions]; 63 | }]; 64 | [_hidListener startForDeviceMatching:@{ 65 | @kIOHIDVendorIDKey : configuration.vendorId, 66 | @kIOHIDProductIDKey : configuration.productId, 67 | }]; 68 | } 69 | 70 | if (!eventTapActions.empty) { 71 | _eventTapListener = [[SCMCEventTapListener alloc] initWithAcceptedCodes:eventTapActions.addedEventCodes callback:^(int64_t code, BOOL pressed) { 72 | [clickHandler handleClickWithCode:@(code) pressed:pressed actionStore:eventTapActions]; 73 | }]; 74 | [_eventTapListener start]; 75 | } 76 | } 77 | 78 | - (void)putAction:(SCMCAction)action forEvent:(SCMCEventSpec *)eventSpec toHidActions:(SCMCActionStore *)hidActions orEventTapActions:(SCMCActionStore *)eventTapActions { 79 | if (nil == eventSpec) return; 80 | 81 | if (eventSpec.type == SCMCEventTypeHid) { 82 | [hidActions addAction:action forEvent:eventSpec]; 83 | } else if (eventSpec.type == SCMCEventTypeEventTap) { 84 | [eventTapActions addAction:action forEvent:eventSpec]; 85 | } 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /Loader Scripting Addition/Sources/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SCMS Loader 4 | // 5 | // Created by Maxim Naumov on 07.01.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | #pragma mark Cleanup Helper 12 | 13 | static void ReleaseRef(void *variableRef) { 14 | CFTypeRef cfObject = *((CFTypeRef *)variableRef); 15 | if (cfObject) CFRelease(cfObject); 16 | } 17 | #define CFRELEASE_CLEANUP __attribute__((__cleanup__(ReleaseRef))) 18 | 19 | #pragma mark - 20 | 21 | static NSData *GetTheOnlyCertificateData(SecStaticCodeRef code) { 22 | CFDictionaryRef cfSigningInformation = NULL; 23 | if (SecCodeCopySigningInformation(code, kSecCSSigningInformation, &cfSigningInformation) != noErr) { 24 | return NULL; 25 | } 26 | NSDictionary *signingInformation = CFBridgingRelease(cfSigningInformation); 27 | 28 | NSArray *certificates = signingInformation[(NSString *)kSecCodeInfoCertificates]; 29 | if (certificates.count != 1) { 30 | return NULL; 31 | } 32 | 33 | SecCertificateRef certificate = (__bridge SecCertificateRef)certificates.firstObject; 34 | return CFBridgingRelease(SecCertificateCopyData(certificate)); 35 | } 36 | 37 | static BOOL IsPluginSignatureValid(NSURL *bundlePath) { 38 | CFRELEASE_CLEANUP SecStaticCodeRef selfCode = NULL; 39 | CFRELEASE_CLEANUP SecStaticCodeRef bundleCode = NULL; 40 | CFRELEASE_CLEANUP SecRequirementRef requirement = NULL; 41 | 42 | if (SecStaticCodeCreateWithPath((__bridge CFURLRef)bundlePath, kSecCSDefaultFlags, &bundleCode) != noErr) { 43 | return NO; 44 | } 45 | 46 | NSURL *selfPath = [NSBundle bundleWithIdentifier:@"deej.SCMC.Loader-Scripting-Addition"].bundleURL; 47 | if (SecStaticCodeCreateWithPath((__bridge CFURLRef)selfPath, kSecCSDefaultFlags, &selfCode) != noErr) { 48 | return NO; 49 | } 50 | 51 | NSData *selfCertificateData = GetTheOnlyCertificateData(selfCode); 52 | NSData *bundleCertificateData = GetTheOnlyCertificateData(bundleCode); 53 | if (![bundleCertificateData isEqualToData:selfCertificateData]) { 54 | return NO; 55 | } 56 | 57 | CFStringRef pluginRequirementString = CFSTR("identifier \"deej.SCMC.Dock-Plugin\" and certificate root = H\"3bbea1421ecbfb0d14919835fe9a9ba78ad3ab80\""); 58 | SecRequirementCreateWithString(pluginRequirementString, kSecCSDefaultFlags, &requirement); 59 | 60 | return (SecStaticCodeCheckValidity(bundleCode, kSecCSDefaultFlags, requirement) == noErr); 61 | } 62 | 63 | 64 | OSErr SCMCLoadDockPlugin(const AppleEvent *event, AppleEvent *reply, long refcon) { 65 | AEDesc pluginPathDesc; 66 | if (AEGetParamDesc(event, keyDirectObject, typeWildCard, &pluginPathDesc) != noErr) { 67 | return fnfErr; 68 | } 69 | NSURL *pluginUrl = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&pluginPathDesc].fileURLValue; 70 | 71 | NSError *error = nil; 72 | if (![pluginUrl checkResourceIsReachableAndReturnError:&error]) { 73 | const char *errorText = error.localizedDescription.UTF8String; 74 | AEPutParamPtr(reply, keyErrorString, typeUTF8Text, errorText, strlen(errorText)); 75 | return fnfErr; 76 | } 77 | 78 | if (!IsPluginSignatureValid(pluginUrl)) { 79 | const char errorText[] = "Invalid bundle signature"; 80 | AEPutParamPtr(reply, keyErrorString, typeUTF8Text, errorText, sizeof(errorText)); 81 | return pathNotVerifiedErr; 82 | } 83 | 84 | [[NSBundle bundleWithURL:pluginUrl] load]; 85 | 86 | return noErr; 87 | } 88 | -------------------------------------------------------------------------------- /Shared/Sources/SCMCHidListener.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMCHidListener.m 3 | // Shared 4 | // 5 | // Created by Maxim Naumov on 14.03.2018. 6 | // Copyright © 2018 deej. All rights reserved. 7 | // 8 | 9 | @import IOKit.hid; 10 | #import "SCMCHidListener.h" 11 | 12 | @implementation SCMCHidListener { 13 | SCMCHidListenerCallback _callback; 14 | /// A zero-terminated array of the codes that are allowed to be passed to the callback. 15 | // It will be accessed at an extremely high rate 16 | // so the idea is to avoid ObjC overheads by using a raw array 17 | uint32_t *_acceptedCodes; 18 | uint32_t _currentlyPressedButton; 19 | IOHIDManagerRef _hidManager; 20 | } 21 | 22 | - (instancetype)initWithAcceptedCodes:(NSArray *)acceptedCodes callback:(SCMCHidListenerCallback)callback { 23 | if (self = [super init]) { 24 | _callback = callback; 25 | [self initializeAcceptedCodes:acceptedCodes]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)initializeAcceptedCodes:(NSArray *)acceptedCodes { 31 | _acceptedCodes = calloc(acceptedCodes.count + 1, sizeof(*_acceptedCodes)); 32 | for (NSUInteger i = 0; i < acceptedCodes.count; i++) { 33 | _acceptedCodes[i] = acceptedCodes[i].unsignedIntValue; 34 | } 35 | } 36 | 37 | - (void)dealloc { 38 | IOHIDManagerClose(_hidManager, kIOHIDOptionsTypeNone); 39 | free(_acceptedCodes); 40 | } 41 | 42 | // MARK: - IOHIDManager 43 | 44 | static BOOL PrefilterElement(const IOHIDElementRef element) { 45 | IOHIDElementType type = IOHIDElementGetType(element); 46 | // We only want to handle buttons 47 | if (type != kIOHIDElementTypeInput_Button) return YES; 48 | 49 | // Probably not a regular button. Sent by some Sculpt Comfort mice 50 | if (IOHIDElementGetLogicalMax(element) != 1) return YES; 51 | 52 | return NO; 53 | } 54 | 55 | static BOOL PrefilterUsage(const uint32_t usage, const uint32_t *const acceptedCodes) { 56 | // Ignore left & right buttons 57 | if (usage == 1 || usage == 2) return YES; 58 | 59 | // Check whether `acceptedCodes` contains `usage` 60 | uint32_t code; 61 | for (NSUInteger i = 0; (code = acceptedCodes[i]) != 0; i++) { 62 | if (usage == code) return NO; 63 | } 64 | 65 | return YES; 66 | } 67 | 68 | static BOOL IsDiscardedByCurrentlyPressedButton(const uint32_t usage, const BOOL pressed, const uint32_t currentlyPressedButton) { 69 | // Sculpt Comfort tends to send many values at once. We only want the first one 70 | if (currentlyPressedButton != 0 && pressed && currentlyPressedButton != usage) return YES; 71 | // Ignore button release events corresponding to the press events filtered out by the line above 72 | if (currentlyPressedButton == 0 && !pressed) return YES; 73 | 74 | return NO; 75 | } 76 | 77 | static void MouseCallback(SCMCHidListener *listener, IOReturn result, void *sender, IOHIDValueRef value) { 78 | if (result != kIOReturnSuccess) return; 79 | 80 | IOHIDElementRef element = IOHIDValueGetElement(value); 81 | if (PrefilterElement(element)) return; 82 | 83 | const uint32_t usage = IOHIDElementGetUsage(element); 84 | if (PrefilterUsage(usage, listener->_acceptedCodes)) return; 85 | 86 | // After calling `PrefilterElement` we are pretty sure that the value is either 0 or 1 87 | BOOL pressed = IOHIDValueGetIntegerValue(value) == 1; 88 | 89 | /// While a button is pressed, ignore all the other buttons until it is released 90 | if (IsDiscardedByCurrentlyPressedButton(usage, pressed, listener->_currentlyPressedButton)) return; 91 | listener->_currentlyPressedButton = pressed ? usage : 0; 92 | 93 | listener->_callback(usage, pressed); 94 | } 95 | 96 | - (void)startForDeviceMatching:(NSDictionary *)match { 97 | _hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); 98 | IOHIDManagerSetDeviceMatching(_hidManager, (__bridge CFDictionaryRef)match); 99 | IOHIDManagerRegisterInputValueCallback(_hidManager, (IOHIDValueCallback)MouseCallback, (__bridge void *)self); 100 | IOHIDManagerScheduleWithRunLoop(_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); 101 | IOHIDManagerOpen(_hidManager, kIOHIDOptionsTypeNone); 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /Loader Scripting Addition/Loader Scripting Addition.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1761280120028F4500A2B1A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1761280020028F4500A2B1A4 /* main.m */; }; 11 | 1761280320028F8500A2B1A4 /* SCMC Loader.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 1761280220028F8500A2B1A4 /* SCMC Loader.sdef */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 176127F620028C3800A2B1A4 /* SCMC Loader.osax */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SCMC Loader.osax"; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | 176127F920028C3800A2B1A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 17 | 1761280020028F4500A2B1A4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 18 | 1761280220028F8500A2B1A4 /* SCMC Loader.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "SCMC Loader.sdef"; sourceTree = ""; }; 19 | /* End PBXFileReference section */ 20 | 21 | /* Begin PBXFrameworksBuildPhase section */ 22 | 176127F320028C3800A2B1A4 /* Frameworks */ = { 23 | isa = PBXFrameworksBuildPhase; 24 | buildActionMask = 2147483647; 25 | files = ( 26 | ); 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXFrameworksBuildPhase section */ 30 | 31 | /* Begin PBXGroup section */ 32 | 176127ED20028C3800A2B1A4 = { 33 | isa = PBXGroup; 34 | children = ( 35 | 176127F820028C3800A2B1A4 /* Sources */, 36 | 176127F720028C3800A2B1A4 /* Products */, 37 | ); 38 | sourceTree = ""; 39 | }; 40 | 176127F720028C3800A2B1A4 /* Products */ = { 41 | isa = PBXGroup; 42 | children = ( 43 | 176127F620028C3800A2B1A4 /* SCMC Loader.osax */, 44 | ); 45 | name = Products; 46 | sourceTree = ""; 47 | }; 48 | 176127F820028C3800A2B1A4 /* Sources */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 176127F920028C3800A2B1A4 /* Info.plist */, 52 | 1761280020028F4500A2B1A4 /* main.m */, 53 | 1761280220028F8500A2B1A4 /* SCMC Loader.sdef */, 54 | ); 55 | path = Sources; 56 | sourceTree = ""; 57 | }; 58 | /* End PBXGroup section */ 59 | 60 | /* Begin PBXNativeTarget section */ 61 | 176127F520028C3800A2B1A4 /* SCMC Loader */ = { 62 | isa = PBXNativeTarget; 63 | buildConfigurationList = 176127FC20028C3800A2B1A4 /* Build configuration list for PBXNativeTarget "SCMC Loader" */; 64 | buildPhases = ( 65 | 176127F220028C3800A2B1A4 /* Sources */, 66 | 176127F320028C3800A2B1A4 /* Frameworks */, 67 | 176127F420028C3800A2B1A4 /* Resources */, 68 | ); 69 | buildRules = ( 70 | ); 71 | dependencies = ( 72 | ); 73 | name = "SCMC Loader"; 74 | productName = "Loader Scripting Addition"; 75 | productReference = 176127F620028C3800A2B1A4 /* SCMC Loader.osax */; 76 | productType = "com.apple.product-type.bundle"; 77 | }; 78 | /* End PBXNativeTarget section */ 79 | 80 | /* Begin PBXProject section */ 81 | 176127EE20028C3800A2B1A4 /* Project object */ = { 82 | isa = PBXProject; 83 | attributes = { 84 | LastUpgradeCheck = 0920; 85 | ORGANIZATIONNAME = deej; 86 | TargetAttributes = { 87 | 176127F520028C3800A2B1A4 = { 88 | CreatedOnToolsVersion = 9.2; 89 | ProvisioningStyle = Manual; 90 | }; 91 | }; 92 | }; 93 | buildConfigurationList = 176127F120028C3800A2B1A4 /* Build configuration list for PBXProject "Loader Scripting Addition" */; 94 | compatibilityVersion = "Xcode 8.0"; 95 | developmentRegion = en; 96 | hasScannedForEncodings = 0; 97 | knownRegions = ( 98 | en, 99 | ); 100 | mainGroup = 176127ED20028C3800A2B1A4; 101 | productRefGroup = 176127F720028C3800A2B1A4 /* Products */; 102 | projectDirPath = ""; 103 | projectRoot = ""; 104 | targets = ( 105 | 176127F520028C3800A2B1A4 /* SCMC Loader */, 106 | ); 107 | }; 108 | /* End PBXProject section */ 109 | 110 | /* Begin PBXResourcesBuildPhase section */ 111 | 176127F420028C3800A2B1A4 /* Resources */ = { 112 | isa = PBXResourcesBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | 1761280320028F8500A2B1A4 /* SCMC Loader.sdef in Resources */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXResourcesBuildPhase section */ 120 | 121 | /* Begin PBXSourcesBuildPhase section */ 122 | 176127F220028C3800A2B1A4 /* Sources */ = { 123 | isa = PBXSourcesBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | 1761280120028F4500A2B1A4 /* main.m in Sources */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXSourcesBuildPhase section */ 131 | 132 | /* Begin XCBuildConfiguration section */ 133 | 176127FA20028C3800A2B1A4 /* Debug */ = { 134 | isa = XCBuildConfiguration; 135 | buildSettings = { 136 | ALWAYS_SEARCH_USER_PATHS = NO; 137 | CLANG_ANALYZER_NONNULL = YES; 138 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 139 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 140 | CLANG_CXX_LIBRARY = "libc++"; 141 | CLANG_ENABLE_MODULES = YES; 142 | CLANG_ENABLE_OBJC_ARC = YES; 143 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 144 | CLANG_WARN_BOOL_CONVERSION = YES; 145 | CLANG_WARN_COMMA = YES; 146 | CLANG_WARN_CONSTANT_CONVERSION = YES; 147 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 148 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 149 | CLANG_WARN_EMPTY_BODY = YES; 150 | CLANG_WARN_ENUM_CONVERSION = YES; 151 | CLANG_WARN_INFINITE_RECURSION = YES; 152 | CLANG_WARN_INT_CONVERSION = YES; 153 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 154 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 155 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 156 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 157 | CLANG_WARN_STRICT_PROTOTYPES = YES; 158 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 159 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 160 | CLANG_WARN_UNREACHABLE_CODE = YES; 161 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 162 | CODE_SIGN_IDENTITY = "SCMC App Internal Use"; 163 | CODE_SIGN_STYLE = Manual; 164 | COPY_PHASE_STRIP = NO; 165 | DEBUG_INFORMATION_FORMAT = dwarf; 166 | ENABLE_STRICT_OBJC_MSGSEND = YES; 167 | ENABLE_TESTABILITY = YES; 168 | GCC_C_LANGUAGE_STANDARD = gnu11; 169 | GCC_DYNAMIC_NO_PIC = NO; 170 | GCC_NO_COMMON_BLOCKS = YES; 171 | GCC_OPTIMIZATION_LEVEL = 0; 172 | GCC_PREPROCESSOR_DEFINITIONS = ( 173 | "DEBUG=1", 174 | "$(inherited)", 175 | ); 176 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 177 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 178 | GCC_WARN_UNDECLARED_SELECTOR = YES; 179 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 180 | GCC_WARN_UNUSED_FUNCTION = YES; 181 | GCC_WARN_UNUSED_VARIABLE = YES; 182 | MACOSX_DEPLOYMENT_TARGET = 10.12; 183 | MTL_ENABLE_DEBUG_INFO = YES; 184 | ONLY_ACTIVE_ARCH = YES; 185 | SDKROOT = macosx; 186 | }; 187 | name = Debug; 188 | }; 189 | 176127FB20028C3800A2B1A4 /* Release */ = { 190 | isa = XCBuildConfiguration; 191 | buildSettings = { 192 | ALWAYS_SEARCH_USER_PATHS = NO; 193 | CLANG_ANALYZER_NONNULL = YES; 194 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 195 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 196 | CLANG_CXX_LIBRARY = "libc++"; 197 | CLANG_ENABLE_MODULES = YES; 198 | CLANG_ENABLE_OBJC_ARC = YES; 199 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 200 | CLANG_WARN_BOOL_CONVERSION = YES; 201 | CLANG_WARN_COMMA = YES; 202 | CLANG_WARN_CONSTANT_CONVERSION = YES; 203 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 204 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 205 | CLANG_WARN_EMPTY_BODY = YES; 206 | CLANG_WARN_ENUM_CONVERSION = YES; 207 | CLANG_WARN_INFINITE_RECURSION = YES; 208 | CLANG_WARN_INT_CONVERSION = YES; 209 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 210 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 211 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 212 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 213 | CLANG_WARN_STRICT_PROTOTYPES = YES; 214 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 215 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | CODE_SIGN_IDENTITY = "SCMC App Internal Use"; 219 | CODE_SIGN_STYLE = Manual; 220 | COPY_PHASE_STRIP = NO; 221 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 222 | ENABLE_NS_ASSERTIONS = NO; 223 | ENABLE_STRICT_OBJC_MSGSEND = YES; 224 | GCC_C_LANGUAGE_STANDARD = gnu11; 225 | GCC_NO_COMMON_BLOCKS = YES; 226 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 227 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 228 | GCC_WARN_UNDECLARED_SELECTOR = YES; 229 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 230 | GCC_WARN_UNUSED_FUNCTION = YES; 231 | GCC_WARN_UNUSED_VARIABLE = YES; 232 | MACOSX_DEPLOYMENT_TARGET = 10.12; 233 | MTL_ENABLE_DEBUG_INFO = NO; 234 | SDKROOT = macosx; 235 | }; 236 | name = Release; 237 | }; 238 | 176127FD20028C3800A2B1A4 /* Debug */ = { 239 | isa = XCBuildConfiguration; 240 | buildSettings = { 241 | COMBINE_HIDPI_IMAGES = YES; 242 | INFOPLIST_FILE = Sources/Info.plist; 243 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 244 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Loader-Scripting-Addition"; 245 | PRODUCT_NAME = "$(TARGET_NAME)"; 246 | WRAPPER_EXTENSION = osax; 247 | }; 248 | name = Debug; 249 | }; 250 | 176127FE20028C3800A2B1A4 /* Release */ = { 251 | isa = XCBuildConfiguration; 252 | buildSettings = { 253 | COMBINE_HIDPI_IMAGES = YES; 254 | INFOPLIST_FILE = Sources/Info.plist; 255 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 256 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Loader-Scripting-Addition"; 257 | PRODUCT_NAME = "$(TARGET_NAME)"; 258 | WRAPPER_EXTENSION = osax; 259 | }; 260 | name = Release; 261 | }; 262 | /* End XCBuildConfiguration section */ 263 | 264 | /* Begin XCConfigurationList section */ 265 | 176127F120028C3800A2B1A4 /* Build configuration list for PBXProject "Loader Scripting Addition" */ = { 266 | isa = XCConfigurationList; 267 | buildConfigurations = ( 268 | 176127FA20028C3800A2B1A4 /* Debug */, 269 | 176127FB20028C3800A2B1A4 /* Release */, 270 | ); 271 | defaultConfigurationIsVisible = 0; 272 | defaultConfigurationName = Release; 273 | }; 274 | 176127FC20028C3800A2B1A4 /* Build configuration list for PBXNativeTarget "SCMC Loader" */ = { 275 | isa = XCConfigurationList; 276 | buildConfigurations = ( 277 | 176127FD20028C3800A2B1A4 /* Debug */, 278 | 176127FE20028C3800A2B1A4 /* Release */, 279 | ); 280 | defaultConfigurationIsVisible = 0; 281 | defaultConfigurationName = Release; 282 | }; 283 | /* End XCConfigurationList section */ 284 | }; 285 | rootObject = 176127EE20028C3800A2B1A4 /* Project object */; 286 | } 287 | -------------------------------------------------------------------------------- /Loader App/Loader App.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 176127EC2002883700A2B1A4 /* Dock Plugin.bundle in Embed Dock Plugin */ = {isa = PBXBuildFile; fileRef = 176127E9200287F500A2B1A4 /* Dock Plugin.bundle */; }; 11 | 179E3E06200274A8000D74C2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 179E3E05200274A8000D74C2 /* main.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 176127E12002875400A2B1A4 /* Embed Dock Plugin */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "$(CONTENTS_FOLDER_PATH)/Dock Plugin"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | 176127EC2002883700A2B1A4 /* Dock Plugin.bundle in Embed Dock Plugin */, 22 | ); 23 | name = "Embed Dock Plugin"; 24 | runOnlyForDeploymentPostprocessing = 0; 25 | }; 26 | /* End PBXCopyFilesBuildPhase section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 176127E9200287F500A2B1A4 /* Dock Plugin.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = "Dock Plugin.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 179E3DF9200274A8000D74C2 /* Sculpt Comfort Mission Control.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Sculpt Comfort Mission Control.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 179E3E04200274A8000D74C2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 179E3E05200274A8000D74C2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | 179E3DF6200274A8000D74C2 /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | ); 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXFrameworksBuildPhase section */ 44 | 45 | /* Begin PBXGroup section */ 46 | 176127E5200287E000A2B1A4 /* Dock Plugin */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | 176127E9200287F500A2B1A4 /* Dock Plugin.bundle */, 50 | ); 51 | name = "Dock Plugin"; 52 | path = "New Group"; 53 | sourceTree = ""; 54 | }; 55 | 179E3DF0200274A8000D74C2 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 179E3DFB200274A8000D74C2 /* Sources */, 59 | 176127E5200287E000A2B1A4 /* Dock Plugin */, 60 | 179E3DFA200274A8000D74C2 /* Products */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | 179E3DFA200274A8000D74C2 /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 179E3DF9200274A8000D74C2 /* Sculpt Comfort Mission Control.app */, 68 | ); 69 | name = Products; 70 | sourceTree = ""; 71 | }; 72 | 179E3DFB200274A8000D74C2 /* Sources */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 179E3E04200274A8000D74C2 /* Info.plist */, 76 | 179E3E05200274A8000D74C2 /* main.m */, 77 | ); 78 | path = Sources; 79 | sourceTree = ""; 80 | }; 81 | /* End PBXGroup section */ 82 | 83 | /* Begin PBXNativeTarget section */ 84 | 179E3DF8200274A8000D74C2 /* Sculpt Comfort Mission Control */ = { 85 | isa = PBXNativeTarget; 86 | buildConfigurationList = 179E3E0A200274A8000D74C2 /* Build configuration list for PBXNativeTarget "Sculpt Comfort Mission Control" */; 87 | buildPhases = ( 88 | 179E3DF5200274A8000D74C2 /* Sources */, 89 | 179E3DF6200274A8000D74C2 /* Frameworks */, 90 | 179E3DF7200274A8000D74C2 /* Resources */, 91 | 176127E12002875400A2B1A4 /* Embed Dock Plugin */, 92 | ); 93 | buildRules = ( 94 | ); 95 | dependencies = ( 96 | ); 97 | name = "Sculpt Comfort Mission Control"; 98 | productName = "Loader App"; 99 | productReference = 179E3DF9200274A8000D74C2 /* Sculpt Comfort Mission Control.app */; 100 | productType = "com.apple.product-type.application"; 101 | }; 102 | /* End PBXNativeTarget section */ 103 | 104 | /* Begin PBXProject section */ 105 | 179E3DF1200274A8000D74C2 /* Project object */ = { 106 | isa = PBXProject; 107 | attributes = { 108 | LastUpgradeCheck = 0920; 109 | ORGANIZATIONNAME = deej; 110 | TargetAttributes = { 111 | 179E3DF8200274A8000D74C2 = { 112 | CreatedOnToolsVersion = 9.2; 113 | ProvisioningStyle = Manual; 114 | SystemCapabilities = { 115 | com.apple.Sandbox = { 116 | enabled = 0; 117 | }; 118 | }; 119 | }; 120 | }; 121 | }; 122 | buildConfigurationList = 179E3DF4200274A8000D74C2 /* Build configuration list for PBXProject "Loader App" */; 123 | compatibilityVersion = "Xcode 8.0"; 124 | developmentRegion = en; 125 | hasScannedForEncodings = 0; 126 | knownRegions = ( 127 | en, 128 | Base, 129 | ); 130 | mainGroup = 179E3DF0200274A8000D74C2; 131 | productRefGroup = 179E3DFA200274A8000D74C2 /* Products */; 132 | projectDirPath = ""; 133 | projectRoot = ""; 134 | targets = ( 135 | 179E3DF8200274A8000D74C2 /* Sculpt Comfort Mission Control */, 136 | ); 137 | }; 138 | /* End PBXProject section */ 139 | 140 | /* Begin PBXResourcesBuildPhase section */ 141 | 179E3DF7200274A8000D74C2 /* Resources */ = { 142 | isa = PBXResourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | /* End PBXResourcesBuildPhase section */ 149 | 150 | /* Begin PBXSourcesBuildPhase section */ 151 | 179E3DF5200274A8000D74C2 /* Sources */ = { 152 | isa = PBXSourcesBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | 179E3E06200274A8000D74C2 /* main.m in Sources */, 156 | ); 157 | runOnlyForDeploymentPostprocessing = 0; 158 | }; 159 | /* End PBXSourcesBuildPhase section */ 160 | 161 | /* Begin XCBuildConfiguration section */ 162 | 179E3E08200274A8000D74C2 /* Debug */ = { 163 | isa = XCBuildConfiguration; 164 | buildSettings = { 165 | ALWAYS_SEARCH_USER_PATHS = NO; 166 | CLANG_ANALYZER_NONNULL = YES; 167 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 168 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 169 | CLANG_CXX_LIBRARY = "libc++"; 170 | CLANG_ENABLE_MODULES = YES; 171 | CLANG_ENABLE_OBJC_ARC = YES; 172 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 173 | CLANG_WARN_BOOL_CONVERSION = YES; 174 | CLANG_WARN_COMMA = YES; 175 | CLANG_WARN_CONSTANT_CONVERSION = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 178 | CLANG_WARN_EMPTY_BODY = YES; 179 | CLANG_WARN_ENUM_CONVERSION = YES; 180 | CLANG_WARN_INFINITE_RECURSION = YES; 181 | CLANG_WARN_INT_CONVERSION = YES; 182 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 183 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 184 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 185 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 186 | CLANG_WARN_STRICT_PROTOTYPES = YES; 187 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 188 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 189 | CLANG_WARN_UNREACHABLE_CODE = YES; 190 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 191 | COPY_PHASE_STRIP = NO; 192 | DEBUG_INFORMATION_FORMAT = dwarf; 193 | ENABLE_STRICT_OBJC_MSGSEND = YES; 194 | ENABLE_TESTABILITY = YES; 195 | GCC_C_LANGUAGE_STANDARD = gnu11; 196 | GCC_DYNAMIC_NO_PIC = NO; 197 | GCC_NO_COMMON_BLOCKS = YES; 198 | GCC_OPTIMIZATION_LEVEL = 0; 199 | GCC_PREPROCESSOR_DEFINITIONS = ( 200 | "DEBUG=1", 201 | "$(inherited)", 202 | ); 203 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 204 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 205 | GCC_WARN_UNDECLARED_SELECTOR = YES; 206 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 207 | GCC_WARN_UNUSED_FUNCTION = YES; 208 | GCC_WARN_UNUSED_VARIABLE = YES; 209 | MACOSX_DEPLOYMENT_TARGET = 10.12; 210 | MTL_ENABLE_DEBUG_INFO = YES; 211 | ONLY_ACTIVE_ARCH = YES; 212 | SDKROOT = macosx; 213 | }; 214 | name = Debug; 215 | }; 216 | 179E3E09200274A8000D74C2 /* Release */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | ALWAYS_SEARCH_USER_PATHS = NO; 220 | CLANG_ANALYZER_NONNULL = YES; 221 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 223 | CLANG_CXX_LIBRARY = "libc++"; 224 | CLANG_ENABLE_MODULES = YES; 225 | CLANG_ENABLE_OBJC_ARC = YES; 226 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 227 | CLANG_WARN_BOOL_CONVERSION = YES; 228 | CLANG_WARN_COMMA = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INFINITE_RECURSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 237 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 238 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 239 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 240 | CLANG_WARN_STRICT_PROTOTYPES = YES; 241 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 242 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 243 | CLANG_WARN_UNREACHABLE_CODE = YES; 244 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 245 | COPY_PHASE_STRIP = NO; 246 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 247 | ENABLE_NS_ASSERTIONS = NO; 248 | ENABLE_STRICT_OBJC_MSGSEND = YES; 249 | GCC_C_LANGUAGE_STANDARD = gnu11; 250 | GCC_NO_COMMON_BLOCKS = YES; 251 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 252 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 253 | GCC_WARN_UNDECLARED_SELECTOR = YES; 254 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 255 | GCC_WARN_UNUSED_FUNCTION = YES; 256 | GCC_WARN_UNUSED_VARIABLE = YES; 257 | MACOSX_DEPLOYMENT_TARGET = 10.12; 258 | MTL_ENABLE_DEBUG_INFO = NO; 259 | SDKROOT = macosx; 260 | }; 261 | name = Release; 262 | }; 263 | 179E3E0B200274A8000D74C2 /* Debug */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | COMBINE_HIDPI_IMAGES = YES; 267 | INFOPLIST_FILE = Sources/Info.plist; 268 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 269 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Loader-App"; 270 | PRODUCT_NAME = "$(TARGET_NAME)"; 271 | }; 272 | name = Debug; 273 | }; 274 | 179E3E0C200274A8000D74C2 /* Release */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | COMBINE_HIDPI_IMAGES = YES; 278 | INFOPLIST_FILE = Sources/Info.plist; 279 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 280 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Loader-App"; 281 | PRODUCT_NAME = "$(TARGET_NAME)"; 282 | }; 283 | name = Release; 284 | }; 285 | /* End XCBuildConfiguration section */ 286 | 287 | /* Begin XCConfigurationList section */ 288 | 179E3DF4200274A8000D74C2 /* Build configuration list for PBXProject "Loader App" */ = { 289 | isa = XCConfigurationList; 290 | buildConfigurations = ( 291 | 179E3E08200274A8000D74C2 /* Debug */, 292 | 179E3E09200274A8000D74C2 /* Release */, 293 | ); 294 | defaultConfigurationIsVisible = 0; 295 | defaultConfigurationName = Release; 296 | }; 297 | 179E3E0A200274A8000D74C2 /* Build configuration list for PBXNativeTarget "Sculpt Comfort Mission Control" */ = { 298 | isa = XCConfigurationList; 299 | buildConfigurations = ( 300 | 179E3E0B200274A8000D74C2 /* Debug */, 301 | 179E3E0C200274A8000D74C2 /* Release */, 302 | ); 303 | defaultConfigurationIsVisible = 0; 304 | defaultConfigurationName = Release; 305 | }; 306 | /* End XCConfigurationList section */ 307 | }; 308 | rootObject = 179E3DF1200274A8000D74C2 /* Project object */; 309 | } 310 | -------------------------------------------------------------------------------- /Preference Pane/Preference Pane.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1725BE472004427E00D7A881 /* PreferencePane.h in Headers */ = {isa = PBXBuildFile; fileRef = 1725BE462004427E00D7A881 /* PreferencePane.h */; }; 11 | 1725BE492004427E00D7A881 /* PreferencePane.m in Sources */ = {isa = PBXBuildFile; fileRef = 1725BE482004427E00D7A881 /* PreferencePane.m */; }; 12 | 1725BE4E2004427E00D7A881 /* PreferencePane.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1725BE4C2004427E00D7A881 /* PreferencePane.xib */; }; 13 | 1725BE832004562B00D7A881 /* libSharedForPreferencePane.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1725BE842004562B00D7A881 /* libSharedForPreferencePane.a */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | 1725BE432004427E00D7A881 /* SCMC Preferences.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SCMC Preferences.prefPane"; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | 1725BE462004427E00D7A881 /* PreferencePane.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PreferencePane.h; sourceTree = ""; }; 19 | 1725BE482004427E00D7A881 /* PreferencePane.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PreferencePane.m; sourceTree = ""; }; 20 | 1725BE4D2004427E00D7A881 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PreferencePane.xib; sourceTree = ""; }; 21 | 1725BE4F2004427E00D7A881 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 22 | 1725BE842004562B00D7A881 /* libSharedForPreferencePane.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSharedForPreferencePane.a; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | /* End PBXFileReference section */ 24 | 25 | /* Begin PBXFrameworksBuildPhase section */ 26 | 1725BE3F2004427E00D7A881 /* Frameworks */ = { 27 | isa = PBXFrameworksBuildPhase; 28 | buildActionMask = 2147483647; 29 | files = ( 30 | 1725BE832004562B00D7A881 /* libSharedForPreferencePane.a in Frameworks */, 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | 1725BE392004427E00D7A881 = { 38 | isa = PBXGroup; 39 | children = ( 40 | 1725BE452004427E00D7A881 /* Sources */, 41 | 1725BE442004427E00D7A881 /* Products */, 42 | 1725BE5920044A6B00D7A881 /* Frameworks */, 43 | ); 44 | sourceTree = ""; 45 | }; 46 | 1725BE442004427E00D7A881 /* Products */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | 1725BE432004427E00D7A881 /* SCMC Preferences.prefPane */, 50 | ); 51 | name = Products; 52 | sourceTree = ""; 53 | }; 54 | 1725BE452004427E00D7A881 /* Sources */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | 1725BE462004427E00D7A881 /* PreferencePane.h */, 58 | 1725BE482004427E00D7A881 /* PreferencePane.m */, 59 | 1725BE4C2004427E00D7A881 /* PreferencePane.xib */, 60 | 1725BE4F2004427E00D7A881 /* Info.plist */, 61 | ); 62 | path = Sources; 63 | sourceTree = ""; 64 | }; 65 | 1725BE5920044A6B00D7A881 /* Frameworks */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 1725BE842004562B00D7A881 /* libSharedForPreferencePane.a */, 69 | ); 70 | name = Frameworks; 71 | sourceTree = ""; 72 | }; 73 | /* End PBXGroup section */ 74 | 75 | /* Begin PBXHeadersBuildPhase section */ 76 | 1725BE402004427E00D7A881 /* Headers */ = { 77 | isa = PBXHeadersBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | 1725BE472004427E00D7A881 /* PreferencePane.h in Headers */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXHeadersBuildPhase section */ 85 | 86 | /* Begin PBXNativeTarget section */ 87 | 1725BE422004427E00D7A881 /* SCMC Preferences */ = { 88 | isa = PBXNativeTarget; 89 | buildConfigurationList = 1725BE522004427E00D7A881 /* Build configuration list for PBXNativeTarget "SCMC Preferences" */; 90 | buildPhases = ( 91 | 1725BE3E2004427E00D7A881 /* Sources */, 92 | 1725BE3F2004427E00D7A881 /* Frameworks */, 93 | 1725BE402004427E00D7A881 /* Headers */, 94 | 1725BE412004427E00D7A881 /* Resources */, 95 | ); 96 | buildRules = ( 97 | ); 98 | dependencies = ( 99 | ); 100 | name = "SCMC Preferences"; 101 | productName = "Preference Pane"; 102 | productReference = 1725BE432004427E00D7A881 /* SCMC Preferences.prefPane */; 103 | productType = "com.apple.product-type.bundle"; 104 | }; 105 | /* End PBXNativeTarget section */ 106 | 107 | /* Begin PBXProject section */ 108 | 1725BE3A2004427E00D7A881 /* Project object */ = { 109 | isa = PBXProject; 110 | attributes = { 111 | LastUpgradeCheck = 0920; 112 | ORGANIZATIONNAME = deej; 113 | TargetAttributes = { 114 | 1725BE422004427E00D7A881 = { 115 | CreatedOnToolsVersion = 9.2; 116 | ProvisioningStyle = Automatic; 117 | }; 118 | }; 119 | }; 120 | buildConfigurationList = 1725BE3D2004427E00D7A881 /* Build configuration list for PBXProject "Preference Pane" */; 121 | compatibilityVersion = "Xcode 8.0"; 122 | developmentRegion = en; 123 | hasScannedForEncodings = 0; 124 | knownRegions = ( 125 | en, 126 | Base, 127 | ); 128 | mainGroup = 1725BE392004427E00D7A881; 129 | productRefGroup = 1725BE442004427E00D7A881 /* Products */; 130 | projectDirPath = ""; 131 | projectRoot = ""; 132 | targets = ( 133 | 1725BE422004427E00D7A881 /* SCMC Preferences */, 134 | ); 135 | }; 136 | /* End PBXProject section */ 137 | 138 | /* Begin PBXResourcesBuildPhase section */ 139 | 1725BE412004427E00D7A881 /* Resources */ = { 140 | isa = PBXResourcesBuildPhase; 141 | buildActionMask = 2147483647; 142 | files = ( 143 | 1725BE4E2004427E00D7A881 /* PreferencePane.xib in Resources */, 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | /* End PBXResourcesBuildPhase section */ 148 | 149 | /* Begin PBXSourcesBuildPhase section */ 150 | 1725BE3E2004427E00D7A881 /* Sources */ = { 151 | isa = PBXSourcesBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | 1725BE492004427E00D7A881 /* PreferencePane.m in Sources */, 155 | ); 156 | runOnlyForDeploymentPostprocessing = 0; 157 | }; 158 | /* End PBXSourcesBuildPhase section */ 159 | 160 | /* Begin PBXVariantGroup section */ 161 | 1725BE4C2004427E00D7A881 /* PreferencePane.xib */ = { 162 | isa = PBXVariantGroup; 163 | children = ( 164 | 1725BE4D2004427E00D7A881 /* Base */, 165 | ); 166 | name = PreferencePane.xib; 167 | sourceTree = ""; 168 | }; 169 | /* End PBXVariantGroup section */ 170 | 171 | /* Begin XCBuildConfiguration section */ 172 | 1725BE502004427E00D7A881 /* Debug */ = { 173 | isa = XCBuildConfiguration; 174 | buildSettings = { 175 | ALWAYS_SEARCH_USER_PATHS = NO; 176 | CLANG_ANALYZER_NONNULL = YES; 177 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 178 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 179 | CLANG_CXX_LIBRARY = "libc++"; 180 | CLANG_ENABLE_MODULES = YES; 181 | CLANG_ENABLE_OBJC_ARC = YES; 182 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 183 | CLANG_WARN_BOOL_CONVERSION = YES; 184 | CLANG_WARN_COMMA = YES; 185 | CLANG_WARN_CONSTANT_CONVERSION = YES; 186 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 187 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 188 | CLANG_WARN_EMPTY_BODY = YES; 189 | CLANG_WARN_ENUM_CONVERSION = YES; 190 | CLANG_WARN_INFINITE_RECURSION = YES; 191 | CLANG_WARN_INT_CONVERSION = YES; 192 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 193 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 194 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 195 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 196 | CLANG_WARN_STRICT_PROTOTYPES = YES; 197 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 198 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 199 | CLANG_WARN_UNREACHABLE_CODE = YES; 200 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 201 | CODE_SIGN_IDENTITY = "-"; 202 | COPY_PHASE_STRIP = NO; 203 | DEBUG_INFORMATION_FORMAT = dwarf; 204 | ENABLE_STRICT_OBJC_MSGSEND = YES; 205 | ENABLE_TESTABILITY = YES; 206 | GCC_C_LANGUAGE_STANDARD = gnu11; 207 | GCC_DYNAMIC_NO_PIC = NO; 208 | GCC_NO_COMMON_BLOCKS = YES; 209 | GCC_OPTIMIZATION_LEVEL = 0; 210 | GCC_PREPROCESSOR_DEFINITIONS = ( 211 | "DEBUG=1", 212 | "$(inherited)", 213 | ); 214 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 215 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 216 | GCC_WARN_UNDECLARED_SELECTOR = YES; 217 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 218 | GCC_WARN_UNUSED_FUNCTION = YES; 219 | GCC_WARN_UNUSED_VARIABLE = YES; 220 | MACOSX_DEPLOYMENT_TARGET = 10.12; 221 | MTL_ENABLE_DEBUG_INFO = YES; 222 | ONLY_ACTIVE_ARCH = YES; 223 | SDKROOT = macosx; 224 | }; 225 | name = Debug; 226 | }; 227 | 1725BE512004427E00D7A881 /* Release */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | ALWAYS_SEARCH_USER_PATHS = NO; 231 | CLANG_ANALYZER_NONNULL = YES; 232 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 234 | CLANG_CXX_LIBRARY = "libc++"; 235 | CLANG_ENABLE_MODULES = YES; 236 | CLANG_ENABLE_OBJC_ARC = YES; 237 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 238 | CLANG_WARN_BOOL_CONVERSION = YES; 239 | CLANG_WARN_COMMA = YES; 240 | CLANG_WARN_CONSTANT_CONVERSION = YES; 241 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 242 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 243 | CLANG_WARN_EMPTY_BODY = YES; 244 | CLANG_WARN_ENUM_CONVERSION = YES; 245 | CLANG_WARN_INFINITE_RECURSION = YES; 246 | CLANG_WARN_INT_CONVERSION = YES; 247 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 248 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 249 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 250 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 251 | CLANG_WARN_STRICT_PROTOTYPES = YES; 252 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 253 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 254 | CLANG_WARN_UNREACHABLE_CODE = YES; 255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 256 | CODE_SIGN_IDENTITY = "-"; 257 | COPY_PHASE_STRIP = NO; 258 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 259 | ENABLE_NS_ASSERTIONS = NO; 260 | ENABLE_STRICT_OBJC_MSGSEND = YES; 261 | GCC_C_LANGUAGE_STANDARD = gnu11; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 264 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 265 | GCC_WARN_UNDECLARED_SELECTOR = YES; 266 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 267 | GCC_WARN_UNUSED_FUNCTION = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | MACOSX_DEPLOYMENT_TARGET = 10.12; 270 | MTL_ENABLE_DEBUG_INFO = NO; 271 | SDKROOT = macosx; 272 | }; 273 | name = Release; 274 | }; 275 | 1725BE532004427E00D7A881 /* Debug */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | CODE_SIGN_IDENTITY = "Mac Developer"; 279 | CODE_SIGN_STYLE = Automatic; 280 | COMBINE_HIDPI_IMAGES = YES; 281 | DEVELOPMENT_TEAM = X58FT7637Z; 282 | INFOPLIST_FILE = Sources/Info.plist; 283 | INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; 284 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Preference-Pane"; 285 | PRODUCT_NAME = "$(TARGET_NAME)"; 286 | PROVISIONING_PROFILE_SPECIFIER = ""; 287 | USER_HEADER_SEARCH_PATHS = $BUILT_PRODUCTS_DIR/libSharedForPreferencePane; 288 | WRAPPER_EXTENSION = prefPane; 289 | }; 290 | name = Debug; 291 | }; 292 | 1725BE542004427E00D7A881 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | CODE_SIGN_IDENTITY = "Mac Developer"; 296 | CODE_SIGN_STYLE = Automatic; 297 | COMBINE_HIDPI_IMAGES = YES; 298 | DEVELOPMENT_TEAM = X58FT7637Z; 299 | INFOPLIST_FILE = Sources/Info.plist; 300 | INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; 301 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Preference-Pane"; 302 | PRODUCT_NAME = "$(TARGET_NAME)"; 303 | PROVISIONING_PROFILE_SPECIFIER = ""; 304 | USER_HEADER_SEARCH_PATHS = $BUILT_PRODUCTS_DIR/libSharedForPreferencePane; 305 | WRAPPER_EXTENSION = prefPane; 306 | }; 307 | name = Release; 308 | }; 309 | /* End XCBuildConfiguration section */ 310 | 311 | /* Begin XCConfigurationList section */ 312 | 1725BE3D2004427E00D7A881 /* Build configuration list for PBXProject "Preference Pane" */ = { 313 | isa = XCConfigurationList; 314 | buildConfigurations = ( 315 | 1725BE502004427E00D7A881 /* Debug */, 316 | 1725BE512004427E00D7A881 /* Release */, 317 | ); 318 | defaultConfigurationIsVisible = 0; 319 | defaultConfigurationName = Release; 320 | }; 321 | 1725BE522004427E00D7A881 /* Build configuration list for PBXNativeTarget "SCMC Preferences" */ = { 322 | isa = XCConfigurationList; 323 | buildConfigurations = ( 324 | 1725BE532004427E00D7A881 /* Debug */, 325 | 1725BE542004427E00D7A881 /* Release */, 326 | ); 327 | defaultConfigurationIsVisible = 0; 328 | defaultConfigurationName = Release; 329 | }; 330 | /* End XCConfigurationList section */ 331 | }; 332 | rootObject = 1725BE3A2004427E00D7A881 /* Project object */; 333 | } 334 | -------------------------------------------------------------------------------- /Dock Plugin/Dock Plugin.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1725BE5D20044A7600D7A881 /* libShared.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1725BE5E20044A7600D7A881 /* libShared.a */; }; 11 | 1734B792205B031A006EC5E5 /* SCMCActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1734B791205B031A006EC5E5 /* SCMCActions.m */; }; 12 | 17354922205AE8F5004923F0 /* Init.m in Sources */ = {isa = PBXBuildFile; fileRef = 17354921205AE8F5004923F0 /* Init.m */; }; 13 | 17BF095F205BD650002E58D9 /* SCMCClickHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BF095E205BD650002E58D9 /* SCMCClickHandler.m */; }; 14 | 17BF0967205BDB4C002E58D9 /* SCMCActionStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BF0965205BDB4C002E58D9 /* SCMCActionStore.m */; }; 15 | 17BF0968205BDB4C002E58D9 /* SCMCCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BF0966205BDB4C002E58D9 /* SCMCCore.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 1725BE5E20044A7600D7A881 /* libShared.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libShared.a; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 1734B790205B031A006EC5E5 /* SCMCActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCMCActions.h; sourceTree = ""; }; 21 | 1734B791205B031A006EC5E5 /* SCMCActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCMCActions.m; sourceTree = ""; }; 22 | 17354921205AE8F5004923F0 /* Init.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Init.m; sourceTree = ""; }; 23 | 1739B866205ADA0C00910CE7 /* Dock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Dock.h; sourceTree = ""; }; 24 | 179E3E2F20028348000D74C2 /* Dock Plugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Dock Plugin.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 179E3E3220028348000D74C2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | 17BF0956205BBDBA002E58D9 /* SCMCAction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCMCAction.h; sourceTree = ""; }; 27 | 17BF095D205BD650002E58D9 /* SCMCClickHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCMCClickHandler.h; sourceTree = ""; }; 28 | 17BF095E205BD650002E58D9 /* SCMCClickHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCMCClickHandler.m; sourceTree = ""; }; 29 | 17BF0963205BDB4C002E58D9 /* SCMCActionStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCMCActionStore.h; sourceTree = ""; }; 30 | 17BF0964205BDB4C002E58D9 /* SCMCCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCMCCore.h; sourceTree = ""; }; 31 | 17BF0965205BDB4C002E58D9 /* SCMCActionStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCMCActionStore.m; sourceTree = ""; }; 32 | 17BF0966205BDB4C002E58D9 /* SCMCCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCMCCore.m; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | 179E3E2C20028348000D74C2 /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | 1725BE5D20044A7600D7A881 /* libShared.a in Frameworks */, 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | 1725BE5C20044A7600D7A881 /* Frameworks */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | 1725BE5E20044A7600D7A881 /* libShared.a */, 51 | ); 52 | name = Frameworks; 53 | sourceTree = ""; 54 | }; 55 | 179E3E2620028348000D74C2 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 179E3E3120028348000D74C2 /* Sources */, 59 | 179E3E3020028348000D74C2 /* Products */, 60 | 1725BE5C20044A7600D7A881 /* Frameworks */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | 179E3E3020028348000D74C2 /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 179E3E2F20028348000D74C2 /* Dock Plugin.bundle */, 68 | ); 69 | name = Products; 70 | sourceTree = ""; 71 | }; 72 | 179E3E3120028348000D74C2 /* Sources */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 179E3E3220028348000D74C2 /* Info.plist */, 76 | 1739B866205ADA0C00910CE7 /* Dock.h */, 77 | 17354921205AE8F5004923F0 /* Init.m */, 78 | 17BF0956205BBDBA002E58D9 /* SCMCAction.h */, 79 | 1734B790205B031A006EC5E5 /* SCMCActions.h */, 80 | 1734B791205B031A006EC5E5 /* SCMCActions.m */, 81 | 17BF095D205BD650002E58D9 /* SCMCClickHandler.h */, 82 | 17BF095E205BD650002E58D9 /* SCMCClickHandler.m */, 83 | 17BF0963205BDB4C002E58D9 /* SCMCActionStore.h */, 84 | 17BF0965205BDB4C002E58D9 /* SCMCActionStore.m */, 85 | 17BF0964205BDB4C002E58D9 /* SCMCCore.h */, 86 | 17BF0966205BDB4C002E58D9 /* SCMCCore.m */, 87 | ); 88 | path = Sources; 89 | sourceTree = ""; 90 | }; 91 | /* End PBXGroup section */ 92 | 93 | /* Begin PBXNativeTarget section */ 94 | 179E3E2E20028348000D74C2 /* Dock Plugin */ = { 95 | isa = PBXNativeTarget; 96 | buildConfigurationList = 179E3E3520028348000D74C2 /* Build configuration list for PBXNativeTarget "Dock Plugin" */; 97 | buildPhases = ( 98 | 179E3E2B20028348000D74C2 /* Sources */, 99 | 179E3E2C20028348000D74C2 /* Frameworks */, 100 | 179E3E2D20028348000D74C2 /* Resources */, 101 | ); 102 | buildRules = ( 103 | ); 104 | dependencies = ( 105 | ); 106 | name = "Dock Plugin"; 107 | productName = "Dock Plugin"; 108 | productReference = 179E3E2F20028348000D74C2 /* Dock Plugin.bundle */; 109 | productType = "com.apple.product-type.bundle"; 110 | }; 111 | /* End PBXNativeTarget section */ 112 | 113 | /* Begin PBXProject section */ 114 | 179E3E2720028348000D74C2 /* Project object */ = { 115 | isa = PBXProject; 116 | attributes = { 117 | LastUpgradeCheck = 0920; 118 | ORGANIZATIONNAME = deej; 119 | TargetAttributes = { 120 | 179E3E2E20028348000D74C2 = { 121 | CreatedOnToolsVersion = 9.2; 122 | ProvisioningStyle = Manual; 123 | }; 124 | }; 125 | }; 126 | buildConfigurationList = 179E3E2A20028348000D74C2 /* Build configuration list for PBXProject "Dock Plugin" */; 127 | compatibilityVersion = "Xcode 8.0"; 128 | developmentRegion = en; 129 | hasScannedForEncodings = 0; 130 | knownRegions = ( 131 | en, 132 | ); 133 | mainGroup = 179E3E2620028348000D74C2; 134 | productRefGroup = 179E3E3020028348000D74C2 /* Products */; 135 | projectDirPath = ""; 136 | projectRoot = ""; 137 | targets = ( 138 | 179E3E2E20028348000D74C2 /* Dock Plugin */, 139 | ); 140 | }; 141 | /* End PBXProject section */ 142 | 143 | /* Begin PBXResourcesBuildPhase section */ 144 | 179E3E2D20028348000D74C2 /* Resources */ = { 145 | isa = PBXResourcesBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXResourcesBuildPhase section */ 152 | 153 | /* Begin PBXSourcesBuildPhase section */ 154 | 179E3E2B20028348000D74C2 /* Sources */ = { 155 | isa = PBXSourcesBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | 17354922205AE8F5004923F0 /* Init.m in Sources */, 159 | 17BF0968205BDB4C002E58D9 /* SCMCCore.m in Sources */, 160 | 17BF0967205BDB4C002E58D9 /* SCMCActionStore.m in Sources */, 161 | 1734B792205B031A006EC5E5 /* SCMCActions.m in Sources */, 162 | 17BF095F205BD650002E58D9 /* SCMCClickHandler.m in Sources */, 163 | ); 164 | runOnlyForDeploymentPostprocessing = 0; 165 | }; 166 | /* End PBXSourcesBuildPhase section */ 167 | 168 | /* Begin XCBuildConfiguration section */ 169 | 179E3E3320028348000D74C2 /* Debug */ = { 170 | isa = XCBuildConfiguration; 171 | buildSettings = { 172 | ALWAYS_SEARCH_USER_PATHS = NO; 173 | CLANG_ANALYZER_NONNULL = YES; 174 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 175 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 176 | CLANG_CXX_LIBRARY = "libc++"; 177 | CLANG_ENABLE_MODULES = YES; 178 | CLANG_ENABLE_OBJC_ARC = YES; 179 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 180 | CLANG_WARN_BOOL_CONVERSION = YES; 181 | CLANG_WARN_COMMA = YES; 182 | CLANG_WARN_CONSTANT_CONVERSION = YES; 183 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 184 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 185 | CLANG_WARN_EMPTY_BODY = YES; 186 | CLANG_WARN_ENUM_CONVERSION = YES; 187 | CLANG_WARN_INFINITE_RECURSION = YES; 188 | CLANG_WARN_INT_CONVERSION = YES; 189 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 190 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 191 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 192 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 193 | CLANG_WARN_STRICT_PROTOTYPES = YES; 194 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 195 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 196 | CLANG_WARN_UNREACHABLE_CODE = YES; 197 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 198 | CODE_SIGN_IDENTITY = "SCMC App Internal Use"; 199 | CODE_SIGN_STYLE = Manual; 200 | COPY_PHASE_STRIP = NO; 201 | DEBUG_INFORMATION_FORMAT = dwarf; 202 | ENABLE_STRICT_OBJC_MSGSEND = YES; 203 | ENABLE_TESTABILITY = YES; 204 | GCC_C_LANGUAGE_STANDARD = gnu11; 205 | GCC_DYNAMIC_NO_PIC = NO; 206 | GCC_NO_COMMON_BLOCKS = YES; 207 | GCC_OPTIMIZATION_LEVEL = 0; 208 | GCC_PREPROCESSOR_DEFINITIONS = ( 209 | "DEBUG=1", 210 | "$(inherited)", 211 | ); 212 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 213 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 214 | GCC_WARN_UNDECLARED_SELECTOR = YES; 215 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 216 | GCC_WARN_UNUSED_FUNCTION = YES; 217 | GCC_WARN_UNUSED_VARIABLE = YES; 218 | MACOSX_DEPLOYMENT_TARGET = 10.12; 219 | MTL_ENABLE_DEBUG_INFO = YES; 220 | ONLY_ACTIVE_ARCH = YES; 221 | SDKROOT = macosx; 222 | }; 223 | name = Debug; 224 | }; 225 | 179E3E3420028348000D74C2 /* Release */ = { 226 | isa = XCBuildConfiguration; 227 | buildSettings = { 228 | ALWAYS_SEARCH_USER_PATHS = NO; 229 | CLANG_ANALYZER_NONNULL = YES; 230 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 231 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 232 | CLANG_CXX_LIBRARY = "libc++"; 233 | CLANG_ENABLE_MODULES = YES; 234 | CLANG_ENABLE_OBJC_ARC = YES; 235 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 236 | CLANG_WARN_BOOL_CONVERSION = YES; 237 | CLANG_WARN_COMMA = YES; 238 | CLANG_WARN_CONSTANT_CONVERSION = 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_LITERAL_CONVERSION = YES; 247 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 248 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 249 | CLANG_WARN_STRICT_PROTOTYPES = YES; 250 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 251 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 252 | CLANG_WARN_UNREACHABLE_CODE = YES; 253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 254 | CODE_SIGN_IDENTITY = "SCMC App Internal Use"; 255 | CODE_SIGN_STYLE = Manual; 256 | COPY_PHASE_STRIP = NO; 257 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 258 | ENABLE_NS_ASSERTIONS = NO; 259 | ENABLE_STRICT_OBJC_MSGSEND = YES; 260 | GCC_C_LANGUAGE_STANDARD = gnu11; 261 | GCC_NO_COMMON_BLOCKS = YES; 262 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 263 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 264 | GCC_WARN_UNDECLARED_SELECTOR = YES; 265 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 266 | GCC_WARN_UNUSED_FUNCTION = YES; 267 | GCC_WARN_UNUSED_VARIABLE = YES; 268 | MACOSX_DEPLOYMENT_TARGET = 10.12; 269 | MTL_ENABLE_DEBUG_INFO = NO; 270 | SDKROOT = macosx; 271 | }; 272 | name = Release; 273 | }; 274 | 179E3E3620028348000D74C2 /* Debug */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | COMBINE_HIDPI_IMAGES = YES; 278 | INFOPLIST_FILE = Sources/Info.plist; 279 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 280 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Dock-Plugin"; 281 | PRODUCT_NAME = "$(TARGET_NAME)"; 282 | SKIP_INSTALL = YES; 283 | USER_HEADER_SEARCH_PATHS = $TARGET_BUILD_DIR/libShared; 284 | WRAPPER_EXTENSION = bundle; 285 | }; 286 | name = Debug; 287 | }; 288 | 179E3E3720028348000D74C2 /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | COMBINE_HIDPI_IMAGES = YES; 292 | INFOPLIST_FILE = Sources/Info.plist; 293 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 294 | PRODUCT_BUNDLE_IDENTIFIER = "deej.SCMC.Dock-Plugin"; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SKIP_INSTALL = YES; 297 | USER_HEADER_SEARCH_PATHS = $TARGET_BUILD_DIR/libShared; 298 | WRAPPER_EXTENSION = bundle; 299 | }; 300 | name = Release; 301 | }; 302 | /* End XCBuildConfiguration section */ 303 | 304 | /* Begin XCConfigurationList section */ 305 | 179E3E2A20028348000D74C2 /* Build configuration list for PBXProject "Dock Plugin" */ = { 306 | isa = XCConfigurationList; 307 | buildConfigurations = ( 308 | 179E3E3320028348000D74C2 /* Debug */, 309 | 179E3E3420028348000D74C2 /* Release */, 310 | ); 311 | defaultConfigurationIsVisible = 0; 312 | defaultConfigurationName = Release; 313 | }; 314 | 179E3E3520028348000D74C2 /* Build configuration list for PBXNativeTarget "Dock Plugin" */ = { 315 | isa = XCConfigurationList; 316 | buildConfigurations = ( 317 | 179E3E3620028348000D74C2 /* Debug */, 318 | 179E3E3720028348000D74C2 /* Release */, 319 | ); 320 | defaultConfigurationIsVisible = 0; 321 | defaultConfigurationName = Release; 322 | }; 323 | /* End XCConfigurationList section */ 324 | }; 325 | rootObject = 179E3E2720028348000D74C2 /* Project object */; 326 | } 327 | -------------------------------------------------------------------------------- /Shared/Shared.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 171CFB3B2005538200B7C645 /* SCMCEventSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 171CFB372005538200B7C645 /* SCMCEventSpec.m */; }; 11 | 171CFB3C2005538200B7C645 /* SCMCEventSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 171CFB372005538200B7C645 /* SCMCEventSpec.m */; }; 12 | 171CFB3D2005538200B7C645 /* SCMCConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 171CFB392005538200B7C645 /* SCMCConfiguration.m */; }; 13 | 171CFB3E2005538200B7C645 /* SCMCConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 171CFB392005538200B7C645 /* SCMCConfiguration.m */; }; 14 | 1725BE89200458BD00D7A881 /* PreferencePaneNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 1725BE88200458BD00D7A881 /* PreferencePaneNames.h */; settings = {ATTRIBUTES = (Private, ); }; }; 15 | 1725BE8A200458BF00D7A881 /* PreferencePaneNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 1725BE88200458BD00D7A881 /* PreferencePaneNames.h */; settings = {ATTRIBUTES = (Private, ); }; }; 16 | 172B0A1B2059951000C6B521 /* SCMCEventTapListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 172B0A192059951000C6B521 /* SCMCEventTapListener.h */; settings = {ATTRIBUTES = (Private, ); }; }; 17 | 172B0A1C2059951000C6B521 /* SCMCEventTapListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 172B0A1A2059951000C6B521 /* SCMCEventTapListener.m */; }; 18 | 172B0A232059A4A000C6B521 /* SCMCEventTapListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 172B0A192059951000C6B521 /* SCMCEventTapListener.h */; settings = {ATTRIBUTES = (Private, ); }; }; 19 | 172B0A242059A4A200C6B521 /* SCMCEventTapListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 172B0A1A2059951000C6B521 /* SCMCEventTapListener.m */; }; 20 | 1739B869205AE55200910CE7 /* SCMCHidListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 178E95B0205946E500407688 /* SCMCHidListener.h */; settings = {ATTRIBUTES = (Private, ); }; }; 21 | 1739B86A205AE55400910CE7 /* SCMCHidListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 178E95B1205946E500407688 /* SCMCHidListener.m */; }; 22 | 175F4CAE200ADC9800EC8475 /* SCMCConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 171CFB382005538200B7C645 /* SCMCConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; }; 23 | 175F4CAF200ADC9800EC8475 /* SCMCEventSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 171CFB3A2005538200B7C645 /* SCMCEventSpec.h */; settings = {ATTRIBUTES = (Private, ); }; }; 24 | 175F4CB0200ADC9900EC8475 /* SCMCConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 171CFB382005538200B7C645 /* SCMCConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; }; 25 | 175F4CB1200ADC9900EC8475 /* SCMCEventSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 171CFB3A2005538200B7C645 /* SCMCEventSpec.h */; settings = {ATTRIBUTES = (Private, ); }; }; 26 | 178E95B2205946E500407688 /* SCMCHidListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 178E95B0205946E500407688 /* SCMCHidListener.h */; settings = {ATTRIBUTES = (Private, ); }; }; 27 | 178E95B3205946E500407688 /* SCMCHidListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 178E95B1205946E500407688 /* SCMCHidListener.m */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 171CFB372005538200B7C645 /* SCMCEventSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCMCEventSpec.m; sourceTree = ""; }; 32 | 171CFB382005538200B7C645 /* SCMCConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCMCConfiguration.h; sourceTree = ""; }; 33 | 171CFB392005538200B7C645 /* SCMCConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCMCConfiguration.m; sourceTree = ""; }; 34 | 171CFB3A2005538200B7C645 /* SCMCEventSpec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCMCEventSpec.h; sourceTree = ""; }; 35 | 1725BE722004533700D7A881 /* libSharedForPreferencePane.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSharedForPreferencePane.a; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 1725BE88200458BD00D7A881 /* PreferencePaneNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencePaneNames.h; sourceTree = ""; }; 37 | 172B0A192059951000C6B521 /* SCMCEventTapListener.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCMCEventTapListener.h; sourceTree = ""; }; 38 | 172B0A1A2059951000C6B521 /* SCMCEventTapListener.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCMCEventTapListener.m; sourceTree = ""; }; 39 | 172B0A202059A38400C6B521 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 40 | 172DE2FA20043FAD0069FEBB /* libShared.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libShared.a; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 178E95B0205946E500407688 /* SCMCHidListener.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCMCHidListener.h; sourceTree = ""; }; 42 | 178E95B1205946E500407688 /* SCMCHidListener.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCMCHidListener.m; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | 1725BE6F2004533700D7A881 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | 172DE2F720043FAD0069FEBB /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 172DE2F120043FAD0069FEBB = { 64 | isa = PBXGroup; 65 | children = ( 66 | 172DE2FC20043FAD0069FEBB /* Sources */, 67 | 172DE2FB20043FAD0069FEBB /* Products */, 68 | ); 69 | sourceTree = ""; 70 | }; 71 | 172DE2FB20043FAD0069FEBB /* Products */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 172DE2FA20043FAD0069FEBB /* libShared.a */, 75 | 1725BE722004533700D7A881 /* libSharedForPreferencePane.a */, 76 | ); 77 | name = Products; 78 | sourceTree = ""; 79 | }; 80 | 172DE2FC20043FAD0069FEBB /* Sources */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 172B0A202059A38400C6B521 /* PrefixHeader.pch */, 84 | 1725BE88200458BD00D7A881 /* PreferencePaneNames.h */, 85 | 171CFB382005538200B7C645 /* SCMCConfiguration.h */, 86 | 171CFB392005538200B7C645 /* SCMCConfiguration.m */, 87 | 171CFB3A2005538200B7C645 /* SCMCEventSpec.h */, 88 | 171CFB372005538200B7C645 /* SCMCEventSpec.m */, 89 | 178E95B0205946E500407688 /* SCMCHidListener.h */, 90 | 178E95B1205946E500407688 /* SCMCHidListener.m */, 91 | 172B0A192059951000C6B521 /* SCMCEventTapListener.h */, 92 | 172B0A1A2059951000C6B521 /* SCMCEventTapListener.m */, 93 | ); 94 | path = Sources; 95 | sourceTree = ""; 96 | }; 97 | /* End PBXGroup section */ 98 | 99 | /* Begin PBXHeadersBuildPhase section */ 100 | 1725BE702004533700D7A881 /* Headers */ = { 101 | isa = PBXHeadersBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | 1739B869205AE55200910CE7 /* SCMCHidListener.h in Headers */, 105 | 1725BE8A200458BF00D7A881 /* PreferencePaneNames.h in Headers */, 106 | 175F4CB0200ADC9900EC8475 /* SCMCConfiguration.h in Headers */, 107 | 175F4CB1200ADC9900EC8475 /* SCMCEventSpec.h in Headers */, 108 | 172B0A232059A4A000C6B521 /* SCMCEventTapListener.h in Headers */, 109 | ); 110 | runOnlyForDeploymentPostprocessing = 0; 111 | }; 112 | 172DE2F820043FAD0069FEBB /* Headers */ = { 113 | isa = PBXHeadersBuildPhase; 114 | buildActionMask = 2147483647; 115 | files = ( 116 | 1725BE89200458BD00D7A881 /* PreferencePaneNames.h in Headers */, 117 | 178E95B2205946E500407688 /* SCMCHidListener.h in Headers */, 118 | 175F4CAE200ADC9800EC8475 /* SCMCConfiguration.h in Headers */, 119 | 175F4CAF200ADC9800EC8475 /* SCMCEventSpec.h in Headers */, 120 | 172B0A1B2059951000C6B521 /* SCMCEventTapListener.h in Headers */, 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | /* End PBXHeadersBuildPhase section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 1725BE712004533700D7A881 /* SharedForPreferencePane */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 1725BE782004533800D7A881 /* Build configuration list for PBXNativeTarget "SharedForPreferencePane" */; 130 | buildPhases = ( 131 | 1725BE6E2004533700D7A881 /* Sources */, 132 | 1725BE6F2004533700D7A881 /* Frameworks */, 133 | 1725BE702004533700D7A881 /* Headers */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = SharedForPreferencePane; 140 | productName = SharedPrefixedNames; 141 | productReference = 1725BE722004533700D7A881 /* libSharedForPreferencePane.a */; 142 | productType = "com.apple.product-type.library.static"; 143 | }; 144 | 172DE2F920043FAD0069FEBB /* Shared */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 172DE30320043FAD0069FEBB /* Build configuration list for PBXNativeTarget "Shared" */; 147 | buildPhases = ( 148 | 172DE2F620043FAD0069FEBB /* Sources */, 149 | 172DE2F720043FAD0069FEBB /* Frameworks */, 150 | 172DE2F820043FAD0069FEBB /* Headers */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | ); 156 | name = Shared; 157 | productName = Shared; 158 | productReference = 172DE2FA20043FAD0069FEBB /* libShared.a */; 159 | productType = "com.apple.product-type.library.static"; 160 | }; 161 | /* End PBXNativeTarget section */ 162 | 163 | /* Begin PBXProject section */ 164 | 172DE2F220043FAD0069FEBB /* Project object */ = { 165 | isa = PBXProject; 166 | attributes = { 167 | LastUpgradeCheck = 0920; 168 | ORGANIZATIONNAME = deej; 169 | TargetAttributes = { 170 | 1725BE712004533700D7A881 = { 171 | CreatedOnToolsVersion = 9.2; 172 | ProvisioningStyle = Automatic; 173 | }; 174 | 172DE2F920043FAD0069FEBB = { 175 | CreatedOnToolsVersion = 9.2; 176 | ProvisioningStyle = Automatic; 177 | }; 178 | }; 179 | }; 180 | buildConfigurationList = 172DE2F520043FAD0069FEBB /* Build configuration list for PBXProject "Shared" */; 181 | compatibilityVersion = "Xcode 8.0"; 182 | developmentRegion = en; 183 | hasScannedForEncodings = 0; 184 | knownRegions = ( 185 | en, 186 | ); 187 | mainGroup = 172DE2F120043FAD0069FEBB; 188 | productRefGroup = 172DE2FB20043FAD0069FEBB /* Products */; 189 | projectDirPath = ""; 190 | projectRoot = ""; 191 | targets = ( 192 | 172DE2F920043FAD0069FEBB /* Shared */, 193 | 1725BE712004533700D7A881 /* SharedForPreferencePane */, 194 | ); 195 | }; 196 | /* End PBXProject section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | 1725BE6E2004533700D7A881 /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 172B0A242059A4A200C6B521 /* SCMCEventTapListener.m in Sources */, 204 | 171CFB3E2005538200B7C645 /* SCMCConfiguration.m in Sources */, 205 | 1739B86A205AE55400910CE7 /* SCMCHidListener.m in Sources */, 206 | 171CFB3C2005538200B7C645 /* SCMCEventSpec.m in Sources */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | 172DE2F620043FAD0069FEBB /* Sources */ = { 211 | isa = PBXSourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | 172B0A1C2059951000C6B521 /* SCMCEventTapListener.m in Sources */, 215 | 171CFB3D2005538200B7C645 /* SCMCConfiguration.m in Sources */, 216 | 178E95B3205946E500407688 /* SCMCHidListener.m in Sources */, 217 | 171CFB3B2005538200B7C645 /* SCMCEventSpec.m in Sources */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXSourcesBuildPhase section */ 222 | 223 | /* Begin XCBuildConfiguration section */ 224 | 1725BE792004533800D7A881 /* Debug */ = { 225 | isa = XCBuildConfiguration; 226 | buildSettings = { 227 | CODE_SIGN_STYLE = Automatic; 228 | EXECUTABLE_PREFIX = lib; 229 | GCC_PREPROCESSOR_DEFINITIONS = ( 230 | "$(inherited)", 231 | FOR_PREFERENCE_PANE, 232 | ); 233 | PRODUCT_NAME = "$(TARGET_NAME)"; 234 | }; 235 | name = Debug; 236 | }; 237 | 1725BE7A2004533800D7A881 /* Release */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | CODE_SIGN_STYLE = Automatic; 241 | EXECUTABLE_PREFIX = lib; 242 | PRODUCT_NAME = "$(TARGET_NAME)"; 243 | }; 244 | name = Release; 245 | }; 246 | 172DE30120043FAD0069FEBB /* Debug */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_ANALYZER_NONNULL = YES; 251 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 257 | CLANG_WARN_BOOL_CONVERSION = YES; 258 | CLANG_WARN_COMMA = YES; 259 | CLANG_WARN_CONSTANT_CONVERSION = YES; 260 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 261 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 262 | CLANG_WARN_EMPTY_BODY = YES; 263 | CLANG_WARN_ENUM_CONVERSION = YES; 264 | CLANG_WARN_INFINITE_RECURSION = YES; 265 | CLANG_WARN_INT_CONVERSION = YES; 266 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 267 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 268 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 269 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 270 | CLANG_WARN_STRICT_PROTOTYPES = YES; 271 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 272 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 273 | CLANG_WARN_UNREACHABLE_CODE = YES; 274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 275 | CODE_SIGN_IDENTITY = "-"; 276 | COPY_PHASE_STRIP = NO; 277 | DEBUG_INFORMATION_FORMAT = dwarf; 278 | ENABLE_STRICT_OBJC_MSGSEND = YES; 279 | ENABLE_TESTABILITY = YES; 280 | GCC_C_LANGUAGE_STANDARD = gnu11; 281 | GCC_DYNAMIC_NO_PIC = NO; 282 | GCC_NO_COMMON_BLOCKS = YES; 283 | GCC_OPTIMIZATION_LEVEL = 0; 284 | GCC_PREFIX_HEADER = Sources/PrefixHeader.pch; 285 | GCC_PREPROCESSOR_DEFINITIONS = ( 286 | "DEBUG=1", 287 | "$(inherited)", 288 | ); 289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 291 | GCC_WARN_UNDECLARED_SELECTOR = YES; 292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 293 | GCC_WARN_UNUSED_FUNCTION = YES; 294 | GCC_WARN_UNUSED_VARIABLE = YES; 295 | MACOSX_DEPLOYMENT_TARGET = 10.12; 296 | MTL_ENABLE_DEBUG_INFO = YES; 297 | ONLY_ACTIVE_ARCH = YES; 298 | PRIVATE_HEADERS_FOLDER_PATH = "lib$(TARGET_NAME)"; 299 | SDKROOT = macosx; 300 | SKIP_INSTALL = YES; 301 | }; 302 | name = Debug; 303 | }; 304 | 172DE30220043FAD0069FEBB /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ALWAYS_SEARCH_USER_PATHS = NO; 308 | CLANG_ANALYZER_NONNULL = YES; 309 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 315 | CLANG_WARN_BOOL_CONVERSION = YES; 316 | CLANG_WARN_COMMA = YES; 317 | CLANG_WARN_CONSTANT_CONVERSION = YES; 318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 319 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 326 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 327 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 328 | CLANG_WARN_STRICT_PROTOTYPES = YES; 329 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 330 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | CODE_SIGN_IDENTITY = "-"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | ENABLE_NS_ASSERTIONS = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu11; 339 | GCC_NO_COMMON_BLOCKS = YES; 340 | GCC_PREFIX_HEADER = Sources/PrefixHeader.pch; 341 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 342 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 343 | GCC_WARN_UNDECLARED_SELECTOR = YES; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.12; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | PRIVATE_HEADERS_FOLDER_PATH = "lib$(TARGET_NAME)"; 350 | SDKROOT = macosx; 351 | SKIP_INSTALL = YES; 352 | }; 353 | name = Release; 354 | }; 355 | 172DE30420043FAD0069FEBB /* Debug */ = { 356 | isa = XCBuildConfiguration; 357 | buildSettings = { 358 | CODE_SIGN_STYLE = Automatic; 359 | EXECUTABLE_PREFIX = lib; 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | }; 362 | name = Debug; 363 | }; 364 | 172DE30520043FAD0069FEBB /* Release */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | CODE_SIGN_STYLE = Automatic; 368 | EXECUTABLE_PREFIX = lib; 369 | PRODUCT_NAME = "$(TARGET_NAME)"; 370 | }; 371 | name = Release; 372 | }; 373 | /* End XCBuildConfiguration section */ 374 | 375 | /* Begin XCConfigurationList section */ 376 | 1725BE782004533800D7A881 /* Build configuration list for PBXNativeTarget "SharedForPreferencePane" */ = { 377 | isa = XCConfigurationList; 378 | buildConfigurations = ( 379 | 1725BE792004533800D7A881 /* Debug */, 380 | 1725BE7A2004533800D7A881 /* Release */, 381 | ); 382 | defaultConfigurationIsVisible = 0; 383 | defaultConfigurationName = Release; 384 | }; 385 | 172DE2F520043FAD0069FEBB /* Build configuration list for PBXProject "Shared" */ = { 386 | isa = XCConfigurationList; 387 | buildConfigurations = ( 388 | 172DE30120043FAD0069FEBB /* Debug */, 389 | 172DE30220043FAD0069FEBB /* Release */, 390 | ); 391 | defaultConfigurationIsVisible = 0; 392 | defaultConfigurationName = Release; 393 | }; 394 | 172DE30320043FAD0069FEBB /* Build configuration list for PBXNativeTarget "Shared" */ = { 395 | isa = XCConfigurationList; 396 | buildConfigurations = ( 397 | 172DE30420043FAD0069FEBB /* Debug */, 398 | 172DE30520043FAD0069FEBB /* Release */, 399 | ); 400 | defaultConfigurationIsVisible = 0; 401 | defaultConfigurationName = Release; 402 | }; 403 | /* End XCConfigurationList section */ 404 | }; 405 | rootObject = 172DE2F220043FAD0069FEBB /* Project object */; 406 | } 407 | --------------------------------------------------------------------------------