├── .gitignore
├── .gitmodules
├── .ruby-version
├── .travis.yml
├── Frameworks
└── NNKit
│ ├── NNKit.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── NNKit.xcscheme
│ ├── NNKit
│ ├── API Extension
│ │ ├── NSInvocation+NNCopying.h
│ │ ├── NSInvocation+NNCopying.m
│ │ ├── NSNotificationCenter+NNAdditions.h
│ │ ├── NSNotificationCenter+NNAdditions.m
│ │ ├── README.md
│ │ ├── despatch.h
│ │ ├── despatch.m
│ │ ├── runtime.c
│ │ └── runtime.h
│ ├── Actors
│ │ ├── NNCleanupProxy.h
│ │ ├── NNCleanupProxy.m
│ │ ├── NNMultiDispatchManager.h
│ │ ├── NNMultiDispatchManager.m
│ │ ├── NNPollingObject+Protected.h
│ │ ├── NNPollingObject.h
│ │ ├── NNPollingObject.m
│ │ ├── NNSelfInvalidatingObject.h
│ │ ├── NNSelfInvalidatingObject.m
│ │ └── README.md
│ ├── Collections
│ │ ├── NNWeakSet.h
│ │ ├── NNWeakSet.m
│ │ ├── NSCollections+NNComprehensions.h
│ │ ├── NSCollections+NNComprehensions.m
│ │ ├── README.md
│ │ ├── _NNWeakArrayTombstone.h
│ │ ├── _NNWeakArrayTombstone.m
│ │ ├── _NNWeakSetEnumerator.h
│ │ └── _NNWeakSetEnumerator.m
│ ├── Concurrency
│ │ ├── NNDelegateProxy.h
│ │ ├── NNDelegateProxy.m
│ │ └── README.md
│ ├── Hacks
│ │ ├── NNStrongifiedProperties.h
│ │ ├── NNStrongifiedProperties.m
│ │ ├── README.md
│ │ ├── memoize.h
│ │ ├── memoize.m
│ │ ├── nn_autofree.h
│ │ └── nn_autofree.m
│ ├── NNKit Mac-Prefix.pch
│ ├── NNKit iOS-Prefix.pch
│ ├── NNKit-Info.plist
│ ├── NNKit.h
│ ├── NNKit.m
│ ├── Services
│ │ ├── NNService+Protected.h
│ │ ├── NNService.h
│ │ ├── NNService.m
│ │ ├── NNServiceManager.h
│ │ ├── NNServiceManager.m
│ │ └── README.md
│ ├── Swizzling
│ │ ├── NNISASwizzledObject.h
│ │ ├── NNISASwizzledObject.m
│ │ ├── README.md
│ │ ├── nn_isaSwizzling.h
│ │ ├── nn_isaSwizzling.m
│ │ └── nn_isaSwizzling_Private.h
│ └── macros.h
│ ├── NNKitTests
│ ├── NNCleanupProxyTests.m
│ ├── NNComprehensionTests.m
│ ├── NNDelegateProxyTests.m
│ ├── NNKit Mac Tests-Info.plist
│ ├── NNKit iOS Tests-Info.plist
│ ├── NNMultiDispatchManagerTests.m
│ ├── NNPollingObjectTests.m
│ ├── NNSelfInvalidatingObjectTests.m
│ ├── NNServiceTests.m
│ ├── NNStrongifiedPropertiesTests.m
│ ├── NNSynthesizedObjectStorageTests.m
│ ├── NNTestCase.h
│ ├── NNTestCase.m
│ ├── NNWeakObserverTests.m
│ ├── NNWeakSetTests.m
│ ├── nn_autofreeTests.m
│ └── nn_isaSwizzlingTests.m
│ └── README.md
├── Podfile
├── Podfile.lock
├── README.md
├── Rakefile
├── Scripts
├── console.rb
├── reset_Accessibility.scpt
└── sign_update.rb
├── Switch.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ ├── xcbaselines
│ └── BCA734FC16DAC54000CD4C74.xcbaseline
│ │ ├── B10416B6-59AF-46B0-8C59-971F2DDC08B3.plist
│ │ └── Info.plist
│ └── xcschemes
│ └── Switch.xcscheme
├── Switch.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── Switch.xcscmblueprint
├── Switch
├── NNMainThreadGuard.m
├── NSLayoutConstraint+SWConstraintHelpers.h
├── NSLayoutConstraint+SWConstraintHelpers.m
├── NSScreen+SWAdditions.h
├── NSScreen+SWAdditions.m
├── NSSet+SWChaining.h
├── NSSet+SWChaining.m
├── Resources
│ ├── Keyboard.icns
│ └── weave.png
├── SWAPIEnabledWorker.h
├── SWAPIEnabledWorker.m
├── SWAccessibilityService.h
├── SWAccessibilityService.m
├── SWAdvancedPreferencesViewController.h
├── SWAdvancedPreferencesViewController.m
├── SWAdvancedPreferencesViewController.xib
├── SWAppDelegate.h
├── SWAppDelegate.m
├── SWApplication.h
├── SWApplication.m
├── SWCoreWindowController.h
├── SWCoreWindowController.m
├── SWCoreWindowService.h
├── SWCoreWindowService.m
├── SWEventTap.h
├── SWEventTap.m
├── SWGeneralPreferencesViewController.h
├── SWGeneralPreferencesViewController.m
├── SWGeneralPreferencesViewController.xib
├── SWHUDCollectionView.h
├── SWHUDCollectionView.m
├── SWHUDView.h
├── SWHUDView.m
├── SWHotKey.h
├── SWHotKey.m
├── SWInterfaceController.h
├── SWInterfaceController.m
├── SWKeyboardPreferencesViewController.h
├── SWKeyboardPreferencesViewController.m
├── SWKeyboardPreferencesViewController.xib
├── SWLoggingService.h
├── SWLoggingService.m
├── SWPreferencesService.h
├── SWPreferencesService.m
├── SWRoundedRectView.h
├── SWRoundedRectView.m
├── SWScrollControl.h
├── SWScrollControl.m
├── SWSelectionBoxView.h
├── SWSelectionBoxView.m
├── SWSelector.h
├── SWSelector.m
├── SWStateMachine.h
├── SWStateMachine.m
├── SWStatusBarMenuService.h
├── SWStatusBarMenuService.m
├── SWWindow+TweetbotQuirks.h
├── SWWindow+TweetbotQuirks.m
├── SWWindow.h
├── SWWindow.m
├── SWWindowContentsService.h
├── SWWindowContentsService.m
├── SWWindowGroup.h
├── SWWindowGroup.m
├── SWWindowListService.h
├── SWWindowListService.m
├── SWWindowListWorker.h
├── SWWindowListWorker.m
├── SWWindowThumbnailView.h
├── SWWindowThumbnailView.m
├── SWWindowWorker.h
├── SWWindowWorker.m
├── Sparkle.dsa_pub.pem
├── Switch-Bridging-Header.h
├── Switch-Info.plist
├── Switch-Prefix.pch
├── Switch.entitlements
├── constants.h
├── constants.m
├── debugger.c
├── debugger.h
├── en.lproj
│ ├── Credits.rtf
│ ├── InfoPlist.strings
│ └── MainMenu.xib
├── helpers.h
├── helpers.m
├── imageComparators.h
└── main.m
├── SwitchTests
├── NSImage+NNFilesystem.h
├── NSImage+NNFilesystem.m
├── NSWindow+NNScreenCapture.h
├── NSWindow+NNScreenCapture.m
├── References
│ └── image.tiff
├── SWChromeTests.m
├── SWDashTests.m
├── SWFinderTests.m
├── SWGithubTests.m
├── SWImageComparisonTests.m
├── SWIsolatorTests.m
├── SWMacVimTests.m
├── SWPowerboxTests.m
├── SWSafariTests.m
├── SWSanityTests.m
├── SWScrollControlTests.m
├── SWSelectorTests.m
├── SWSheetTests.m
├── SWStateMachineTests.m
├── SWTestApplication.h
├── SWTestApplication.m
├── SWTweetbotTests.m
├── SWWindowFilteringTests.h
├── SWWindowListServiceTestSuperclass.h
├── SWWindowListServiceTestSuperclass.m
├── SWWindowListServiceTests.m
├── SWWordTests.m
├── SWXcodeTests.m
├── SwitchTests-Info.plist
└── en.lproj
│ ├── 1376.ar
│ ├── 5891.ar
│ ├── 5904.ar
│ └── InfoPlist.strings
├── appcast.xml
├── exportOptionsApp.plist
└── relaunch
├── SWTerminationListener.h
├── SWTerminationListener.m
├── main.m
└── relaunch-Prefix.pch
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Frameworks/Haxcessibility"]
2 | path = Frameworks/Haxcessibility
3 | url = git://github.com/numist/Haxcessibility.git
4 | [submodule "Frameworks/ReactiveCocoa"]
5 | path = Frameworks/ReactiveCocoa
6 | url = git://github.com/numist/ReactiveCocoa.git
7 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | ruby-2.1.0
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | xcode_project: Switch.xcodeproj
3 | xcode_scheme: Switch
4 | osx_image: xcode9
5 |
6 | before_script:
7 | - export LANG=en_US.UTF-8
8 |
9 | install:
10 | - gem install rake
11 | - rake deps
12 |
13 | script:
14 | - rake app
15 | - rake test
16 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/NSInvocation+NNCopying.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSInvocation+NNCopying.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 03/10/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | @interface NSInvocation (NNCopying)
18 |
19 | - (instancetype)nn_copy;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/NSInvocation+NNCopying.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSInvocation+NNCopying.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 03/10/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSInvocation+NNCopying.h"
16 |
17 | @implementation NSInvocation (NNCopying)
18 |
19 | - (instancetype)nn_copy;
20 | {
21 | NSMethodSignature *signature = [self methodSignature];
22 | NSUInteger const arguments = signature.numberOfArguments;
23 |
24 | NSInvocation *result = [NSInvocation invocationWithMethodSignature:signature];
25 |
26 | void *heapBuffer = NULL;
27 | size_t heapBufferSize = 0;
28 |
29 | NSUInteger alignp = 0;
30 | for (NSUInteger i = 0; i < arguments; i++) {
31 | const char *type = [signature getArgumentTypeAtIndex:i];
32 | NSGetSizeAndAlignment(type, NULL, &alignp);
33 |
34 | if (alignp > heapBufferSize) {
35 | heapBuffer = heapBuffer
36 | ? reallocf(heapBuffer, alignp)
37 | : malloc(alignp);
38 | heapBufferSize = alignp;
39 | }
40 |
41 | [self getArgument:heapBuffer atIndex:i];
42 | [result setArgument:heapBuffer atIndex:i];
43 | }
44 |
45 | if (heapBuffer) {
46 | free(heapBuffer);
47 | }
48 |
49 | result.target = self.target;
50 |
51 | if (self.argumentsRetained) {
52 | [result retainArguments];
53 | }
54 |
55 | return result;
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/NSNotificationCenter+NNAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSNotificationCenter+NNAdditions.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/14/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSNotificationCenter+NNAdditions.h"
16 |
17 | #import "NNCleanupProxy.h"
18 |
19 |
20 | @implementation NSNotificationCenter (NNAdditions)
21 |
22 | - (void)addWeakObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
23 | {
24 | NSString *key = [NSString stringWithFormat:@"%p-%@-%@-%p", anObject, NSStringFromSelector(aSelector), aName, self];
25 | NNCleanupProxy *proxy = [NNCleanupProxy cleanupProxyForTarget:observer withKey:[key hash]];
26 |
27 | __weak NSNotificationCenter *weakCenter = self;
28 | __unsafe_unretained NNCleanupProxy *unsafeProxy = proxy;
29 |
30 | [proxy cacheMethodSignatureForSelector:aSelector];
31 | proxy.cleanupBlock = ^{
32 | NSNotificationCenter *center = weakCenter;
33 |
34 | [center removeObserver:unsafeProxy name:aName object:anObject];
35 | };
36 | [self addObserver:proxy selector:aSelector name:aName object:anObject];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/README.md:
--------------------------------------------------------------------------------
1 | NNKit API Extensions
2 | ====================
3 |
4 | For its own internal use, as well as your enjoyment, NNKit contains a set of extensions to existing system APIs.
5 |
6 | despatch
7 | --------
8 |
9 | [Despatch](http://numist.net/define/?despatch) contains helper functions to make dealing with GCD easier. At the moment this is one function:
10 |
11 | ### `despatch_sync_main_reentrant` ####
12 |
13 | `despatch_sync_main_reentrant` is a function for making synchronous dispatch onto the main queue simpler. The block argument is invoked directly if the sender is already executing on the main thread, and dispatched synchronously onto the main queue otherwise.
14 |
15 | ### `despatch_group_yield` ###
16 |
17 | The yield concept is borrowed from Python and other languages as a way for a path of execution to pause and allow other work scheduled for that thread to proceed. In this case it's most useful in unit tests to allow asynchronous work that takes place on the main thread to proceed.
18 |
19 | A very basic example from `NNDelegateProxyTests.m`:
20 |
21 | - (void)testGlobalAsync;
22 | {
23 | dispatch_group_enter(group);
24 | [[[MYClass alloc] initWithDelegate:self] globalAsync];
25 |
26 | NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:0.1];
27 | while (!despatch_group_yield(group) && [[NSDate date] compare:timeout] == NSOrderedAscending);
28 | XCTAssertFalse(dispatch_group_wait(group, DISPATCH_TIME_NOW), @"Delegate message was never received (timed out)!");
29 | }
30 |
31 | runtime
32 | -------
33 |
34 | Runtime provides functions that should exist in the Objective-C runtime, but don't.
35 |
36 | ### `nn_selector_belongsToProtocol` ###
37 |
38 | `nn_selector_belongsToProtocol` returns whether or not a selector belongs to a protocol, with additional arguments that inform its search pattern and return information about the selector found in the protocol. Providing default values for `instance` and `required` begin the search with those attributes, and their values on return indicate the attributes of the first match found.
39 |
40 | NSNotificationCenter
41 | --------------------
42 |
43 | The `NNAdditions` category to `NSNotificationCenter` adds a `addWeakObserver:selector:name:object:` method which references the observer weakly so no observer removal is required—it is automatically cleaned up when the observer is deallocated.
44 |
45 | NSInvocation
46 | ------------
47 |
48 | The `NNCopying` category to `NSInvocation` adds an `nn_copy` method which returns a copy of the receiver.
49 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/despatch.h:
--------------------------------------------------------------------------------
1 | //
2 | // despatch.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #ifndef NNKit_despatch_h
16 | #define NNKit_despatch_h
17 |
18 | /*!
19 | * @function despatch_sync_main_reentrant
20 | *
21 | * @abstract
22 | * Runs a block on the main queue, reentrantly if already on the main queue.
23 | *
24 | * @discussion
25 | * When on the main queue, executes the block synchronously before returning.
26 | * Otherwise, submits a block to the main queue and does not return until the block
27 | * has finished.
28 | *
29 | * @param block
30 | * The block to be invoked on the main queue.
31 | * The result of passing NULL
in this parameter is undefined.
32 | * Which is to say it will probably crash.
33 | */
34 | void despatch_sync_main_reentrant(dispatch_block_t block);
35 |
36 | /*!
37 | * @function despatch_group_yield
38 | *
39 | * @abstract
40 | * Yields control of the current runloop. Return value indicates if the dispatch
41 | * group is clear.
42 | *
43 | * @discussion
44 | * When waiting for asynchronous jobs in a dispatch group that may block on the
45 | * current thread, this function yields the runloop and then returns the group
46 | * state.
47 | *
48 | * @param group
49 | * The group for which the caller is waiting.
50 | *
51 | * @result
52 | * YES
if the group has no members, NO
otherwise.
53 | */
54 | BOOL despatch_group_yield(dispatch_group_t group);
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/despatch.m:
--------------------------------------------------------------------------------
1 | //
2 | // despatch.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #include "despatch.h"
16 |
17 |
18 | void despatch_sync_main_reentrant(dispatch_block_t block)
19 | {
20 | if ([[NSThread currentThread] isMainThread]) {
21 | block();
22 | } else {
23 | dispatch_sync(dispatch_get_main_queue(), block);
24 | }
25 | }
26 |
27 | BOOL despatch_group_yield(dispatch_group_t group)
28 | {
29 | // Let the runloop consume another event.
30 | NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
31 | assert(currentRunLoop); // I sure have gotten paranoid in my old age.
32 | (void)[currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
33 |
34 | // dispatch_group_wait docs say it returns zero or nonzero. Luckily, it needs to be inverted anyway, so a valid BOOL value gets enforced.
35 | return !dispatch_group_wait(group, DISPATCH_TIME_NOW);
36 | }
37 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/API Extension/runtime.c:
--------------------------------------------------------------------------------
1 | //
2 | // runtime.c
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #include "runtime.h"
16 |
17 | #include
18 | #include
19 |
20 |
21 | BOOL nn_selector_belongsToProtocol(SEL selector, Protocol *protocol, BOOL *requiredPtr, BOOL *instancePtr)
22 | {
23 | BOOL required = requiredPtr ? !!*requiredPtr : NO;
24 | BOOL instance = instancePtr ? !!*instancePtr : NO;
25 |
26 | for (int i = 0; i < (1 << 2); ++i) {
27 | BOOL checkRequired = required ^ (i & 1);
28 | BOOL checkInstance = instance ^ ((i & (1 << 1)) >> 1);
29 |
30 | struct objc_method_description hasMethod = protocol_getMethodDescription(protocol, selector, checkRequired, checkInstance);
31 | if (hasMethod.name || hasMethod.types) {
32 | if (requiredPtr) {
33 | *requiredPtr = checkRequired;
34 | }
35 | if (instancePtr) {
36 | *instancePtr = checkInstance;
37 | }
38 | return YES;
39 | }
40 | }
41 |
42 | return NO;
43 | }
44 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Actors/NNMultiDispatchManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNMultiDispatchManager.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/19/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface NNMultiDispatchManager : NSObject
19 |
20 | @property (nonatomic, assign, readwrite, getter = isEnabled, setter = setIsEnabled:) BOOL enabled;
21 | @property (nonatomic, readonly, assign) Protocol *protocol;
22 |
23 | - (instancetype)initWithProtocol:(Protocol *)protocol;
24 |
25 | - (void)addObserver:(id)observer;
26 | - (BOOL)hasObserver:(id)observer;
27 | - (void)removeObserver:(id)observer;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Actors/NNPollingObject+Protected.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNPollingObject+Protected.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 07/12/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface NNPollingObject (Protected)
19 |
20 | - (void)postNotification:(NSDictionary *)userInfo;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Actors/NNPollingObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNPollingObject.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 07/10/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface NNPollingObject : NSObject
19 |
20 | + (NSString *)notificationName;
21 |
22 | // I think this is the first time where I've wanted the default (atomic, assign, readwrite) flags for a property!
23 | // Too bad I have all warnings turned on:
24 | @property (atomic, assign, readwrite) NSTimeInterval interval;
25 |
26 | - (instancetype)initWithQueue:(dispatch_queue_t)queue;
27 | - (void)main;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Actors/NNSelfInvalidatingObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNSelfInvalidatingObject.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | /*!
19 | * @class NNSelfInvalidatingObject
20 | *
21 | * @discussion
22 | * For use when an object has to do cleanup work asynchronously, or outside of
23 | * dealloc
. Simply implement the invalidate
method and
24 | * call [super invalidate]
when the actor has finished cleaning up.
25 | */
26 | @interface NNSelfInvalidatingObject : NSObject
27 |
28 | /*!
29 | * @method invalidate
30 | *
31 | * @discussion
32 | * Called only once, either explicitly (by an interested object) or when the
33 | * object has been fully-released.
34 | *
35 | * When invalidation is complete, [super invalidate] must be called to complete
36 | * deallocation of the object.
37 | */
38 | - (void)invalidate;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/NNWeakSet.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNWeakSet.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 06/04/16.
6 | // Copyright © 2016 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | /*!
18 | * @class NNMutableWeakSet
19 | *
20 | * @abstract
21 | * Provides a set-type collection that references its members weakly.
22 | *
23 | * @discussion
24 | * NNWeakSet implements the same API as NSMutableSet, but holds weak
25 | * references to its members.
26 | *
27 | * No compaction is required, members are automatically removed when they are
28 | * deallocated.
29 | *
30 | * This collection type may be slower than NSHashTable, but it also has
31 | * fewer bugs.
32 | */
33 | @interface NNWeakSet : NSMutableSet
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/NSCollections+NNComprehensions.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+NNComprehensions.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 02/25/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | typedef BOOL (^nn_filter_block_t)(id item);
18 | typedef id (^nn_map_block_t)(id item);
19 | typedef id (^nn_reduce_block_t)(id accumulator, id item);
20 |
21 | @protocol NNCollection
22 | - (instancetype)nn_filter:(nn_filter_block_t)block;
23 | - (instancetype)nn_map:(nn_map_block_t)block;
24 | - (id)nn_reduce:(nn_reduce_block_t)block;
25 | @end
26 |
27 | @interface NSArray (NNComprehensions)
28 | @end
29 |
30 | @interface NSSet (NNComprehensions)
31 | @end
32 |
33 | @interface NSOrderedSet (NNComprehensions)
34 | @end
35 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/README.md:
--------------------------------------------------------------------------------
1 | # NNKit Collections #
2 |
3 | The code in this component gives collections superpowers.
4 |
5 | ## Category: NNComprehensions ##
6 |
7 | The `NNComprehensions` category on `NSArray`, `NSSet`, and `NSOrderedSet` implements the following comprehensions:
8 |
9 | ### nn_filter: ###
10 | Returns a new collection of the same (immutable) type that contains a subset of the items in the original array, as chosen by the method's argument, a block that takes an `id` and returns a `BOOL`.
11 |
12 | #### Example: ####
13 | ``` objective-c
14 | // Returns @[@3, @6, @9]
15 | [@[@1, @2, @3, @4, @5, @6, @7, @8, @9, @10] nn_filter:^(id item){ return (BOOL)!([item integerValue] % 3); }];
16 | ```
17 |
18 | ### nn_map: ###
19 | Returns a new collection of the same (immutable) type that contains new values based on the result of the block parameter, which takes an id and returns an id.
20 |
21 | Returning `nil` from the block is not supported. A separate filter step should be used first to remove unwanted items from the collection.
22 |
23 | #### Example: ####
24 | ``` objective-c
25 | // Returns @[@2, @4, @6, @8, @10, @12, @14, @16, @18, @20]
26 | [@[@1, @2, @3, @4, @5, @6, @7, @8, @9, @10] nn_map:^(id item){ return @([item integerValue] * 2); }];
27 | ```
28 |
29 | ### nn_reduce: ###
30 | Returns a reduction of the collection as defined by the block parameter, which takes an accumulator value (an `id` which starts as nil) and an item and returns the new value of the accumulator.
31 |
32 | #### Example: ####
33 | ``` objective-c
34 | // Returns @55
35 | [@[@1, @2, @3, @4, @5, @6, @7, @8, @9, @10] nn_reduce:^(id acc, id item){ return @([acc integerValue] + [item integerValue]); }];
36 | ```
37 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/_NNWeakArrayTombstone.h:
--------------------------------------------------------------------------------
1 | //
2 | // _NNWeakArrayTombstone.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/19/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface _NNWeakArrayTombstone : NSObject
19 |
20 | + (_NNWeakArrayTombstone *)tombstoneWithTarget:(id)target;
21 |
22 | @property (nonatomic, readonly, weak) id target;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/_NNWeakArrayTombstone.m:
--------------------------------------------------------------------------------
1 | //
2 | // _NNWeakArrayTombstone.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/19/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "_NNWeakArrayTombstone.h"
16 |
17 |
18 | @interface _NNWeakArrayTombstone ()
19 |
20 | @property (nonatomic, readonly, assign) NSUInteger hash;
21 |
22 | @end
23 |
24 |
25 | @implementation _NNWeakArrayTombstone
26 |
27 | + (_NNWeakArrayTombstone *)tombstoneWithTarget:(id)target;
28 | {
29 | _NNWeakArrayTombstone *tombstone = [_NNWeakArrayTombstone new];
30 | tombstone->_target = target;
31 | return tombstone;
32 | }
33 |
34 | @synthesize hash = _hash;
35 | - (NSUInteger)hash;
36 | {
37 | if (!self->_hash) {
38 | @synchronized(self) {
39 | if (!self->_hash) {
40 | id target = self.target;
41 | if (target) {
42 | self->_hash = [target hash];
43 | } else {
44 | self->_hash = (uintptr_t)self;
45 | }
46 | }
47 | }
48 | }
49 |
50 | return self->_hash;
51 | }
52 |
53 | - (BOOL)isEqual:(id)object;
54 | {
55 | id target = self.target;
56 | return [target isEqual:object] ? YES : (uintptr_t)object == (uintptr_t)self;
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/_NNWeakSetEnumerator.h:
--------------------------------------------------------------------------------
1 | //
2 | // _NNWeakSetEnumerator.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/19/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class NNWeakSet;
19 |
20 |
21 | @interface _NNWeakSetEnumerator : NSEnumerator
22 |
23 | - (instancetype)initWithWeakSet:(NNWeakSet *)set;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Collections/_NNWeakSetEnumerator.m:
--------------------------------------------------------------------------------
1 | //
2 | // _NNWeakSetEnumerator.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/19/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "_NNWeakSetEnumerator.h"
16 |
17 | #import "_NNWeakArrayTombstone.h"
18 | #import "NNWeakSet.h"
19 |
20 |
21 | @interface NNWeakSet (Private)
22 |
23 | @property (nonatomic, readonly, strong) NSSet *backingStore;
24 |
25 | @end
26 |
27 |
28 | @interface _NNWeakSetEnumerator ()
29 |
30 | @property (nonatomic, readonly, strong) NSEnumerator *tombstoneEnumerator;
31 |
32 | @end
33 |
34 |
35 | @implementation _NNWeakSetEnumerator
36 |
37 | - (instancetype)initWithWeakSet:(NNWeakSet *)set;
38 | {
39 | if (!(self = [super init])) { return nil; }
40 |
41 | self->_tombstoneEnumerator = [set.backingStore.copy objectEnumerator];
42 |
43 | return self;
44 | }
45 |
46 | - (NSArray *)allObjects;
47 | {
48 | NSMutableArray<_NNWeakArrayTombstone *> *result = [NSMutableArray new];
49 |
50 | for (_NNWeakArrayTombstone *tombstone in self.tombstoneEnumerator.allObjects) {
51 | id obj = tombstone.target;
52 | if (obj) {
53 | [result addObject:obj];
54 | }
55 | }
56 |
57 | return result;
58 | }
59 |
60 | - (id)nextObject;
61 | {
62 | id obj;
63 | _NNWeakArrayTombstone *tombstone;
64 |
65 | do {
66 | tombstone = self.tombstoneEnumerator.nextObject;
67 | obj = tombstone.target;
68 | } while (!obj && tombstone);
69 |
70 | return obj;
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Concurrency/NNDelegateProxy.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNDelegateProxy.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | /*!
19 | * @class NNDelegateProxy
20 | *
21 | * @discussion
22 | * A proxy object ensuring that messages to the delegate are dispatched on the
23 | * main thread.
24 | *
25 | * Messages declared as oneway void are dispatched asynchronously, messages that
26 | * are optional are dispatched against nil if the delegate does not implement them.
27 | * Messages that are optional and non-void are a bad idea and you shouldn't use them.
28 | */
29 | @interface NNDelegateProxy : NSProxy
30 |
31 | /*!
32 | * @method proxyWithDelegate:protocol:
33 | *
34 | * @discussion
35 | * Creates a new proxy for delegate conforming to
36 | * protocol.
37 | *
38 | * @param delegate
39 | * The object to receive delegate messages.
40 | *
41 | * @param protocol
42 | * The protocol to which delegate conforms. Can be NULL
,
43 | * but shouldn't be.
44 | *
45 | * @result
46 | * Proxy to stand in for delegate for messages conforming to
47 | * protocol.
48 | */
49 | + (id)proxyWithDelegate:(id)delegate protocol:(Protocol *)protocol;
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Concurrency/README.md:
--------------------------------------------------------------------------------
1 | NNKit Concurrency
2 | =================
3 |
4 | NNKit provides tools to help make concurrency less of a headache, following the model of islands of serialization in a sea of concurrency. Since not all code can be expected to follow this model, NNKit also assumes that the only safe manner of passing messages between modules is on the main thread, and recievers are expected to get off the main thread as needed.
5 |
6 | NNDelegateProxy
7 | ---------------
8 |
9 | The `NNDelegateProxy` class provides a mechanism to ensure that all messages sent to a delegate are dispatched on the main thread.
10 |
11 | ### Example ###
12 |
13 | // You should already have a protocol for your use of the delegate pattern:
14 | @protocol MYClassDelegate
15 | - (void)objectCalledDelegateMethod:(id)obj;
16 | @end
17 |
18 |
19 | @interface MYClass : NSObject
20 |
21 | // And should already have a weak property for your delegate in your class declaration:
22 | @property (nonatomic, weak) id delegate;
23 |
24 | // Add a strong reference to a new property, the delegate proxy:
25 | @property (strong) id delegateProxy;
26 |
27 | @end
28 |
29 | @implementation MYClass
30 |
31 | - (instancetype)init;
32 | {
33 | if (!(self = [super init])) { return nil; }
34 |
35 | // Initialize the delegate proxy, feel free to set the delegate later if you don't have one handy.
36 | _delegateProxy = [NNDelegateProxy proxyWithDelegate:nil protocol:@protocol(MYClassDelegate)];
37 |
38 | // …
39 |
40 | return self;
41 | }
42 |
43 | // If you have a writable delegate property, you'll need a custom delegate setter to ensure that the proxy gets updated:
44 | - (void)setDelegate:(id)delegate;
45 | {
46 | self->_delegate = delegate;
47 |
48 | ((NNDelegateProxy *)self.delegateProxy).delegate = delegate;
49 | // NOTE: A cast is necessary here because the delegateProxy property is typed id to retain as much static checking as possible elsewhere in your code, which fails here because the compiler doesn't realise that it's still an NNDelegateProxy under the hood.
50 | }
51 |
52 | - (void)method;
53 | {
54 | // Who cares how we got to where we are, or where that even is; when it's time to dispatch a delegate message just send it to the proxy:
55 | [self.delegateProxy objectCalledDelegateMethod:self];
56 | }
57 |
58 | @end
59 |
60 | This proxy class was inspired by [Andy Matuschak](https://github.com/andymatuschak).
61 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Hacks/NNStrongifiedProperties.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNStrongifiedProperties.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | /*!
18 | * @class NNStrongifiedProperties
19 | *
20 | * @discussion
21 | * Used with isa-swizzling to provide strong getters for weak properties in the
22 | * form of methods named strongProperty
, where
23 | * Property
is the unambiguous capitalized name of a weak
24 | * property on the object.
25 | */
26 | @interface NNStrongifiedProperties : NSObject
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Hacks/README.md:
--------------------------------------------------------------------------------
1 | NNKit Hacks
2 | ===========
3 |
4 | This portion of NNKit contains things that, while well-tested and reliable, shouldn't pass a sane person's test for acceptable complexity per unit utility.
5 |
6 | Automatically Freed C Buffers
7 | -----------------------------
8 |
9 | Have a complicated function with a lot of logic and early returns? Avoid the possibility of forgetting to free your buffers with `nn_autofree`!
10 |
11 | @autoreleasepool {
12 | int *foo = nn_autofree(malloc(size));
13 | }
14 |
15 | Don't forget, you're still in charge of NULLing your pointers, so it's easiest if you create your own autorelease pool, which will also create an extra scope for the buffer's pointer which it can't escape.
16 |
17 | Strongified Property Access
18 | ---------------------------
19 |
20 | Weak properties can be accessed with autoreleasing getters by either inheriting from or isa-swizzling `NNStrongifiedProperties`.
21 |
22 | @interface WeakDemo : NNStrongifiedProperties
23 | @property (weak) id foo;
24 | @end
25 |
26 | @interface WeakDemo (StrongAccessors)
27 | - (id)strongFoo;
28 | @end
29 |
30 | @implementation WeakDemo
31 | @end
32 |
33 | int main() {
34 | // Whenever you need an autoreleased reference to foo:
35 | [[WeakDemo new] strongFoo]
36 | }
37 |
38 | If you already inherit from a more useful class, this behaviour can be "learned" by an existing object by using isa swizzling:
39 |
40 | @interface WeakDemo : NSObject
41 | @property (weak) id foo;
42 | @end
43 |
44 | @interface WeakDemo (StrongAccessors)
45 | - (id)strongFoo;
46 | @end
47 |
48 | @implementation WeakDemo
49 | @end
50 |
51 | int main() {
52 | id obj = [WeakDemo new];
53 | nn_object_swizzleIsa(obj, [NNStrongifiedProperties class]);
54 |
55 | // Whenever you need an autoreleased reference to foo:
56 | [obj strongFoo]
57 | }
58 |
59 | This hack was concieved after enabling the `-Wreceiver-is-weak` warning in clang and learning about the race condition it polices.
60 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Hacks/memoize.h:
--------------------------------------------------------------------------------
1 | //
2 | // memoize.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 06/23/15.
6 | // Copyright © 2015 Scott Perry. All rights reserved.
7 | //
8 |
9 | #define NNMemoize(block) _NNMemoize(self, _cmd, block)
10 |
11 | id _NNMemoize(id self, SEL _cmd, id (^block)());
12 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Hacks/memoize.m:
--------------------------------------------------------------------------------
1 | //
2 | // memoize.c
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 06/23/15.
6 | // Copyright © 2015 Scott Perry. All rights reserved.
7 | //
8 |
9 | #import "memoize.h"
10 |
11 | #import
12 |
13 |
14 | id _NNMemoize(id self, SEL _cmd, id (^block)()) {
15 | id result;
16 | void *key = (void *)((uintptr_t)(__bridge void *)self ^ (uintptr_t)(void *)_cmd ^ (uintptr_t)&_NNMemoize);
17 |
18 | @synchronized(self) {
19 | result = objc_getAssociatedObject(self, key);
20 | if (!result) {
21 | result = block();
22 | objc_setAssociatedObject(self, key, result, OBJC_ASSOCIATION_COPY_NONATOMIC);
23 | }
24 | }
25 |
26 | return result;
27 | }
28 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Hacks/nn_autofree.h:
--------------------------------------------------------------------------------
1 | //
2 | // nn_autofree.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/09/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | /*!
18 | * @function nn_autofree
19 | *
20 | * @abstract
21 | * Adds the buffer to the current autorelease pool.
22 | *
23 | * @discussion
24 | * This function ties the buffer's lifetime to that of an object added to the
25 | * current autorelease pool, causing it to be freed when the pool is drained.
26 | *
27 | * @param ptr
28 | * The buffer to add to the current autorelease pool.
29 | */
30 | void *nn_autofree(void *ptr);
31 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Hacks/nn_autofree.m:
--------------------------------------------------------------------------------
1 | //
2 | // nn_autofree.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/09/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 | // Requires -fno-objc-arc
15 | //
16 |
17 | #import "nn_autofree.h"
18 |
19 | void *nn_autofree(void *ptr)
20 | {
21 | if (ptr) {
22 | [NSData dataWithBytesNoCopy:ptr length:1 freeWhenDone:YES];
23 | }
24 | return ptr;
25 | }
26 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/NNKit Mac-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #endif
10 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/NNKit iOS-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #endif
10 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/NNKit-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | net.numist.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | FMWK
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | NSHumanReadableCopyright
26 | Copyright © 2013 Scott Perry. All rights reserved.
27 | NSPrincipalClass
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/NNKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNKit.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | #import
18 | #import
19 | #import
20 | #import
21 | #import
22 |
23 | #import
24 | #import
25 | #import
26 | #import
27 | #import
28 | #import
29 | #import
30 | #import
31 | #import
32 | #import
33 |
34 | #import
35 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/NNKit.m:
--------------------------------------------------------------------------------
1 | //
2 | // NNKit.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 09/05/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NNKit.h"
16 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Services/NNService+Protected.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNService+Protected.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 10/17/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class NNMultiDispatchManager;
19 |
20 |
21 | @interface NNService (Protected)
22 |
23 | @property (atomic, readonly, strong) NNMultiDispatchManager *subscriberDispatcher;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Services/NNService.m:
--------------------------------------------------------------------------------
1 | //
2 | // NNService.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 10/17/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NNService+Protected.h"
16 |
17 | #import "NNServiceManager.h"
18 | #import "NNMultiDispatchManager.h"
19 |
20 |
21 | @interface NNService ()
22 |
23 | @property (atomic, readonly, strong) NNMultiDispatchManager *subscriberDispatcher;
24 |
25 | @end
26 |
27 |
28 | @implementation NNService
29 |
30 | + (instancetype)sharedService;
31 | {
32 | static NSMutableDictionary *instances;
33 |
34 | static dispatch_once_t onceToken;
35 | dispatch_once(&onceToken, ^{
36 | instances = [NSMutableDictionary new];
37 | });
38 |
39 | NNService *result;
40 |
41 | @synchronized(instances) {
42 | result = [instances objectForKey:self];
43 | if (!result) {
44 | result = [self new];
45 | [instances setObject:result forKey:self];
46 | }
47 | }
48 |
49 | return result;
50 | }
51 |
52 | + (NNServiceType)serviceType;
53 | {
54 | return NNServiceTypePersistent;
55 | }
56 |
57 | + (NSSet *)dependencies;
58 | {
59 | return [NSSet set];
60 | }
61 |
62 | + (Protocol *)subscriberProtocol;
63 | {
64 | return @protocol(NSObject);
65 | }
66 |
67 | - (id)init;
68 | {
69 | if (!(self = [super init])) { return nil; }
70 |
71 | self->_subscriberDispatcher = [[NNMultiDispatchManager alloc] initWithProtocol:self.class.subscriberProtocol];
72 |
73 | return self;
74 | }
75 |
76 | - (void)startService;
77 | {
78 | NSAssert([[NSThread currentThread] isMainThread], @"Service must be started on the main thread");
79 | }
80 |
81 | - (void)stopService;
82 | {
83 | NSAssert([[NSThread currentThread] isMainThread], @"Service must be stopped on the main thread");
84 | }
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Services/README.md:
--------------------------------------------------------------------------------
1 | NNKit Services
2 | ==============
3 |
4 | NNKit provides a framework for services running in your application, including dependency management, subscriber and observer dispatch, automatic starting and stopping of services based on subscriptions, and an easy mechanism to register all the services in your application in your app delegate, keeping your code small and readable.
5 |
6 | What makes a service
7 | --------------------
8 |
9 | Services are classes that inherit from `NNService` and respond to `serviceType` with a type other than `NNServiceTypeNone`. The other two types are:
10 |
11 | * `NNServiceTypePersistent`: the service will run as long as its dependencies (if any) are running.
12 | * `NNServiceTypeOnDemand`: the service will run as long as its dependencies (if any) are running and at least one object has subscribed to the service using the service manager's `addSubscriber:forService:` method.
13 |
14 | Dependency management
15 | ---------------------
16 |
17 | Service dependencies are defined by the `dependencies` method, which returns an NSSet of class objects. Dependencies that are not already known to the service manager will be added automatically if possible.
18 |
19 | Subscriber (and observer) message dispatch
20 | ------------------------------------------
21 |
22 | Services whose instances dispatch messages to their subscribers must respond to `subscriberProtocol` with the appropriate protocol. Subscribers must conform to this protocol and will be checked at runtime. Sending a message to subscribers can be accomplished with code resembling the following:
23 |
24 | ``` objective-c
25 | - (void)sendMessage;
26 | {
27 | [(id)self.subscriberDispatcher serviceWillDoThing:self];
28 | }
29 | ```
30 |
31 | Convenience hacks
32 | -----------------
33 |
34 | Automatically adding all services known to the runtime is accomplished by calling `registerAllPossibleServices` on a service manager, preferably the `sharedManager`.
35 |
36 | Would you like to know more?
37 | ----------------------------
38 |
39 | For a deeper dive into services, check out the [unit tests](https://github.com/numist/NNKit/blob/master/NNKitTests/NNServiceTests.m).
40 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Swizzling/NNISASwizzledObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNISASwizzledObject.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 02/07/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @protocol NNISASwizzledObject @end
19 |
20 |
21 | @interface NNISASwizzledObject : NSObject
22 |
23 | + (void)prepareObjectForSwizzling:(NSObject *)anObject;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Swizzling/README.md:
--------------------------------------------------------------------------------
1 | NNKit Swizzling
2 | ===============
3 |
4 | NNKit provides robust, general-purpose swizzling utilities.
5 |
6 | If you think this is a good idea, you should probably stop and make sure that your needs are not a symptom of more severe architectural problems.
7 |
8 | Isa Swizzling
9 | -------------
10 |
11 | Robust isa swizzling is provided using the `nn_object_swizzleIsa` function. The following conditions must be met:
12 |
13 | * The object is an instance of the swizzling class's superclass, or a subclass of the swizzling class's superclass.
14 | * The swizzling class does not add any ivars or non-dynamic properties.
15 |
16 | An object has been swizzled by a class if it responds YES to `isKindOfClass:` with the swizzling class as an argument. Protocols can also be used, and queried using `conformsToProtocol:`, as usual.
17 |
18 | To avoid any confusion, your swizzling class should not implement an allocator or initializer. They will never be called for swizzled objects.
19 |
20 | ### Usage ###
21 |
22 | First, you'll need to define your swizzling class. For example:
23 |
24 | @interface MYClass : NSObject
25 | @property (nonatomic, readonly) NSUInteger random;
26 | - (void)duck;
27 | @end
28 |
29 | @implementation MYClass
30 | - (NSUInteger)random { return 7; }
31 | - (void)duck { NSLog(@"quack!"); }
32 | - (void)dog { NSLog(@"woof!"); }
33 | @end
34 |
35 | To swizzle your object and use its newfound functionality, just call `nn_object_swizzleIsa`:
36 |
37 | #import
38 |
39 | @implementation MYCode
40 | - (void)main {
41 | NSObject *bar = [[NSObject alloc] init];
42 | nn_object_swizzleIsa(bar, [MYClass class]);
43 | if ([bar isKindOfClass:[MYClass class]]) {
44 | [(MYClass *)bar duck];
45 | }
46 | if ([bar conformsToProtocol:@protocol(NSDog)]) {
47 | [(id)bar dog];
48 | }
49 | }
50 | @end
51 |
52 | See the tests for more explicit examples of what is supposed to work and what is supposed to be an error.
53 |
54 | Credits
55 | =======
56 |
57 | If not for [Rob Rix](https://github.com/robrix/), the Swizzling component of NNKit would not exist. Which probably would have been a good thing.
58 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Swizzling/nn_isaSwizzling.h:
--------------------------------------------------------------------------------
1 | //
2 | // nn_isaSwizzling.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 02/07/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | /*!
19 | * @function nn_object_swizzleIsa
20 | *
21 | * @abstract
22 | * Swizzles the class of obj to a dynamic subclass including the
23 | * qualities of swizzlingClass.
24 | *
25 | * @discussion
26 | * This function implements generic isa swizzling assuming the following conditions are met:
27 | * • A protocol with the same name as swizzlingClass exists and is
28 | * implemented by swizzlingClass.
29 | * • obj is an instance of the swizzlingClass's
30 | * superclass, or a subclass of swizzlingClass's superclass.
31 | * • swizzlingClass does not add any ivars or non-dynamic properties.
32 | *
33 | * An object has been swizzled by a class if it conforms to that class's
34 | * complementing protocol, allowing you to cast the object (after checking!) to
35 | * a type that explicitly implements the protocol.
36 | *
37 | * For more details about use, see the tests in nn_isaSwizzlingTests.m.
38 | *
39 | * @param obj
40 | * The object to be swizzled.
41 | *
42 | * @param swizzlingClass
43 | * The class to apply to obj.
44 | */
45 | BOOL nn_object_swizzleIsa(id obj, Class swizzlingClass) __attribute__((nonnull(1, 2)));
46 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/Swizzling/nn_isaSwizzling_Private.h:
--------------------------------------------------------------------------------
1 | //
2 | // nn_isaSwizzling_Private.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 02/08/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | BOOL nn_alreadySwizzledObjectWithSwizzlingClass(id anObject, Class aClass) __attribute__((nonnull(1, 2)));
18 |
19 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKit/macros.h:
--------------------------------------------------------------------------------
1 | //
2 | // macros.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 02/25/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #pragma once
16 |
17 | // Compile-time key path additions
18 | #define NNKeyPath(object, keyPath) ({ if (NO) { (void)((object).keyPath); } @#keyPath; })
19 | #define NNSelfKeyPath(keyPath) NNKeyPath(self, keyPath)
20 | #define NNTypedKeyPath(ObjectClass, keyPath) NNKeyPath(((ObjectClass *)nil), keyPath)
21 | #define NNProtocolKeyPath(Protocol, keyPath) NNKeyPath(((id )nil), keyPath)
22 |
23 | // Compile-time selector additions
24 | #define NNSelector(object, selectorName) ({ if (NO) { (void)[(object) selectorName]; } @selector(selectorName); })
25 | #define NNSelfSelector(selectorName) NNSelector(self, selectorName)
26 | #define NNTypedSelector(ObjectClass, selectorName) NNSelector(((ObjectClass *)nil), selectorName)
27 | #define NNProtocolSelector(Protocol, selectorName) NNSelector(((id )nil), selectorName)
28 |
29 | #define NNSelector1(object, selectorName) ({ if (NO) { (void)[(object) selectorName nil]; } @selector(selectorName); })
30 | #define NNSelfSelector1(selectorName) NNSelector1(self, selectorName)
31 | #define NNTypedSelector1(ObjectClass, selectorName) NNSelector1(((ObjectClass *)nil), selectorName)
32 | #define NNProtocolSelector1(Protocol, selectorName) NNSelector1(((id )nil), selectorName)
33 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKitTests/NNKit Mac Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | net.numist.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKitTests/NNKit iOS Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | net.numist.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKitTests/NNTestCase.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNTestCase.h
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/20/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | @interface NNTestCase : XCTestCase
18 |
19 | - (BOOL)testForMemoryLeaksWithBlock:(void (^)())block iterations:(size_t)iterations;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKitTests/NNTestCase.m:
--------------------------------------------------------------------------------
1 | //
2 | // NNTestCase.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/20/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NNTestCase.h"
16 |
17 | #import
18 |
19 |
20 | static size_t report_memory(void) {
21 | struct task_basic_info info;
22 | mach_msg_type_number_t size = sizeof(info);
23 | kern_return_t kerr = task_info(mach_task_self(),
24 | TASK_BASIC_INFO,
25 | (task_info_t)&info,
26 | &size);
27 | if( kerr != KERN_SUCCESS ) {
28 | @throw [NSException exceptionWithName:@"wtf" reason:[NSString stringWithFormat:@"Error with task_info(): %s", mach_error_string(kerr)] userInfo:nil];
29 | }
30 | return info.resident_size;
31 | }
32 |
33 |
34 | @interface NNTestCase ()
35 |
36 | @end
37 |
38 |
39 | @implementation NNTestCase
40 |
41 | - (BOOL)testForMemoryLeaksWithBlock:(void (^)())block iterations:(size_t)iterations;
42 | {
43 | XCTAssertTrue(iterations > 4096, @"Memory leak tests are not accurate with iteration counts less than 4096!");
44 |
45 | // Three bytes per iteration is allowed to leak because that's basically impossible.
46 | size_t bytes_expected = iterations * 3;
47 | size_t memory_usage_at_start = report_memory();
48 |
49 | while (--iterations != 0) {
50 | @autoreleasepool {
51 | block();
52 | }
53 | }
54 |
55 | size_t bytes_actual = report_memory() - memory_usage_at_start;
56 | BOOL memory_usage_is_good = bytes_actual < bytes_expected;
57 | NSLog(@"Memory usage increased by %zu bytes by end of test", bytes_actual);
58 | XCTAssertTrue(memory_usage_is_good, @"Memory usage increased by %zu bytes by end of test (expected < %zu)", bytes_actual, bytes_expected);
59 |
60 | return memory_usage_is_good;
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKitTests/NNWeakObserverTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // NNWeakObserverTests.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/14/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | #import
18 |
19 |
20 | static NSString *notificationName = @"somenotification";
21 | unsigned receivedNotifications;
22 |
23 |
24 | @interface _NNWeakObserverTestObserver : NSObject
25 | @end
26 | @implementation _NNWeakObserverTestObserver
27 | - (void)notify:(NSNotification *)note;
28 | {
29 | receivedNotifications++;
30 | }
31 | - (void)dealloc;
32 | {
33 | NSLog(@"Destroyed object!");
34 | }
35 | @end
36 |
37 |
38 | @interface NNWeakObserverTests : XCTestCase
39 |
40 | @end
41 |
42 |
43 | @implementation NNWeakObserverTests
44 |
45 | - (void)setUp
46 | {
47 | [super setUp];
48 |
49 | receivedNotifications = 0;
50 | }
51 |
52 | - (void)testWeakObservers
53 | {
54 | @autoreleasepool {
55 | __attribute__((objc_precise_lifetime)) _NNWeakObserverTestObserver *observer = [_NNWeakObserverTestObserver new];
56 | [[NSNotificationCenter defaultCenter] addWeakObserver:observer selector:@selector(notify:) name:notificationName object:nil];
57 | [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self];
58 | XCTAssertEqual(receivedNotifications, (unsigned)1, @"");
59 | }
60 | XCTAssertNoThrow([[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self], @"");
61 | XCTAssertEqual(receivedNotifications, (unsigned)1, @"");
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/NNKitTests/nn_autofreeTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // nn_autofreeTests.m
3 | // NNKit
4 | //
5 | // Created by Scott Perry on 11/20/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NNTestCase.h"
16 |
17 | #import
18 |
19 |
20 | @interface nn_autofreeTests : NNTestCase
21 |
22 | @end
23 |
24 |
25 | @implementation nn_autofreeTests
26 |
27 | - (void)setUp
28 | {
29 | [super setUp];
30 | // Put setup code here. This method is called before the invocation of each test method in the class.
31 | }
32 |
33 | - (void)tearDown
34 | {
35 | // Put teardown code here. This method is called after the invocation of each test method in the class.
36 | [super tearDown];
37 | }
38 |
39 | - (void)testExample
40 | {
41 | [self testForMemoryLeaksWithBlock:^{
42 | nn_autofree(malloc(2));
43 | } iterations:1e5];
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Frameworks/NNKit/README.md:
--------------------------------------------------------------------------------
1 | NNKit
2 | =====
3 |
4 | This library represents a collection of well-tested, robust, occasionally idiotic, but always well-meaning widgets for the Objective-C developer.
5 |
6 | At the moment it is a poorly-documented collection of code samples for my [NSMeetup talk](http://www.meetup.com/nsmeetup/events/136648202/) as well as a shared repository of solutions to common problems for [Switch](https://github.com/numist/Switch) and tmbo, the latter being a sort of promise to keep on adding, testing, and documenting the framework.
7 |
8 | The framework is broken up by purpose, the most entertaining of which are likely [Swizzling](https://github.com/numist/NNKit/tree/master/NNKit/Swizzling) and [Hacks](https://github.com/numist/NNKit/tree/master/NNKit/Hacks).
9 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 | platform :osx, '10.10'
3 |
4 | target :Switch do
5 | pod 'MASPreferences'
6 | pod 'Sparkle'
7 | target :SwitchTests do
8 | pod 'OCMock'
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - MASPreferences (1.1.4)
3 | - OCMock (3.1.2)
4 | - Sparkle (1.14.0)
5 |
6 | DEPENDENCIES:
7 | - MASPreferences
8 | - OCMock
9 | - Sparkle
10 |
11 | SPEC REPOS:
12 | https://github.com/CocoaPods/Specs.git:
13 | - MASPreferences
14 | - OCMock
15 | - Sparkle
16 |
17 | SPEC CHECKSUMS:
18 | MASPreferences: 7bdcfe891d7840453cf48f95fa866c3e152ace7a
19 | OCMock: a10ea9f0a6e921651f96f78b6faee95ebc813b92
20 | Sparkle: ccd95233b12a3e3d4eeb55ff01dd4c8bb8188b07
21 |
22 | PODFILE CHECKSUM: f98179f647f587219a5246f66f8624262c7dd81d
23 |
24 | COCOAPODS: 1.9.3
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Switch, Window-Based Context Switching
2 | ======================================
3 |
4 | Switch is a window-based (as opposed to application-based) context switcher. By default it is bound to using `⌥⇥` and `⌥⇧⇥` to cycle through the visible windows on the current space. When the interface is active, `⌥W` can be used to close windows and `⌥,` used to show a preferences window. The main interface looks like this:
5 |
6 | 
7 |
8 | This project is functional, but not finished. That said, I've been using it every day.
9 |
10 | [Patches](https://github.com/numist/Switch/pull/new) and [issues](https://github.com/numist/Switch/issues) are welcome. If a window is being improperly shown or omitted from the interface, please include a [snapshot](https://github.com/numist/Switch/wiki/About-Snapshots).
11 |
12 | Getting Started
13 | ---------------
14 |
15 | Download the [latest release](https://github.com/numist/Switch/releases), put the application bundle in your `/Applications` or `~/Applications` directory, and run it! It will check for updates automatically so you can stay up to date as the project develops.
16 |
17 | Switch requires Mac OS X version 10.14 or newer and is still in development. For a list of known issues, check out the [bug tag](https://github.com/numist/Switch/issues?labels=bug&state=open) for general badness and the [quirk tag](https://github.com/numist/Switch/issues?labels=quirk&state=open) for windows being improperly shown or omitted from the interface.
18 |
19 | Contributing
20 | ------------
21 |
22 | [](https://travis-ci.org/numist/Switch)
23 |
24 | To check out the project, its submodules, and open in Xcode:
25 |
26 | git clone git://github.com/numist/Switch.git
27 | cd Switch/
28 | rake deps
29 | open Switch.xcworkspace
30 |
31 | At this point, `⌘R` should have you up and running!
32 |
33 | The release process uses the project `Rakefile`; if you have a Developer ID certificate installed, you should be able to run `rake release` without any issues. Without a Developer ID, the `analyze`, `test`, and `app` targets (and their dependencies) should succeed.
34 |
35 | Thanks!
36 | -------
37 |
38 | Switch relies on a number of external frameworks, either as [submodules](https://github.com/numist/Switch/tree/develop/Frameworks) or [pods](https://github.com/numist/Switch/tree/develop/Podfile). Thanks to the people responsible for them, you've saved me time and tears.
39 |
--------------------------------------------------------------------------------
/Scripts/console.rb:
--------------------------------------------------------------------------------
1 |
2 | $stdout.sync = true
3 |
4 | class Console
5 | @@line_length = 0
6 |
7 | def self.append(text)
8 | # TODO blow up if "\r" is found or something
9 | text_without_colors = text.gsub(/\e\[[\d]+(;[\d]+)*m/, "")
10 | last_newline_index = text_without_colors.rindex "\n"
11 | if last_newline_index.nil?
12 | @@line_length += text.length
13 | else
14 | @@line_length = text.length - (last_newline_index + 1)
15 | end
16 |
17 | $stdout.print text
18 | end
19 |
20 | def self.clear_line
21 | # clear the old line
22 | if @@line_length > 0
23 | spaces = ""
24 | @@line_length.times { spaces = "#{spaces} " }
25 | $stdout.print "\r#{spaces}\r"
26 | @@line_length = 0
27 | end
28 | end
29 |
30 | def self.print(text)
31 | clear_line
32 | append text
33 | end
34 |
35 | def self.puts(text)
36 | print "#{text}\n"
37 | end
38 |
39 | # Colours:
40 | # 0 Turn off all attributes
41 | # 1 Set bright mode
42 | # 4 Set underline mode
43 | # 5 Set blink mode
44 | # 7 Exchange foreground and background colors
45 | # 8 Hide text (foreground color would be the same as background)
46 | # 30 Black text
47 | # 31 Red text
48 | # 32 Green text
49 | # 33 Yellow text
50 | # 34 Blue text
51 | # 35 Magenta text
52 | # 36 Cyan text
53 | # 37 White text
54 | # 39 Default text color
55 | # 40 Black background
56 | # 41 Red background
57 | # 42 Green background
58 | # 43 Yellow background
59 | # 44 Blue background
60 | # 45 Magenta background
61 | # 46 Cyan background
62 | # 47 White background
63 | # 49 Default background color
64 |
65 | def self.background_red(text)
66 | return "\e[41m#{text}\e[49m"
67 | end
68 |
69 | def self.background_white(text)
70 | return "\e[47m#{text}\e[49m"
71 | end
72 |
73 | def self.bold(text)
74 | return "\e[1m#{text}\e[0m"
75 | end
76 |
77 | def self.cyan(text)
78 | return "\e[36m#{text}\e[39m"
79 | end
80 |
81 | def self.black(text)
82 | return "\e[30m#{text}\e[39m"
83 | end
84 |
85 | def self.green(text)
86 | return "\e[32m#{text}\e[39m"
87 | end
88 |
89 | def self.white(text)
90 | return "\e[37m#{text}\e[39m"
91 | end
92 | end
93 |
--------------------------------------------------------------------------------
/Scripts/reset_Accessibility.scpt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/Scripts/reset_Accessibility.scpt
--------------------------------------------------------------------------------
/Scripts/sign_update.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | if ARGV.length < 2
3 | puts "Usage: ruby sign_update.rb update_archive private_key"
4 | exit
5 | end
6 |
7 | puts `openssl dgst -sha1 -binary < "#{ARGV[0]}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64`
--------------------------------------------------------------------------------
/Switch.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Switch.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Switch.xcodeproj/xcshareddata/xcbaselines/BCA734FC16DAC54000CD4C74.xcbaseline/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | runDestinationsByUUID
6 |
7 | B10416B6-59AF-46B0-8C59-971F2DDC08B3
8 |
9 | localComputer
10 |
11 | busSpeedInMHz
12 | 100
13 | cpuCount
14 | 1
15 | cpuKind
16 | Intel Core i7
17 | cpuSpeedInMHz
18 | 2000
19 | logicalCPUCoresPerPackage
20 | 4
21 | modelCode
22 | MacBookAir5,1
23 | physicalCPUCoresPerPackage
24 | 2
25 | platformIdentifier
26 | com.apple.platform.macosx
27 |
28 | targetArchitecture
29 | x86_64
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Switch.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Switch/NSLayoutConstraint+SWConstraintHelpers.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSLayoutConstraint+SWConstraintHelpers.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/22/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | @interface NSLayoutConstraint (SWConstraintHelpers)
18 |
19 | + (NSArray *)sw_constraintsCenteringView:(NSView *)view toView:(NSView *)anchor;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Switch/NSLayoutConstraint+SWConstraintHelpers.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSLayoutConstraint+SWConstraintHelpers.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/22/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSLayoutConstraint+SWConstraintHelpers.h"
16 |
17 | @implementation NSLayoutConstraint (SWConstraintHelpers)
18 |
19 | + (NSArray *)sw_constraintsCenteringView:(NSView *)view toView:(NSView *)anchor;
20 | {
21 | return @[
22 | [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX
23 | relatedBy:NSLayoutRelationEqual
24 | toItem:anchor attribute:NSLayoutAttributeCenterX
25 | multiplier:1.f constant:0.f],
26 |
27 | [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterY
28 | relatedBy:NSLayoutRelationEqual
29 | toItem:anchor attribute:NSLayoutAttributeCenterY
30 | multiplier:1.f constant:0.f]
31 | ];
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/Switch/NSScreen+SWAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSScreen+SWAdditions.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 04/29/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface NSScreen (SWAdditions)
19 |
20 | + (CGFloat)sw_totalScreenHeight;
21 |
22 | - (CGDirectDisplayID)sw_screenNumber;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Switch/NSScreen+SWAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSScreen+SWAdditions.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 04/29/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSScreen+SWAdditions.h"
16 |
17 |
18 | @implementation NSScreen (SWAdditions)
19 |
20 | + (CGFloat)sw_totalScreenHeight;
21 | {
22 | return [[[NSScreen screens] nn_reduce:^id(id accumulator, id item) {
23 | if (!accumulator) { accumulator = @(0.0); }
24 | CGRect screenFrame = [item private_sw_absoluteFrame];
25 | CGFloat screenHeight = screenFrame.origin.y + screenFrame.size.height;
26 | if ([accumulator floatValue] < screenFrame.origin.y + screenFrame.size.height) {
27 | accumulator = @(screenHeight);
28 | }
29 | return accumulator;
30 | }] floatValue];
31 | }
32 |
33 | - (CGDirectDisplayID)sw_screenNumber;
34 | {
35 | NSDictionary *description = self.deviceDescription;
36 | return [description[@"NSScreenNumber"] unsignedIntValue];
37 | }
38 |
39 | - (CGRect)private_sw_absoluteFrame;
40 | {
41 | CGPoint offset = CGPointZero;
42 | for (NSScreen *screen in [NSScreen screens]) {
43 | if (screen.frame.origin.x < offset.x) {
44 | offset.x = screen.frame.origin.x;
45 | }
46 | if (screen.frame.origin.y < offset.y) {
47 | offset.y = screen.frame.origin.y;
48 | }
49 | }
50 |
51 | CGRect result = self.frame;
52 | result.origin.x -= offset.x;
53 | result.origin.y -= offset.y;
54 | return result;
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/Switch/NSSet+SWChaining.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSSet+SWChaining.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/22/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface NSSet (SWChaining)
19 |
20 | - (instancetype)sw_unionSet:(NSSet *)otherSet;
21 | - (instancetype)sw_minusSet:(NSSet *)otherSet;
22 | - (instancetype)sw_intersectSet:(NSSet *)otherSet;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Switch/NSSet+SWChaining.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSSet+SWChaining.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/22/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSSet+SWChaining.h"
16 |
17 |
18 | @implementation NSSet (SWChaining)
19 |
20 | - (instancetype)sw_unionSet:(NSSet *)otherSet;
21 | {
22 | NSMutableSet *result = [self mutableCopy];
23 | [result unionSet:otherSet];
24 | return result;
25 | }
26 |
27 | - (instancetype)sw_minusSet:(NSSet *)otherSet;
28 | {
29 | NSMutableSet *result = [self mutableCopy];
30 | [result minusSet:otherSet];
31 | return result;
32 | }
33 |
34 | - (instancetype)sw_intersectSet:(NSSet *)otherSet;
35 | {
36 | NSMutableSet *result = [self mutableCopy];
37 | [result intersectSet:otherSet];
38 | return result;
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Switch/Resources/Keyboard.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/Switch/Resources/Keyboard.icns
--------------------------------------------------------------------------------
/Switch/Resources/weave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/Switch/Resources/weave.png
--------------------------------------------------------------------------------
/Switch/SWAPIEnabledWorker.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWAPIEnabledWorker.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 07/10/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 |
16 | extern NSString *SWAXAPIEnabledKey;
17 |
18 |
19 | @interface SWAPIEnabledWorker : NNPollingObject
20 |
21 | + (BOOL)isAPIEnabled;
22 |
23 | - (instancetype)init;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Switch/SWAPIEnabledWorker.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWAPIEnabledWorker.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 07/10/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 | #import "SWAPIEnabledWorker.h"
15 |
16 | #import
17 | #import
18 |
19 |
20 | NSString *SWAXAPIEnabledKey = @"AXAPIEnabled";
21 |
22 |
23 | @interface SWAPIEnabledWorker ()
24 |
25 | @property (nonatomic, assign, readwrite) BOOL APIEnabled;
26 |
27 | @end
28 |
29 |
30 | @implementation SWAPIEnabledWorker
31 |
32 | #pragma mark - Initialization
33 |
34 | - (instancetype)init;
35 | {
36 | if (!(self = [super initWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)])) { return nil; }
37 |
38 | _APIEnabled = [[self class] isAPIEnabled];
39 | self.interval = 0.25;
40 |
41 | return self;
42 | }
43 |
44 | #pragma mark - NNPollingObject
45 |
46 | - (void)main;
47 | {
48 | BOOL enabled = [[self class] isAPIEnabled];
49 | if (enabled != self.APIEnabled) {
50 | self.APIEnabled = enabled;
51 | [self postNotification:@{ SWAXAPIEnabledKey : @(enabled) }];
52 | }
53 | }
54 |
55 | #pragma mark - SWAPIEnabledWorker
56 |
57 | + (BOOL)isAPIEnabled;
58 | {
59 | return (BOOL)AXIsProcessTrustedWithOptions(nil);
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Switch/SWAccessibilityService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWAccessibilityService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/20/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @class SWWindow;
16 |
17 |
18 | @interface SWAccessibilityService : NNService
19 |
20 | - (void)checkAPI;
21 |
22 | - (void)raiseWindow:(SWWindow *)window completion:(void(^)(NSError *))completionBlock;
23 | - (void)closeWindow:(SWWindow *)window completion:(void(^)(NSError *))completionBlock;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Switch/SWAdvancedPreferencesViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWAdvancedPreferencesViewController.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 04/30/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "MASPreferencesViewController.h"
16 |
17 |
18 | @interface SWAdvancedPreferencesViewController : NSViewController
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Switch/SWAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWAppDelegate.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/24/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface SWAppDelegate : NSObject
19 |
20 | - (void)relaunch:(id)sender;
21 | - (IBAction)showPreferences:(id)sender;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Switch/SWApplication.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWApplication.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/21/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface SWApplication : NSObject
19 |
20 | + (instancetype)applicationWithPID:(pid_t)pid name:(NSString *)name;
21 |
22 | @property (nonatomic, assign, readonly) pid_t pid;
23 | @property (nonatomic, copy, readonly) NSImage *cachedIcon;
24 | @property (nonatomic, strong, readonly) NSString *name;
25 |
26 | - (NSImage *)loadIcon;
27 |
28 | - (BOOL)isActiveApplication;
29 | - (BOOL)isLiveApplication;
30 | - (BOOL)canBeActivated;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Switch/SWCoreWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWCoreWindowController.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 07/10/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class SWCoreWindowController;
19 | @class SWWindow;
20 |
21 |
22 | @protocol SWCoreWindowControllerDelegate
23 |
24 | - (void)coreWindowController:(SWCoreWindowController *)controller didSelectWindow:(SWWindow *)window;
25 | - (void)coreWindowController:(SWCoreWindowController *)controller didActivateWindow:(SWWindow *)window;
26 | - (void)coreWindowControllerDidClickOutsideInterface:(SWCoreWindowController *)controller;
27 |
28 | @end
29 |
30 |
31 | // A poor attempt at getting core window controllers to be well-behaved targets for the multi-dispatch manager.
32 | @protocol SWCoreWindowControllerAPI
33 |
34 | @required
35 | - (void)updateWindowList:(NSOrderedSet *)windowList;
36 | - (void)selectWindow:(SWWindow *)window;
37 | - (void)disableWindow:(SWWindow *)window;
38 | - (void)enableWindow:(SWWindow *)window;
39 |
40 | @end
41 |
42 |
43 | @interface SWCoreWindowController : NSWindowController
44 |
45 | @property (nonatomic, strong, setter=updateWindowList:) NSOrderedSet *windowList;
46 | @property (nonatomic, weak) id delegate;
47 |
48 | - (id)initWithScreen:(NSScreen *)screen;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Switch/SWCoreWindowService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWCoreWindowService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 11/19/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @interface SWCoreWindowService : NNService
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Switch/SWEventTap.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWEventTap.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/13/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWHotKey.h"
16 |
17 |
18 | typedef BOOL (^SWEventTapKeyFilter)(CGEventRef event);
19 | typedef void (^SWEventTapModifierCallback)(BOOL matched);
20 | typedef void (^SWEventTapCallback)(CGEventRef event);
21 |
22 |
23 | @interface SWEventTap : NNService
24 |
25 | @property (nonatomic, assign, readwrite) BOOL suppressKeyEvents;
26 |
27 | // For key bindings. Block can return NO to stop the event's further propagation.
28 | - (void)registerHotKey:(SWHotKey *)hotKey object:(id)owner block:(SWEventTapKeyFilter)eventFilter;
29 | - (void)removeBlockForHotKey:(SWHotKey *)hotKey object:(id)owner;
30 |
31 | // For modifier key state updates. Used to dismiss the interface.
32 | - (void)registerModifier:(SWHotKeyModifierKey)modifiers object:(id)owner block:(SWEventTapModifierCallback)eventCallback;
33 | - (void)removeBlockForModifier:(SWHotKeyModifierKey)modifiers object:(id)owner;
34 |
35 | // Primarily for mouse move and scroll events. Used for selector updates..
36 | - (void)registerForEventsWithType:(CGEventType)eventType object:(id)owner block:(SWEventTapCallback)eventCallback;
37 | - (void)removeBlockForEventsWithType:(CGEventType)eventType object:(id)owner;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Switch/SWGeneralPreferencesViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWGeneralPreferencesViewController.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/10/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "MASPreferencesViewController.h"
16 |
17 |
18 | @interface SWGeneralPreferencesViewController : NSViewController
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Switch/SWHUDCollectionView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWHUDCollectionView.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 05/28/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @protocol SWHUDCollectionViewDataSource;
16 | @protocol SWHUDCollectionViewDelegate;
17 |
18 |
19 | @interface SWHUDCollectionView : NSView
20 |
21 | @property (nonatomic, weak) id dataSource;
22 | @property (nonatomic, weak) id delegate;
23 |
24 | @property (nonatomic, readonly) NSUInteger selectedIndex;
25 |
26 | - (NSUInteger)numberOfCells;
27 |
28 | - (NSView *)cellForIndex:(NSUInteger)index;
29 |
30 | - (void)selectCellAtIndex:(NSUInteger)index;
31 | - (void)deselectCell;
32 |
33 | - (void)reloadData;
34 |
35 | @end
36 |
37 |
38 | @protocol SWHUDCollectionViewDataSource
39 |
40 | - (CGFloat)HUDCollectionViewMaximumCellSize:(SWHUDCollectionView *)view;
41 | - (NSUInteger)HUDCollectionViewNumberOfCells:(SWHUDCollectionView *)view;
42 | - (NSView *)HUDCollectionView:(SWHUDCollectionView *)view viewForCellAtIndex:(NSUInteger)index;
43 |
44 | @end
45 |
46 |
47 | @protocol SWHUDCollectionViewDelegate
48 |
49 | @optional
50 | - (void)HUDCollectionView:(SWHUDCollectionView *)view willSelectCellAtIndex:(NSUInteger)index;
51 | - (void)HUDCollectionView:(SWHUDCollectionView *)view didSelectCellAtIndex:(NSUInteger)index;
52 | - (void)HUDCollectionView:(SWHUDCollectionView *)view activateCellAtIndex:(NSUInteger)index;
53 | - (void)HUDCollectionViewClickOutsideCollection:(SWHUDCollectionView *)view;
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/Switch/SWHUDView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWHUDView.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/02/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWRoundedRectView.h"
16 |
17 |
18 | @interface SWHUDView : SWRoundedRectView
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Switch/SWHUDView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWHUDView.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/02/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWHUDView.h"
16 |
17 |
18 | @implementation SWHUDView
19 |
20 | #pragma mark - Initialization
21 |
22 | - (id)initWithFrame:(CGRect)frame
23 | {
24 | BailUnless(self = [super initWithFrame:frame], nil);
25 |
26 | self.border = 0.0;
27 | self.radius = kNNWindowRoundRectRadius;
28 | self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
29 |
30 | return self;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Switch/SWHotKey.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWHotKey.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 07/16/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 | #import
17 |
18 |
19 | typedef NS_OPTIONS(unsigned, SWHotKeyModifierKey) {
20 | SWHotKeyModifierShift = controlKey,
21 | SWHotKeyModifierOption = optionKey,
22 | SWHotKeyModifierControl = shiftKey,
23 | SWHotKeyModifierCmd = cmdKey,
24 | };
25 |
26 |
27 | @interface SWHotKey : NSObject
28 |
29 | @property (nonatomic, readonly) CGKeyCode code;
30 | @property (nonatomic, readonly) SWHotKeyModifierKey modifiers;
31 |
32 | + (SWHotKey *)hotKeyWithKeycode:(CGKeyCode)code modifiers:(SWHotKeyModifierKey)modifiers;
33 | + (SWHotKey *)hotKeyFromEvent:(CGEventRef)event;
34 |
35 | - (NSString *)modifierDescription;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Switch/SWInterfaceController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWInterfaceController.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/01/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class SWInterfaceController;
19 | @class SWWindow;
20 |
21 |
22 | @protocol SWInterfaceControllerDelegate
23 |
24 | - (void)interfaceController:(SWInterfaceController *)controller didSelectWindow:(SWWindow *)window;
25 | - (void)interfaceController:(SWInterfaceController *)controller didActivateWindow:(SWWindow *)window;
26 | - (void)interfaceControllerDidClickOutsideInterface:(SWInterfaceController *)controller;
27 |
28 | @end
29 |
30 |
31 | @interface SWInterfaceController : NSObject
32 |
33 | @property (nonatomic, readwrite, assign, getter=showingInterface, setter=shouldShowInterface:) _Bool showInterface;
34 |
35 | - (instancetype)initWithDelegate:(id)delegate;
36 |
37 | - (void)updateWindowList:(NSOrderedSet *)windowList;
38 | - (void)selectWindow:(SWWindow *)window;
39 | - (void)disableWindow:(SWWindow *)window;
40 | - (void)enableWindow:(SWWindow *)window;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/Switch/SWKeyboardPreferencesViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWKeyboardPreferencesViewController.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 04/28/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface SWKeyboardPreferencesViewController : NSViewController
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Switch/SWKeyboardPreferencesViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWKeyboardPreferencesViewController.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 04/28/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWKeyboardPreferencesViewController.h"
16 |
17 |
18 | @interface SWKeyboardPreferencesViewController ()
19 |
20 | @end
21 |
22 |
23 | @implementation SWKeyboardPreferencesViewController
24 |
25 | #pragma mark - MASPreferencesViewController
26 |
27 | - (NSString *)identifier
28 | {
29 | return NSStringFromClass([self class]);
30 | }
31 |
32 | - (NSImage *)toolbarItemImage
33 | {
34 | return [NSImage imageNamed:@"Keyboard.icns"];
35 | }
36 |
37 | - (NSString *)toolbarItemLabel
38 | {
39 | return NSLocalizedString(@"Hotkeys", @"Toolbar item name for the Hotkeys preference pane");
40 | }
41 |
42 | - (BOOL)hasResizableWidth;
43 | {
44 | return NO;
45 | }
46 |
47 | - (BOOL)hasResizableHeight;
48 | {
49 | return NO;
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/Switch/SWLoggingService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWLoggingService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/15/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface SWLoggingService : NNService
19 |
20 | - (NSString *)logDirectoryPath;
21 | - (void)rotateLogIfNecessary;
22 | - (void)takeWindowListSnapshot;
23 |
24 | @end
25 |
26 | #define SWLog(fmt, ...) do { \
27 | [[SWLoggingService sharedService] rotateLogIfNecessary]; \
28 | Log(fmt, ##__VA_ARGS__); \
29 | } while(0)
30 |
31 | #define SWLogBackgroundThreadOnly() do { \
32 | if ([NSThread isMainThread]) { \
33 | SWLog(@"ERROR: -[%@ %@] was called on the main thread %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [NSThread callStackSymbols]); \
34 | Assert(![NSThread isMainThread]); \
35 | } \
36 | } while(0)
37 |
38 | #define SWLogMainThreadOnly() do { \
39 | if (![NSThread isMainThread]) { \
40 | SWLog(@"ERROR: -[%@ %@] was called on a background thread %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [NSThread callStackSymbols]); \
41 | Assert([NSThread isMainThread]); \
42 | } \
43 | } while(0)
44 |
45 | #define SWCodeBlock(...) __VA_ARGS__
46 |
47 | #define SWTimeTask(codeBlock, fmt, ...) do { \
48 | NSDate *start = [NSDate new]; \
49 | codeBlock \
50 | NSString *logmsg = [NSString stringWithFormat:fmt, ##__VA_ARGS__]; \
51 | NSTimeInterval elapsed = -[start timeIntervalSinceNow]; \
52 | if (elapsed > (1.0 / ([NSThread isMainThread] ? 60.0 : 10.0))) { \
53 | SWLog(@"%@ took %.3fs", logmsg, elapsed); \
54 | } \
55 | } while(0)
56 |
--------------------------------------------------------------------------------
/Switch/SWPreferencesService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWPreferencesService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/20/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class SWPreferencesService;
19 |
20 |
21 | @interface SWPreferencesService : NNService
22 |
23 | @property (nonatomic, assign, readwrite) _Bool multimonInterface;
24 | @property (nonatomic, assign, readwrite) _Bool multimonGroupByMonitor;
25 | @property (nonatomic, assign, readwrite) _Bool showStatusItem;
26 | @property (nonatomic, strong, readwrite, null_resettable) NSString *appcastURL;
27 |
28 | - (void)showPreferencesWindow:(nonnull id)sender;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/Switch/SWRoundedRectView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWRoundedRectView.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/01/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface SWRoundedRectView : NSView
19 |
20 | @property (nonatomic, assign) CGFloat border;
21 | @property (nonatomic, assign) CGFloat radius;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Switch/SWRoundedRectView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWRoundedRectView.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/01/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWRoundedRectView.h"
16 |
17 |
18 | @implementation SWRoundedRectView
19 |
20 | #pragma mark - Initialization
21 |
22 | - (instancetype)initWithFrame:(CGRect)frame;
23 | {
24 | BailUnless(self = [super initWithFrame:frame], nil);
25 |
26 | [self setWantsLayer:YES];
27 |
28 | return self;
29 | }
30 |
31 | #pragma mark - NSView
32 |
33 | - (void)updateLayer;
34 | {
35 | if (self.border > 0) {
36 | self.layer.borderWidth = self.border;
37 | self.layer.borderColor = [[[NSColor whiteColor] colorWithAlphaComponent:0.8] CGColor];
38 | }
39 |
40 | self.layer.cornerRadius = self.radius;
41 | self.layer.backgroundColor = [[[NSColor blackColor] colorWithAlphaComponent:0.3] CGColor];
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Switch/SWScrollControl.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWScrollControl.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 09/30/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @interface SWScrollControl : NSObject
19 |
20 | - (instancetype)initWithThreshold:(NSInteger)threshold incHandler:(dispatch_block_t)incBlock decHandler:(dispatch_block_t)decBlock;
21 |
22 | - (void)feed:(NSInteger)numEvents;
23 | - (void)reset;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Switch/SWScrollControl.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWScrollControl.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 09/30/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWScrollControl.h"
16 |
17 |
18 | static NSInteger const kMaxThreshold = NSIntegerMax / 2;
19 |
20 |
21 | @interface SWScrollControl ()
22 |
23 | @property (nonatomic, readonly, strong) dispatch_block_t inc;
24 | @property (nonatomic, readonly, strong) dispatch_block_t dec;
25 | @property (nonatomic, readonly, assign) NSInteger threshold;
26 | @property (nonatomic, readwrite, assign) NSInteger offset;
27 |
28 | @end
29 |
30 |
31 | @implementation SWScrollControl
32 |
33 | - (instancetype)initWithThreshold:(NSInteger)threshold incHandler:(dispatch_block_t)incBlock decHandler:(dispatch_block_t)decBlock;
34 | {
35 | BailUnless(self = [super init], nil);
36 |
37 | self->_inc = incBlock;
38 | self->_dec = decBlock;
39 | self->_threshold = labs(threshold);
40 |
41 | if (self->_threshold > kMaxThreshold) {
42 | NSLog(@"%@ does not support thresholds larger than %ld", NSStringFromClass([self class]), kMaxThreshold);
43 | return nil;
44 | }
45 |
46 | return self;
47 | }
48 |
49 | - (void)feed:(NSInteger)numEvents;
50 | {
51 | NSInteger units = (numEvents / self.threshold);
52 | numEvents %= self.threshold;
53 |
54 | self.offset += numEvents;
55 |
56 | units += (self.offset / self.threshold);
57 | self.offset %= self.threshold;
58 |
59 | while (units > 0) {
60 | self.inc();
61 | units--;
62 | }
63 | while (units < 0) {
64 | self.dec();
65 | units++;
66 | }
67 | }
68 |
69 | - (void)reset;
70 | {
71 | self.offset = 0;
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/Switch/SWSelectionBoxView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWSelectionBoxView.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/02/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWRoundedRectView.h"
16 |
17 |
18 | @interface SWSelectionBoxView : SWRoundedRectView
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Switch/SWSelectionBoxView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWSelectionBoxView.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/02/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWSelectionBoxView.h"
16 |
17 |
18 | @implementation SWSelectionBoxView
19 |
20 | #pragma mark - Initialization
21 |
22 | - (id)initWithFrame:(CGRect)frame
23 | {
24 | BailUnless(self = [super initWithFrame:frame], nil);
25 |
26 | self.border = kNNItemBorderWidth;
27 | self.radius = kNNSelectionRoundRectRadius;
28 | self.translatesAutoresizingMaskIntoConstraints = NO;
29 |
30 | return self;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Switch/SWSelector.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWSelector.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 01/05/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class SWWindow;
19 |
20 |
21 | @interface SWSelector : NSObject
22 |
23 | @property (nonatomic, copy, readonly) SWWindow *selectedWindow;
24 | @property (nonatomic, assign, readonly) NSInteger selectedIndex;
25 | @property (nonatomic, copy, readonly) NSOrderedSet *windowList;
26 |
27 | - (NSUInteger)selectedUIndex;
28 |
29 | - (instancetype)increment;
30 | - (instancetype)incrementWithoutWrapping;
31 | - (instancetype)decrement;
32 | - (instancetype)decrementWithoutWrapping;
33 | - (instancetype)selectIndex:(NSInteger)index;
34 | - (instancetype)updateWithWindowList:(NSOrderedSet *)windowList;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/Switch/SWStatusBarMenuService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWStatusBarMenuService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/15/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | @interface SWStatusBarMenuService : NNService
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Switch/SWWindow+TweetbotQuirks.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindow+TweetBotQuirks.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 01/11/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindow.h"
16 |
17 | @interface SWWindow (TweetbotQuirks)
18 |
19 | - (BOOL)tweetbot_isRelatedToLowerWindow:(SWWindow *)window;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Switch/SWWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindow.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/21/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | typedef NSPoint NNVec2;
19 |
20 |
21 | @class SWApplication;
22 |
23 |
24 | @interface SWWindow : NSObject
25 |
26 | + (instancetype)windowWithDescription:(NSDictionary *)description;
27 |
28 | @property (nonatomic, strong, readonly) SWApplication *application;
29 | @property (atomic, copy, readonly) NSDictionary *windowDescription;
30 |
31 | - (CGRect)frame;
32 | - (CGRect)flippedFrame;
33 | - (NSString *)name;
34 | - (NSScreen *)screen;
35 | - (CGWindowID)windowID;
36 |
37 | - (NSString *)displayName;
38 |
39 | - (BOOL)isSameWindow:(SWWindow *)window;
40 | - (BOOL)isRelatedToLowerWindow:(SWWindow *)window;
41 | - (NNVec2)offsetOfCenterToCenterOfWindow:(SWWindow *)window;
42 | - (NSSize)sizeDifferenceFromWindow:(SWWindow *)window;
43 | - (BOOL)enclosedByWindow:(SWWindow *)window;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Switch/SWWindowContentsService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowContentsService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 01/02/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @class SWWindow;
16 | @class SWWindowContentsService;
17 |
18 |
19 | @protocol SWWindowContentsSubscriber
20 |
21 | - (oneway void)windowContentService:(SWWindowContentsService *)windowService updatedContent:(NSImage *)content forWindow:(SWWindow *)window;
22 |
23 | @end
24 |
25 |
26 | @interface SWWindowContentsService : NNService
27 |
28 | - (NSImage *)contentForWindow:(SWWindow *)window;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/Switch/SWWindowGroup.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowGroup.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 12/24/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindow.h"
16 |
17 |
18 | @class SWApplication;
19 |
20 |
21 | @interface SWWindowGroup : SWWindow
22 |
23 | @property (nonatomic, strong, readonly) SWWindow *mainWindow;
24 | @property (nonatomic, strong, readonly) NSOrderedSet *windows;
25 |
26 | - (instancetype)initWithWindows:(NSOrderedSet *)windows mainWindow:(SWWindow *)mainWindow;
27 |
28 | - (BOOL)isRelatedToLowerGroup:(SWWindowGroup *)group;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/Switch/SWWindowListService.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowListService.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 12/24/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @class SWWindowListService;
16 |
17 |
18 | @protocol SWWindowListSubscriber
19 | @optional
20 |
21 | - (oneway void)windowListServiceStarted:(SWWindowListService *)service;
22 | - (oneway void)windowListService:(SWWindowListService *)service updatedList:(NSOrderedSet *)windows;
23 | - (oneway void)windowListServiceStopped:(SWWindowListService *)service;
24 |
25 | @end
26 |
27 |
28 | @interface SWWindowListService : NNService
29 |
30 | + (NSOrderedSet *)filterInfoDictionariesToWindowObjects:(NSArray *)infoDicts;
31 | + (NSOrderedSet *)filterWindowObjectsToWindowGroups:(NSOrderedSet *)rawWindowList;
32 | + (NSOrderedSet *)sortedWindowGroups:(NSOrderedSet *)windowGroups;
33 |
34 | @property (nonatomic, copy, readonly) NSOrderedSet *windows;
35 |
36 | // Background threads only!
37 | - (void)refreshWindowListAndWait;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Switch/SWWindowListWorker.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowListWorker.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/22/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @interface SWWindowListWorker : NNPollingObject
16 |
17 | - (void)refreshWindowListAndWait;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Switch/SWWindowListWorker.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowListWorker.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/22/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindowListWorker.h"
16 |
17 | #import
18 |
19 |
20 | static NSTimeInterval refreshInterval = 0.1;
21 |
22 |
23 | @interface SWWindowListWorker ()
24 |
25 | @property (nonatomic, copy, readwrite) NSArray *windowInfoList;
26 | @property (nonatomic, strong) dispatch_queue_t private_queue;
27 |
28 | @end
29 |
30 |
31 | @implementation SWWindowListWorker
32 |
33 | #pragma mark - Initialization
34 |
35 | - (instancetype)init;
36 | {
37 | dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
38 | if (!(self = [super initWithQueue:q])) { return nil; }
39 |
40 | self.private_queue = q;
41 | self.interval = refreshInterval;
42 |
43 | return self;
44 | }
45 |
46 | #pragma mark - NNPollingObject
47 |
48 | - (oneway void)main;
49 | {
50 | [self private_refreshWindowList];
51 | }
52 |
53 | #pragma mark - SWWindowListWorker
54 |
55 | - (void)refreshWindowListAndWait;
56 | {
57 | dispatch_sync(self.private_queue, ^{
58 | [self private_refreshWindowList];
59 | });
60 | }
61 |
62 | - (void)private_refreshWindowList;
63 | {
64 | SWLogBackgroundThreadOnly();
65 |
66 | SWTimeTask(SWCodeBlock({
67 | CFArrayRef cgWindowInfoList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
68 | NSArray *windowInfoList = CFBridgingRelease(cgWindowInfoList);
69 | if (![self.windowInfoList isEqualToArray:windowInfoList]) {
70 | self.windowInfoList = windowInfoList;
71 | [self postNotification:@{@"windows" : self.windowInfoList}];
72 | }
73 | }), @"Copying window info list");
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/Switch/SWWindowThumbnailView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowThumbnailView.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/21/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | @class SWWindow;
19 |
20 |
21 | @interface SWWindowThumbnailView : NSView
22 |
23 | - (instancetype)initWithFrame:(CGRect)frameRect window:(SWWindow *)window;
24 |
25 | - (void)setActive:(BOOL)active;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Switch/SWWindowWorker.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowWorker.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/22/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | @class SWWindow;
16 |
17 |
18 | @interface SWWindowWorker : NNPollingObject
19 |
20 | - (instancetype)initWithModelObject:(SWWindow *)window __attribute__((nonnull(1)));
21 |
22 | - (CGWindowID) windowID;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Switch/Sparkle.dsa_pub.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQCRka+uAlcerqIXNFJuII/YNdl5qB8c
3 | QGDYct1OhPpRKuQquy6imYtFl1ZRv8DOLnVZQFQYd1t/a6/thwc/Nl3M1h8p3dvx
4 | 5CD6lN7ph0rMBO+r5b3SQp6HVZtRf7c7tGweHkBtv4TkLYYBXgUcse9IdB9deZZ5
5 | KofWYNS7FPXWnpqYDvu/cQ2e+SjRdvydJui6YpZMhGuY4sIMjLFhqKrnIwL8Lk7e
6 | zrDofhhLri4WqsspMis4tcTObG/RKRJ3lQ9Ao0D4Wsak9wiaPcml4/OnbF7ivr3p
7 | HIXW+WDKI0QcL94UjM5K8CQ2pdD+Xkprcn3iEY+vopTLvyv5+1l7pX7DAhUA/dqJ
8 | 5WIBtx3fZz2U24ngdmtg9BUCggEADRDOa+Sta0EnVvOwZwzDBIUoelX6BYDj1qrP
9 | khQYOlh1gJdTCmSSuMPdh651djOJZivYgdvyOdV+Wq5cI8WSn7UU1qqhw3qnyjYK
10 | u74OPBH5YM7KALRkrVoJkCdKi6voWLxMBo9HVKs2ima6fatJk3ZpuxdQZrFMVayP
11 | xTOubvwlncNTU/WCpA8zshIdgw+Y95Zoxfu78gNRYMg9f14znIAzpYkxasnIvHGx
12 | BWhYegzopIvf5GBs+6V6tzIt9JCSpeyBaq9htvO6PkEtbITJHTvtJRK6O6wZHibU
13 | U5U1jKYmKap6CbDccHGelXOE/j7lXVdFe0p31zrUwmX+hT07tAOCAQUAAoIBACeq
14 | dDhGkZN/IhQI10f5AzlS+5KtoDPgCK9jAQF9eeqoNA+gtbkPsa9b0LH8Dfu8hgwA
15 | Liu3cHTaocfuRNhlBeUAgfBTs50rZlESk3QnDYqBPLUcopQHKgD+JYoSzsJsXsrd
16 | R2SnYtaHb8UivU9nYmi8jB58RrouqSrqOmn3YTbbQILRn4tTbn6yN5H5DOl3C99B
17 | riCx+OMeG/3aLo03vbAdXc0IL2Jr1+XOgXaHQyuZKxytl7yM5taUd4T/a16924jj
18 | 8vISK+2SN9GK2k9jWo5bWC07DO2sfO2ge8sJFDepl9REi/DMiFlzNKfqwfmJTs59
19 | aSzo181mAiCIc6G70sk=
20 | -----END PUBLIC KEY-----
21 |
--------------------------------------------------------------------------------
/Switch/Switch-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/Switch/Switch-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppleEventsUsageDescription
6 |
7 | LSUIElement
8 |
9 | CFBundleDevelopmentRegion
10 | en
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIconFile
14 |
15 | CFBundleIdentifier
16 | net.numist.${PRODUCT_NAME:rfc1034identifier}
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundleName
20 | ${PRODUCT_NAME}
21 | CFBundlePackageType
22 | APPL
23 | CFBundleShortVersionString
24 | 0.0.10 (β)
25 | CFBundleSignature
26 | ????
27 | CFBundleVersion
28 | 0.0.10
29 | LSApplicationCategoryType
30 | public.app-category.productivity
31 | LSMinimumSystemVersion
32 | ${MACOSX_DEPLOYMENT_TARGET}
33 | NSHumanReadableCopyright
34 | Copyright © 2016 Scott Perry.
35 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
36 |
37 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
38 |
39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 | NSMainNibFile
41 | MainMenu
42 | NSPrincipalClass
43 | NSApplication
44 | SUEnableAutomaticChecks
45 |
46 | SUShowReleaseNotes
47 |
48 | SUPublicDSAKeyFile
49 | Sparkle.dsa_pub.pem
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Switch/Switch-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Switch' target in the 'Switch' project
3 | //
4 |
5 | #define Log(fmt, ...) do { \
6 | NSLog(@"%@:%d %@", [[[NSString alloc] initWithCString:(__FILE__) encoding:NSUTF8StringEncoding] lastPathComponent], __LINE__, [NSString stringWithFormat:(fmt), ##__VA_ARGS__]); \
7 | } while(0)
8 |
9 | #ifdef __OBJC__
10 | # import
11 | # import
12 | # import
13 | # import
14 | # import "debugger.h"
15 | # import "constants.h"
16 | # import "helpers.h"
17 | # import "SWLoggingService.h"
18 | #endif
19 |
20 | #define sw_deprecated __attribute__((deprecated))
21 | #define sw_unused __attribute__((unused))
22 |
--------------------------------------------------------------------------------
/Switch/Switch.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Switch/constants.h:
--------------------------------------------------------------------------------
1 | //
2 | // constants.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/01/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | // Points
19 | extern const CGFloat kNNMaxWindowThumbnailSize;
20 | extern const CGFloat kNNMaxApplicationIconSize;
21 | extern const CGFloat kNNScreenToWindowInset;
22 | extern const CGFloat kNNWindowToItemInset;
23 | extern const CGFloat kNNItemBorderWidth;
24 | extern const CGFloat kNNItemToThumbInset;
25 | extern const CGFloat kNNWindowToThumbInset;
26 | extern const CGFloat kNNWindowRoundRectRadius;
27 | extern const CGFloat kNNSelectionRoundRectRadius;
28 |
29 | // Seconds
30 | extern const NSTimeInterval delayBeforePresentingSwitcherWindow;
31 |
32 | // Enum stringification
33 | NSString *NNStringFromCGWindowLevel(long level);
34 |
35 | // Helper macros
36 | #define CLASS_CAST(Classname, value) ((Classname *)CLASS_CAST_IMPL([Classname class], (value)))
37 | id CLASS_CAST_IMPL(Class class, id value);
38 |
--------------------------------------------------------------------------------
/Switch/debugger.c:
--------------------------------------------------------------------------------
1 | //
2 | // debugger.c
3 | // Debugger
4 | //
5 | // Created by Scott Perry on 8/11/11.
6 | // Public domain.
7 | //
8 |
9 | #if defined(DEBUG)
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | /*
18 | * NOTE: Forward decl of AmIBeingDebugged since this file is built without platform flags
19 | * (resulting in a warning when including debugger.h directly)
20 | */
21 | bool AmIBeingDebugged(void);
22 |
23 | /*
24 | * This function provided by Apple TechNote QA1361:
25 | * http://developer.apple.com/library/mac/#qa/qa1361/_index.html
26 | */
27 | bool AmIBeingDebugged(void)
28 | // Returns true if the current process is being debugged (either
29 | // running under the debugger or has a debugger attached post facto).
30 | {
31 | int junk;
32 | int mib[4];
33 | struct kinfo_proc info;
34 | size_t size;
35 |
36 | // Initialize the flags so that, if sysctl fails for some bizarre
37 | // reason, we get a predictable result.
38 |
39 | info.kp_proc.p_flag = 0;
40 |
41 | // Initialize mib, which tells sysctl the info we want, in this case
42 | // we're looking for information about a specific process ID.
43 |
44 | mib[0] = CTL_KERN;
45 | mib[1] = KERN_PROC;
46 | mib[2] = KERN_PROC_PID;
47 | mib[3] = getpid();
48 |
49 | // Call sysctl.
50 |
51 | size = sizeof(info);
52 | junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
53 | assert(junk == 0);
54 |
55 | // We're being debugged if the P_TRACED flag is set.
56 |
57 | return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
58 | }
59 |
60 | #endif
61 |
--------------------------------------------------------------------------------
/Switch/en.lproj/Credits.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370
2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;}
4 | \vieww9600\viewh8400\viewkind0
5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
6 |
7 | \f0\b\fs24 \cf0 Engineering:
8 | \b0 \
9 | Scott Perry\
10 | \
11 |
12 | \b Human Interface Design:
13 | \b0 \
14 | Nobody\
15 | \
16 |
17 | \b Testing:
18 | \b0 \
19 | So far, nobody\
20 | \
21 |
22 | \b Documentation:
23 | \b0 \
24 | Oops\
25 | \
26 |
27 | \b With special thanks to:
28 | \b0 \
29 | David Smith, Gwynne Raskind, and Rob Rix\
30 | }
--------------------------------------------------------------------------------
/Switch/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Switch/helpers.h:
--------------------------------------------------------------------------------
1 | //
2 | // helpers.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 |
18 | #define NNAssertMainQueue() NSAssert([[NSThread currentThread] isMainThread], @"Current path of execution must be run on the main thread");
19 |
20 | BOOL NNCGRectsEqual(CGRect a, CGRect b);
21 | BOOL NNNSSizesEqual(NSSize a, NSSize b);
22 |
23 | void *NNCFAutorelease(CFTypeRef cfObject);
24 |
--------------------------------------------------------------------------------
/Switch/helpers.m:
--------------------------------------------------------------------------------
1 | //
2 | // helpers.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "helpers.h"
16 |
17 |
18 | BOOL NNNSSizesEqual(NSSize a, NSSize b)
19 | {
20 | return a.width == b.width && a.height == b.height;
21 | }
22 |
23 | BOOL NNCGRectsEqual(CGRect a, CGRect b)
24 | {
25 | return a.origin.x == b.origin.x && a.origin.y == b.origin.y && NNNSSizesEqual(a.size, b.size);
26 | }
27 |
28 | void *NNCFAutorelease(CFTypeRef cfObject)
29 | {
30 | if (cfObject) {
31 | static Class arp = Nil;
32 | static dispatch_once_t onceToken;
33 | dispatch_once(&onceToken, ^{
34 | arp = NSClassFromString(@"NSAutoreleasePool");
35 | Assert(arp);
36 | });
37 |
38 | [arp addObject:(__bridge id)cfObject];
39 | }
40 |
41 | return (void *)cfObject;
42 | }
43 |
--------------------------------------------------------------------------------
/Switch/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 02/24/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | int main(int argc, char *argv[])
18 | {
19 | return NSApplicationMain(argc, (const char **)argv);
20 | }
21 |
--------------------------------------------------------------------------------
/SwitchTests/NSImage+NNFilesystem.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSImage+NNFilesystem.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | @interface NSImage (NNFilesystem)
18 |
19 | - (BOOL)writeTIFFToFile:(NSString *)path;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/SwitchTests/NSImage+NNFilesystem.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSImage+NNFilesystem.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSImage+NNFilesystem.h"
16 |
17 | @implementation NSImage (NNFilesystem)
18 |
19 | - (BOOL)writeTIFFToFile:(NSString *)path;
20 | {
21 | return [[self TIFFRepresentation] writeToFile:path atomically:NO];
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/SwitchTests/NSWindow+NNScreenCapture.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSWindow+NNScreenCapture.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | @interface NSWindow (NNScreenCapture)
18 |
19 | - (NSImage *)nnImage;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/SwitchTests/NSWindow+NNScreenCapture.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSWindow+NNScreenCapture.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "NSWindow+NNScreenCapture.h"
16 |
17 | @implementation NSWindow (NNScreenCapture)
18 |
19 | - (NSImage *)nnImage;
20 | {
21 | CGWindowID windowID = (CGWindowID)self.windowNumber;
22 | CGImageRef cgShot = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageDefault);
23 | Check(cgShot);
24 | NSImage *nsShot = [[NSImage alloc] initWithCGImage:cgShot size:NSZeroSize];
25 |
26 | CFRelease(cgShot);
27 | cgShot = NULL;
28 |
29 | return nsShot;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/SwitchTests/References/image.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/SwitchTests/References/image.tiff
--------------------------------------------------------------------------------
/SwitchTests/SWDashTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWDashTests.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 01/05/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindowListServiceTestSuperclass.h"
16 |
17 |
18 | @interface SWDashTests : SWWindowListServiceTestSuperclass
19 |
20 | @end
21 |
22 |
23 | @implementation SWDashTests
24 |
25 | // https://github.com/numist/Switch/issues/48
26 | - (void)testUnnamedDashWindow;
27 | {
28 | NSDictionary *windowDescription = @{
29 | NNWindowAlpha : @1,
30 | NNWindowBounds : DICT_FROM_RECT(((CGRect){
31 | .size.height = 616,
32 | .size.width = 936,
33 | .origin.x = 44,
34 | .origin.y = 36
35 | })),
36 | NNWindowIsOnscreen : @1,
37 | NNWindowLayer : @0,
38 | NNWindowMemoryUsage : @2576052,
39 | NNWindowNumber : @84004,
40 | NNWindowOwnerName : @"Dash",
41 | NNWindowOwnerPID : @7852,
42 | NNWindowSharingState : @1,
43 | NNWindowStoreType : @2,
44 | };
45 | NSArray *infoList = @[windowDescription];
46 |
47 | [self updateListServiceWithInfoList:infoList];
48 | XCTAssertEqual(self.listService.windows.count, 1, @"Dash was incorrectly filtered out");
49 | XCTAssertEqual(((SWWindowGroup *)[self.listService.windows objectAtIndex:0]).windows.count, infoList.count, @"");
50 | XCTAssertEqualObjects(((SWWindowGroup *)[self.listService.windows objectAtIndex:0]).mainWindow.windowDescription, windowDescription, @"");
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/SwitchTests/SWFinderTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWFinderTests.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 05/13/16.
6 | // Copyright © 2016 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindowListServiceTestSuperclass.h"
16 |
17 |
18 | @interface SWFinderTests : SWWindowListServiceTestSuperclass
19 |
20 | @end
21 |
22 |
23 | @implementation SWFinderTests
24 |
25 | - (void)testQuicklookWindow;
26 | {
27 | // This Quicklook window was recorded on OS X 10.11.3 when Finder was not frontmost
28 | NSArray *infoList = @[
29 | @{
30 | NNWindowLayer : @0,
31 | NNWindowAlpha : @1.000000,
32 | NNWindowMemoryUsage : @1024,
33 | NNWindowIsOnscreen : @1,
34 | NNWindowSharingState : @1,
35 | NNWindowOwnerPID : @58213,
36 | NNWindowNumber : @14164,
37 | NNWindowOwnerName : @"Finder",
38 | NNWindowStoreType : @1,
39 | NNWindowBounds : @{
40 | @"Height" : @669,
41 | @"Width" : @366,
42 | @"X" : @500,
43 | @"Y" : @59,
44 | },
45 | NNWindowName : @"",
46 | },
47 | ];
48 |
49 | [self updateListServiceWithInfoList:infoList];
50 | XCTAssertEqual(self.listService.windows.count, 0, @"Finder QuickLook window was incorrectly filtered");
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/SwitchTests/SWGithubTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWGithubTests.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindowListServiceTestSuperclass.h"
16 |
17 |
18 | @interface SWGithubTests : SWWindowListServiceTestSuperclass
19 |
20 | @end
21 |
22 |
23 | @implementation SWGithubTests
24 |
25 | // This never had an Issue on Github, but it was a problem. Fixed in the Github app at the end of 2013 (thanks! <3), test kept for compatibility.
26 | - (void)testUnnamedGithubWindow;
27 | {
28 | NSDictionary *windowDescription = @{
29 | NNWindowAlpha : @1,
30 | NNWindowBounds : DICT_FROM_RECT(((CGRect){
31 | .size.height = 742,
32 | .size.width = 1311,
33 | .origin.x = 28,
34 | .origin.y = 22
35 | })),
36 | NNWindowIsOnscreen : @1,
37 | NNWindowLayer : @0,
38 | NNWindowMemoryUsage : @4804660,
39 | NNWindowNumber : @93247,
40 | NNWindowOwnerName : @"GitHub",
41 | NNWindowOwnerPID : @23598,
42 | NNWindowSharingState : @1,
43 | NNWindowStoreType : @2,
44 | };
45 | NSArray *infoList = @[windowDescription];
46 |
47 | [self updateListServiceWithInfoList:infoList];
48 |
49 | XCTAssertEqual(self.listService.windows.count, 1, @"");
50 | XCTAssertEqual(((SWWindowGroup *)[self.listService.windows objectAtIndex:0]).windows.count, infoList.count, @"");
51 | XCTAssertEqualObjects(((SWWindowGroup *)[self.listService.windows objectAtIndex:0]).mainWindow.windowDescription, windowDescription, @"");
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/SwitchTests/SWIsolatorTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWIsolatorTests.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 04/30/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindowListServiceTestSuperclass.h"
16 |
17 |
18 | @interface SWIsolatorTests : SWWindowListServiceTestSuperclass
19 |
20 | @end
21 |
22 |
23 | @implementation SWIsolatorTests
24 |
25 | - (void)testIsolatorShieldFiltering;
26 | {
27 | NSDictionary *windowDescription = @{
28 | NNWindowLayer : @0,
29 | NNWindowName : @"",
30 | NNWindowMemoryUsage : @5186812,
31 | NNWindowIsOnscreen : @1,
32 | NNWindowSharingState : @1,
33 | NNWindowOwnerPID : @428,
34 | NNWindowNumber : @121,
35 | NNWindowOwnerName : @"Isolator",
36 | NNWindowStoreType : @2,
37 | NNWindowBounds : @{
38 | @"Height" : @900,
39 | @"Width" : @1440,
40 | @"X" : @0,
41 | @"Y" : @0,
42 | },
43 | NNWindowAlpha : @0.731156,
44 | };
45 | NSArray *infoList = @[windowDescription];
46 |
47 | [self updateListServiceWithInfoList:infoList];
48 |
49 | XCTAssertEqual(self.listService.windows.count, 0, @"");
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/SwitchTests/SWTestApplication.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWTestApplication.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 09/29/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWApplication.h"
16 |
17 |
18 | @interface SWTestApplication : SWApplication
19 |
20 | @property (nonatomic, assign, readwrite, getter=isActiveApplication) BOOL active;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/SwitchTests/SWTestApplication.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWTestApplication.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 09/29/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWTestApplication.h"
16 |
17 |
18 | @interface SWTestApplication ()
19 |
20 | @property (nonatomic, assign, readwrite) pid_t pid;
21 | @property (nonatomic, copy, readwrite) NSImage *icon;
22 | @property (nonatomic, strong, readwrite) NSString *name;
23 | @property (nonatomic, assign, readwrite, getter=isLiveApplication) BOOL liveApplication;
24 | @property (nonatomic, assign, readwrite) BOOL canBeActivated;
25 |
26 | @end
27 |
28 |
29 | @implementation SWTestApplication
30 |
31 | @synthesize pid = _pid;
32 | @synthesize icon = _icon;
33 | @synthesize name = _name;
34 | @synthesize liveApplication = _liveApplication;
35 | @synthesize canBeActivated = _canBeActivated;
36 |
37 | - (instancetype)initWithPID:(pid_t)pid name:(NSString *)name;
38 | {
39 | if (!(self = [super init])) { return nil; }
40 |
41 | self->_pid = pid;
42 | self->_name = name;
43 | self->_active = [name isEqualToString:@"Switch"];
44 | self->_liveApplication = YES;
45 | self->_canBeActivated = ^{
46 | NSArray *applicationNamesThatCannotBeActivated = @[
47 | @"com.apple.security.pboxd",
48 | @"com.apple.appkit.xpc.openAndSav",
49 | ];
50 | return ![applicationNamesThatCannotBeActivated containsObject:self.name];
51 | }();
52 |
53 | return self;
54 | }
55 |
56 | - (NSRunningApplication *)runningApplication;
57 | {
58 | __builtin_trap();
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/SwitchTests/SWWindowFilteringTests.h:
--------------------------------------------------------------------------------
1 | //
2 | // NNWindowFilteringTests.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 10/11/13.
6 | // Copyright © 2013 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #ifndef Switch_NNWindowFilteringTests_h
16 | #define Switch_NNWindowFilteringTests_h
17 |
18 |
19 | #define DICT_FROM_RECT(rect) ((__bridge_transfer NSDictionary *)CGRectCreateDictionaryRepresentation(rect))
20 |
21 |
22 | static NSString *NNWindowAlpha;
23 | static NSString *NNWindowBounds;
24 | static NSString *NNWindowIsOnscreen;
25 | static NSString *NNWindowLayer;
26 | static NSString *NNWindowMemoryUsage;
27 | static NSString *NNWindowName;
28 | static NSString *NNWindowNumber;
29 | static NSString *NNWindowOwnerName;
30 | static NSString *NNWindowOwnerPID;
31 | static NSString *NNWindowSharingState;
32 | static NSString *NNWindowStoreType;
33 |
34 | __attribute__((constructor)) static void NNWindowKeyInit() {
35 | NNWindowAlpha = (__bridge NSString *)kCGWindowAlpha;
36 | NNWindowBounds = (__bridge NSString *)kCGWindowBounds;
37 | NNWindowIsOnscreen = (__bridge NSString *)kCGWindowIsOnscreen;
38 | NNWindowLayer = (__bridge NSString *)kCGWindowLayer;
39 | NNWindowMemoryUsage = (__bridge NSString *)kCGWindowMemoryUsage;
40 | NNWindowName = (__bridge NSString *)kCGWindowName;
41 | NNWindowNumber = (__bridge NSString *)kCGWindowNumber;
42 | NNWindowOwnerName = (__bridge NSString *)kCGWindowOwnerName;
43 | NNWindowOwnerPID = (__bridge NSString *)kCGWindowOwnerPID;
44 | NNWindowSharingState = (__bridge NSString *)kCGWindowSharingState;
45 | NNWindowStoreType = (__bridge NSString *)kCGWindowStoreType;
46 | }
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/SwitchTests/SWWindowListServiceTestSuperclass.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowListServiceTestSuperclass.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 01/05/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import
16 |
17 | #import "SWWindowListService.h"
18 | #import "SWWindowFilteringTests.h"
19 | #import "SWWindowGroup.h"
20 | #import "SWWindow.h"
21 |
22 |
23 | @interface SWWindowListServiceTestSuperclass : XCTestCase
24 |
25 | @property (nonatomic, strong, readonly) SWWindowListService *listService;
26 |
27 | - (void)updateListServiceWithInfoList:(NSArray *)infoList;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/SwitchTests/SWWindowListServiceTestSuperclass.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWWindowListServiceTestSuperclass.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 01/05/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 |
15 | #import "SWWindowListServiceTestSuperclass.h"
16 |
17 |
18 | @interface SWWindowListService (Internal)
19 |
20 | - (void)private_updateWindowList:(NSArray *)windowInfoList;
21 |
22 | @end
23 |
24 |
25 | @implementation SWWindowListServiceTestSuperclass
26 |
27 | - (void)setUp
28 | {
29 | [super setUp];
30 |
31 | self->_listService = [SWWindowListService new];
32 | }
33 |
34 | - (void)tearDown
35 | {
36 | self->_listService = nil;
37 |
38 | [super tearDown];
39 | }
40 |
41 | - (void)updateListServiceWithInfoList:(NSArray *)infoList;
42 | {
43 | [self.listService private_updateWindowList:infoList];
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/SwitchTests/SwitchTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | net.numist.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwitchTests/en.lproj/1376.ar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/SwitchTests/en.lproj/1376.ar
--------------------------------------------------------------------------------
/SwitchTests/en.lproj/5891.ar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/SwitchTests/en.lproj/5891.ar
--------------------------------------------------------------------------------
/SwitchTests/en.lproj/5904.ar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/numist/Switch/7d5cda1411c939a5229c80e6b194ae79d6fc41ef/SwitchTests/en.lproj/5904.ar
--------------------------------------------------------------------------------
/SwitchTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/exportOptionsApp.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | method
6 | mac-application
7 |
8 |
--------------------------------------------------------------------------------
/relaunch/SWTerminationListener.h:
--------------------------------------------------------------------------------
1 | //
2 | // SWTerminationListener.h
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/11/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 | // Inspiration from relaunch.m: https://github.com/andymatuschak/Sparkle/blob/7316a00e9c92f54c552076a44c38241c0f1bf975/relaunch.m
15 | //
16 |
17 | @interface SWTerminationListener : NSObject
18 |
19 | - (id)initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid;
20 | - (void)relaunch;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/relaunch/SWTerminationListener.m:
--------------------------------------------------------------------------------
1 | //
2 | // SWTerminationListener.m
3 | // Switch
4 | //
5 | // Created by Scott Perry on 03/11/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 | // Inspiration from relaunch.m: https://github.com/andymatuschak/Sparkle/blob/7316a00e9c92f54c552076a44c38241c0f1bf975/relaunch.m
15 | //
16 |
17 | #import "SWTerminationListener.h"
18 |
19 |
20 | @interface SWTerminationListener ()
21 |
22 | @property (nonatomic, assign, readonly) const char *executablePath;
23 | @property (nonatomic, assign, readonly) pid_t parentProcessId;
24 |
25 | @end
26 |
27 |
28 | @implementation SWTerminationListener
29 |
30 | - (id)initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid;
31 | {
32 | if (!(self = [super init])) { return nil; }
33 |
34 | _executablePath = execPath;
35 | _parentProcessId = ppid;
36 | if (getppid() == 1) {
37 | // ppid is launchd (1) => parent terminated already
38 | [self relaunch];
39 | }
40 | [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(watchdog:) userInfo:nil repeats:YES];
41 |
42 | return self;
43 | }
44 |
45 | - (void)watchdog:(NSTimer *)timer;
46 | {
47 | if (![NSRunningApplication runningApplicationWithProcessIdentifier:self.parentProcessId]) {
48 | [self relaunch];
49 | }
50 | }
51 |
52 | - (void)relaunch;
53 | {
54 | [[NSWorkspace sharedWorkspace] openFile:[[NSFileManager defaultManager] stringWithFileSystemRepresentation:self.executablePath length:strlen(self.executablePath)]];
55 | [[NSApplication sharedApplication] terminate:self];
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/relaunch/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // relaunch
4 | //
5 | // Created by Scott Perry on 03/11/14.
6 | // Copyright © 2014 Scott Perry.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 | //
10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 | //
12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 | //
14 | // Inspiration from relaunch.m: https://github.com/andymatuschak/Sparkle/blob/7316a00e9c92f54c552076a44c38241c0f1bf975/relaunch.m
15 | //
16 |
17 | #import "SWTerminationListener.h"
18 |
19 |
20 | int main (int argc, const char * argv[])
21 | {
22 | if (argc != 3) { return EXIT_FAILURE; }
23 |
24 | @autoreleasepool {
25 | [NSApplication sharedApplication];
26 |
27 | static SWTerminationListener *listener;
28 | listener = [[SWTerminationListener alloc] initWithExecutablePath:argv[1] parentProcessId:atoi(argv[2])];
29 |
30 | [[NSApplication sharedApplication] run];
31 | }
32 |
33 | return EXIT_SUCCESS;
34 | }
35 |
--------------------------------------------------------------------------------
/relaunch/relaunch-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #endif
10 |
--------------------------------------------------------------------------------