├── asdfghjkl
├── bat27.png
├── asdfghjkl-Bridging-Header.h
├── ScrollUtils.h
├── ScrollUtils.m
├── Base.lproj
│ └── MainMenu.xib
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
└── AppDelegate.swift
├── asdfghjkl.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcuserdata
│ └── matt.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ ├── asdfghjkl- root.xcscheme
│ │ └── asdfghjkl.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
├── asdfghjklTests
├── Info.plist
└── asdfghjklTests.swift
└── README.md
/asdfghjkl/bat27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shrugs/asdfghjkl/HEAD/asdfghjkl/bat27.png
--------------------------------------------------------------------------------
/asdfghjkl/asdfghjkl-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 | #import "ScrollUtils.h"
--------------------------------------------------------------------------------
/asdfghjkl.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/asdfghjkl/ScrollUtils.h:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollUtils.h
3 | // asdfghjkl
4 | //
5 | // Created by Matt Condon on 9/6/15.
6 | // Copyright © 2015 mattc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ScrollUtils : NSObject
12 |
13 | + (CGEventRef) createScrollEventWithScrollAmount:(int32_t)amt;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/asdfghjkl/ScrollUtils.m:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollUtils.m
3 | // asdfghjkl
4 | //
5 | // Created by Matt Condon on 9/6/15.
6 | // Copyright © 2015 mattc. All rights reserved.
7 | //
8 |
9 | #import "ScrollUtils.h"
10 |
11 | @implementation ScrollUtils
12 |
13 | + (CGEventRef) createScrollEventWithScrollAmount:(int32_t)amt
14 | {
15 | return CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 1, amt, 0);
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/asdfghjklTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/asdfghjkl.xcodeproj/xcuserdata/matt.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | asdfghjkl- root.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | asdfghjkl.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | C935D0221B9AC16400D8E9AC
21 |
22 | primary
23 |
24 |
25 | C935D0321B9AC16400D8E9AC
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/asdfghjklTests/asdfghjklTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // asdfghjklTests.swift
3 | // asdfghjklTests
4 | //
5 | // Created by Matt Condon on 9/5/15.
6 | // Copyright (c) 2015 mattc. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import XCTest
11 |
12 | class asdfghjklTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/asdfghjkl/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/asdfghjkl/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/asdfghjkl/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | LSUIElement
28 |
29 | NSHumanReadableCopyright
30 | Copyright © 2015 mattc. All rights reserved.
31 | NSMainNibFile
32 | MainMenu
33 | NSPrincipalClass
34 | NSApplication
35 |
36 |
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## asdfghjkl
2 |
3 | > Keyboard as Trackpad
4 |
5 | Yes, really.
6 |
7 | [](https://www.youtube.com/watch?v=QZ1KNP_R76c)
8 |
9 | Watch it in action [on YouTube](https://www.youtube.com/watch?v=QZ1KNP_R76c).
10 |
11 | ## Inspiration
12 |
13 | Throughout history, we've invented better and better ways of interfacing with machines. The **mouse**, the **VirtualBoy**, the **nub mouse thing** on ThinkPads. But we weren't satisfied with the current state of input devices. As computers become more and more personal and more and more a part of our daily lives, we need better, **more efficient** ways of interacting with them. One of the biggest inefficiencies in modern desktop computing is moving your hands from the keyboard to the track pad. So we got rid of that. Yup. Really.
14 |
15 | Introducing **asdfghjkl** , a revolution in computer-human interface design patterns, by team "Keyboard as Trackpad".
16 |
17 | ## What it does
18 |
19 | Hold down the _Control_ key and run your finger across the keyboard. Watch as the mouse follows your commands. Marvel at the time you saved.
20 | Hold down the _Shift_ key and run your finger across the keyboard. Watch as the page scrolls under your command. Marvel at the time you saved.
21 |
22 | ## Challenges I ran into
23 |
24 | Using my computer.
25 |
26 | ## Accomplishments that I'm proud of
27 |
28 | Using my computer.
29 |
30 | ## What I learned
31 |
32 | How to better use my computer.
33 |
34 | ## How I built it
35 |
36 | After getting the MVP working, I exclusively used **asdfghjkl** for navigation and input while developing the app.
37 |
38 | It's built in Swift 2.0 (for the easy C interoperability) and partially Obj-C for certain functions.
39 |
40 | ## What's next for **asdfghjkl**
41 |
42 | Apple partnership is in the works. NASA partnership is going smoothly; soon the inhabitants of the ISS will be able to get more done, easier, thanks to mandatory **asdfghjkl** usage.
43 |
44 | ## Info
45 |
46 | The correct way to pronounce **asdfghjkl** is "asdfghjkl". Please don't get it wrong. Additionally, the only way to type **asdfghjkl** is by sliding your finger across the entire home row. Just don't hold _Control_, or your mouse will fly to the right!
47 |
--------------------------------------------------------------------------------
/asdfghjkl.xcodeproj/xcuserdata/matt.xcuserdatad/xcschemes/asdfghjkl- root.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
55 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
74 |
76 |
82 |
83 |
84 |
85 |
87 |
88 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/asdfghjkl.xcodeproj/xcuserdata/matt.xcuserdatad/xcschemes/asdfghjkl.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
78 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
99 |
105 |
106 |
107 |
108 |
110 |
111 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/asdfghjkl.xcodeproj/xcuserdata/matt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
18 |
30 |
31 |
32 |
34 |
46 |
47 |
48 |
50 |
62 |
63 |
64 |
66 |
78 |
79 |
80 |
82 |
94 |
95 |
96 |
98 |
110 |
111 |
112 |
114 |
126 |
127 |
128 |
130 |
140 |
141 |
142 |
144 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/asdfghjkl/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // asdfghjkl
4 | //
5 | // Created by Matt Condon on 9/5/15.
6 | // Copyright (c) 2015 mattc. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import CoreGraphics
11 |
12 | let POSITIONS : [Int64: [Int]] = [
13 | 50: [223, 173],
14 | 18: [267, 173],
15 | 19: [309, 173],
16 | 20: [351, 173],
17 | 21: [393, 173],
18 | 23: [435, 173],
19 | 22: [477, 173],
20 | 26: [519, 173],
21 | 28: [561, 173],
22 | 25: [603, 173],
23 | 29: [645, 173],
24 | 27: [687, 173],
25 | 24: [730, 173],
26 | 51: [786, 173],
27 |
28 | 48: [233, 214],
29 | 12: [285, 214],
30 | 13: [330, 214],
31 | 14: [372, 214],
32 | 15: [414, 214],
33 | 17: [456, 214],
34 | 16: [498, 214],
35 | 32: [540, 214],
36 | 34: [582, 214],
37 | 31: [624, 214],
38 | 35: [666, 214],
39 | 33: [708, 214],
40 | 30: [750, 214],
41 | 42: [792, 214],
42 |
43 | 0: [298, 255],
44 | 1: [340, 255],
45 | 2: [382, 255],
46 | 3: [424, 255],
47 | 5: [466, 255],
48 | 4: [508, 255],
49 | 38: [550, 255],
50 | 40: [592, 255],
51 | 37: [634, 255],
52 | 41: [676, 255],
53 | 39: [718, 255],
54 | 36: [779, 255],
55 |
56 | 6: [319, 296],
57 | 7: [361, 296],
58 | 8: [403, 296],
59 | 9: [445, 296],
60 | 11: [487, 296],
61 | 45: [529, 296],
62 | 46: [571, 296],
63 | 43: [613, 296],
64 | 47: [655, 296],
65 | 44: [697, 296],
66 |
67 | 49: [489, 340],
68 | 123: [712, 350],
69 | 126: [754, 330],
70 | 125: [754, 350],
71 | 124: [796, 350],
72 | ]
73 |
74 | let LEFT_KEYS : [Int64] = [50, 18, 19, 20, 21, 23, 48, 12, 13, 14, 15, 17, 0, 1, 2, 3, 5, 6, 7, 8, 9, 11]
75 | let RIGHT_KEYS : [Int64] = [22, 26, 28, 25, 29, 27, 24, 51, 16, 32, 34, 31, 35, 33, 30, 42, 4, 38, 40, 37, 41, 39, 36, 11, 45, 46, 43, 47, 44, 49, 123, 125, 126, 124]
76 |
77 | var lastLocation : [Int] = []
78 | var lastKeyCode : Int64?
79 | var isTouchingTimer : NSTimer?
80 | var keyUpTimer : NSTimer?
81 | var timeOfLastKeypress : NSDate?
82 |
83 | var wasDragging : Bool = false
84 |
85 | var setOfHeldButtons = NSMutableSet()
86 | var setOfPreviouslyHeldButtons = NSSet()
87 | var hasPotentialScroll = false
88 | var isScrolling = false
89 | var scrollTimer : NSTimer?
90 | var scrollUp = false
91 |
92 | var interpTimer : NSTimer?
93 | let steps : Double = 15.0
94 |
95 | var isScrollingTimer : NSTimer?
96 |
97 | var delayedMoveTimer : NSTimer?
98 |
99 | let scrollDelay = 0.1
100 |
101 | var scrollEventStarted = false
102 | var scrollEventContinued = false
103 | var isMoving = false
104 |
105 | class Whatever : NSObject {
106 | func touchingFinished() {
107 | isTouchingTimer?.invalidate()
108 | isTouchingTimer = nil
109 |
110 | lastKeyCode = nil
111 | timeOfLastKeypress = nil
112 |
113 | delayedMoveTimer?.invalidate()
114 | delayedMoveTimer = nil
115 |
116 | scrollEventStarted = false
117 | scrollEventContinued = false
118 | isMoving = false
119 | }
120 |
121 | func scrollingFinished() {
122 | isScrollingTimer = nil
123 | }
124 |
125 | func lClick() {
126 | leftClick()
127 | }
128 |
129 | func rClick() {
130 | rightClick()
131 | }
132 |
133 | func interpTimerCallback(timer : NSTimer) {
134 | let userInfo = timer.userInfo as! [String: Double]
135 | let iter = userInfo["iteration"]!
136 |
137 | if (iter > steps) {
138 | // stop iteration
139 | return
140 | }
141 |
142 | let interval = userInfo["interval"]!
143 | let dx = userInfo["dx"]!
144 | let dy = userInfo["dy"]!
145 | let fromX = userInfo["fromX"]!
146 | let fromY = userInfo["fromY"]!
147 | let dt = interval * iter
148 | let totalTime = interval * steps
149 |
150 | let t = dt / totalTime
151 |
152 | let newX = lerp(fromX, d: dx, t: t)
153 | let newY = lerp(fromY, d: dy, t: t)
154 |
155 | moveMouse(to: CGPoint(x: newX, y: newY))
156 |
157 | interpTimer = NSTimer.scheduledTimerWithTimeInterval(interval, target: whatever, selector: "interpTimerCallback:", userInfo: [
158 | "iteration": iter + 1,
159 | "interval": interval,
160 | "dx": dx,
161 | "dy": dy,
162 | "fromX": fromX,
163 | "fromY": fromY
164 | ], repeats: false)
165 | }
166 |
167 | func interpolateScroll(timer : NSTimer) {
168 | let userInfo = timer.userInfo as! [String: Double]
169 | let iter = userInfo["iteration"]!
170 |
171 | if (iter > steps) {
172 | // stop iteration
173 | return
174 | }
175 |
176 | let interval = userInfo["interval"]!
177 | let dy = userInfo["dy"]!
178 | let dt = interval * iter
179 | let totalTime = interval * steps
180 |
181 | let direction = userInfo["direction"]! > 0
182 |
183 | let t = dt / totalTime
184 |
185 | let newY = lerp(0, d: dy, t: t)
186 |
187 | scroll(newY, direction: direction)
188 |
189 | interpTimer = NSTimer.scheduledTimerWithTimeInterval(interval, target: whatever, selector: "interpolateScroll:", userInfo: [
190 | "iteration": iter + 1,
191 | "interval": interval,
192 | "dy": dy,
193 | "direction": direction
194 | ], repeats: false)
195 | }
196 |
197 | func delayedMoveTimerCallback(timer : NSTimer) {
198 | isMoving = true
199 | // let p = timer.userInfo as! [Int]
200 | // smoothMoveMouse(by: p)
201 | }
202 | }
203 |
204 | let whatever = Whatever()
205 |
206 | func lerp(a : Double, d: Double, t : Double) -> Double {
207 | return a + d * t
208 | }
209 |
210 | func interpolateBetweenPoints(from from: CGPoint, to: CGPoint) {
211 | let deltaX = to.x - from.x
212 | let deltaY = to.y - from.y
213 |
214 | let totalTime = 0.08
215 |
216 | interpTimer?.invalidate()
217 | interpTimer = NSTimer.scheduledTimerWithTimeInterval(totalTime / steps, target: whatever, selector: "interpTimerCallback:", userInfo: [
218 | "iteration": 0,
219 | "interval": totalTime / steps,
220 | "dx": deltaX,
221 | "dy": deltaY,
222 | "fromX": from.x,
223 | "fromY": from.y
224 | ], repeats: false)
225 | }
226 |
227 | func interpolateScroll(amt : Double, direction : Double) {
228 |
229 | let totalTime = 0.4
230 |
231 | interpTimer?.invalidate()
232 | interpTimer = NSTimer.scheduledTimerWithTimeInterval(totalTime / steps, target: whatever, selector: "interpolateScroll:", userInfo: [
233 | "iteration": 0,
234 | "interval": totalTime / steps,
235 | "dy": amt,
236 | "direction": direction
237 | ], repeats: false)
238 | }
239 |
240 | func distanceFromLast(keyCode : Int64) -> [Int] {
241 | // computes the distance with (0,0) at top left
242 | guard let lastKey = lastKeyCode else {
243 | return [0, 0]
244 | }
245 |
246 | let location = POSITIONS[keyCode]!
247 | let lastLocation = POSITIONS[lastKey]!
248 | let r = [location[0] - lastLocation[0], location[1] - lastLocation[1]]
249 | return r
250 | }
251 |
252 | func modifyValue(v : Double, forTime time : Double) -> Double {
253 | let s = -12.5 * time + 4
254 | return v * s
255 | }
256 |
257 | func onShiftKeyDown(keyCode : Int64) {
258 |
259 | if let _ = isScrollingTimer {
260 | // only trigger this block if it's the nth key we've touched in a row
261 |
262 | // deltaT for keyDown events calculations
263 | var dt = 0.0
264 | if let tl = timeOfLastKeypress {
265 | dt = NSDate().timeIntervalSinceDate(tl)
266 | }
267 |
268 | let d = distanceFromLast(keyCode)
269 | let direction = d[1] < 0
270 | let scrollAmt = modifyValue(abs(Double(d[1])/2.0), forTime: dt)
271 | smoothScroll(scrollAmt, direction: direction ? 1.0 : -1.0)
272 | }
273 |
274 | lastKeyCode = keyCode
275 | timeOfLastKeypress = NSDate()
276 |
277 | isScrollingTimer?.invalidate()
278 | isScrollingTimer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: whatever, selector: "scrollingFinished", userInfo: nil, repeats: false)
279 |
280 | }
281 |
282 | func onShiftKeyUp(keyCode : Int64) {
283 |
284 | }
285 |
286 | func onKeyDown(keyCode : Int64) {
287 | setOfHeldButtons.addObject(NSNumber(longLong: keyCode))
288 |
289 | if let _ = isTouchingTimer {
290 | // only trigger this block if it's the nth key we've touched in a row
291 |
292 | // deltaT for keyDown events calculations
293 | var dt = 0.0
294 | if let tl = timeOfLastKeypress {
295 | dt = NSDate().timeIntervalSinceDate(tl)
296 | }
297 |
298 | // print(keyCode, dt, setOfHeldButtons.count)
299 | let d = distanceFromLast(keyCode)
300 | let nd = [
301 | Int(modifyValue(Double(d[0]), forTime: dt)),
302 | Int(modifyValue(Double(d[1]), forTime: dt))
303 | ]
304 |
305 | isMoving = true
306 | smoothMoveMouse(by: nd)
307 | } else {
308 | isTouchingTimer?.invalidate()
309 | isTouchingTimer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: whatever, selector: "touchingFinished", userInfo: nil, repeats: false)
310 | }
311 |
312 | lastKeyCode = keyCode
313 | timeOfLastKeypress = NSDate()
314 | // reset the isTouching and keyUp timers every time we get a keyDown
315 | keyUpTimer?.invalidate()
316 | keyUpTimer = nil
317 |
318 | }
319 |
320 | func onKeyUp(keyCode : Int64) {
321 | setOfHeldButtons.removeObject(NSNumber(longLong: keyCode))
322 |
323 | if !isMoving {
324 | // if we're not dragging, we care about clicks
325 | // just in case, create a timer that's invalidated if the user clicks down before the timeout
326 | keyUpTimer?.invalidate()
327 | if LEFT_KEYS.contains(keyCode) {
328 | keyUpTimer = NSTimer.scheduledTimerWithTimeInterval(0.31, target: whatever, selector: "lClick", userInfo: nil, repeats: false)
329 | } else {
330 | keyUpTimer = NSTimer.scheduledTimerWithTimeInterval(0.31, target: whatever, selector: "rClick", userInfo: nil, repeats: false)
331 | }
332 | } else {
333 | isTouchingTimer?.invalidate()
334 | isTouchingTimer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: whatever, selector: "touchingFinished", userInfo: nil, repeats: false)
335 | }
336 |
337 | }
338 |
339 |
340 |
341 |
342 |
343 | /****
344 |
345 | EVENT FUNCTIONS
346 |
347 | ****/
348 |
349 | func smoothMoveMouse(by by : [Int]) {
350 | let currentLocation = NSEvent.mouseLocation()
351 | let newX = currentLocation.x + CGFloat(by[0])
352 | let newY = currentLocation.y - CGFloat(by[1])
353 |
354 | interpolateBetweenPoints(from: currentLocation, to: CGPoint(x: newX, y: newY))
355 | }
356 |
357 | func smoothScroll(amt : Double, direction : Double) {
358 | interpolateScroll(amt, direction: direction)
359 | }
360 |
361 | func moveMouse(by by: [Int]) {
362 |
363 | let currentLocation = NSEvent.mouseLocation()
364 | let newX = currentLocation.x + CGFloat(by[0])
365 | // invert to use origin at bottom left
366 | let newY = (NSScreen.mainScreen()?.frame.size.height)! - (currentLocation.y - CGFloat(by[1]))
367 | let move = CGEventCreateMouseEvent(
368 | nil,
369 | CGEventType.MouseMoved,
370 | CGPoint(x: newX, y: newY),
371 | CGMouseButton.Left
372 | )
373 | CGEventPost(CGEventTapLocation.CGHIDEventTap, move)
374 | }
375 |
376 | func moveMouse(to to: CGPoint) {
377 | // lol global coordinates
378 | let newTo = CGPoint(x: to.x, y: (NSScreen.mainScreen()?.frame.size.height)! - to.y)
379 | let move = CGEventCreateMouseEvent(
380 | nil,
381 | CGEventType.MouseMoved,
382 | newTo,
383 | CGMouseButton.Left
384 | )
385 | CGEventPost(CGEventTapLocation.CGHIDEventTap, move)
386 | }
387 |
388 | func scroll(amt: Double, direction : Bool) {
389 | let scrollAmt = amt * (direction ? 1 : -1)
390 | let move = ScrollUtils.createScrollEventWithScrollAmount(Int32(scrollAmt)).takeRetainedValue() as CGEvent
391 | CGEventPost(CGEventTapLocation.CGHIDEventTap, move)
392 | }
393 |
394 | func leftDown() {
395 | let down = CGEventCreateMouseEvent(
396 | nil,
397 | CGEventType.LeftMouseDown,
398 | CGPoint(x: NSEvent.mouseLocation().x, y: (NSScreen.mainScreen()?.frame.size.height)! - NSEvent.mouseLocation().y),
399 | CGMouseButton.Left
400 | )
401 | CGEventPost(CGEventTapLocation.CGHIDEventTap, down)
402 | }
403 |
404 | func leftUp() {
405 | let up = CGEventCreateMouseEvent(
406 | nil,
407 | CGEventType.LeftMouseUp,
408 | CGPoint(x: NSEvent.mouseLocation().x, y: (NSScreen.mainScreen()?.frame.size.height)! - NSEvent.mouseLocation().y),
409 | CGMouseButton.Left
410 | )
411 | CGEventPost(CGEventTapLocation.CGHIDEventTap, up)
412 | }
413 |
414 | func leftClick() {
415 | leftDown()
416 | leftUp()
417 | }
418 |
419 | func leftDrag(to to : CGPoint) {
420 | let drag = CGEventCreateMouseEvent(
421 | nil,
422 | CGEventType.LeftMouseDragged,
423 | to,
424 | CGMouseButton.Left
425 | )
426 | CGEventPost(CGEventTapLocation.CGHIDEventTap, drag)
427 | }
428 |
429 | func rightDown() {
430 | let down = CGEventCreateMouseEvent(
431 | nil,
432 | CGEventType.RightMouseDown,
433 | CGPoint(x: NSEvent.mouseLocation().x, y: (NSScreen.mainScreen()?.frame.size.height)! - NSEvent.mouseLocation().y),
434 | CGMouseButton.Right
435 | )
436 | CGEventPost(CGEventTapLocation.CGHIDEventTap, down)
437 | }
438 |
439 | func rightUp() {
440 | let up = CGEventCreateMouseEvent(
441 | nil,
442 | CGEventType.RightMouseUp,
443 | CGPoint(x: NSEvent.mouseLocation().x, y: (NSScreen.mainScreen()?.frame.size.height)! - NSEvent.mouseLocation().y),
444 | CGMouseButton.Right
445 | )
446 | CGEventPost(CGEventTapLocation.CGHIDEventTap, up)
447 | }
448 |
449 | func rightClick() {
450 | print("rightClick")
451 | rightDown()
452 | rightUp()
453 | }
454 |
455 | @NSApplicationMain
456 | class AppDelegate: NSObject, NSApplicationDelegate {
457 |
458 | @IBOutlet weak var window: NSWindow!
459 |
460 | var eventTap : CFMachPort?
461 | let w = whatever
462 |
463 | func applicationDidFinishLaunching(aNotification: NSNotification) {
464 |
465 | let eventMask = (1 << CGEventType.KeyDown.rawValue) |
466 | (1 << CGEventType.KeyUp.rawValue) |
467 | (1 << CGEventType.LeftMouseDown.rawValue) |
468 | (1 << CGEventType.LeftMouseUp.rawValue) |
469 | (1 << CGEventType.MouseMoved.rawValue) |
470 | (1 << CGEventType.RightMouseDown.rawValue) |
471 | (1 << CGEventType.RightMouseUp.rawValue) |
472 | (1 << CGEventType.LeftMouseDragged.rawValue) |
473 | (1 << CGEventType.ScrollWheel.rawValue)
474 |
475 | guard let eventTap = CGEventTapCreate(
476 | .CGHIDEventTap,
477 | .HeadInsertEventTap,
478 | .Default,
479 | CGEventMask(eventMask),
480 | { (proxy : CGEventTapProxy, type : CGEventType, event : CGEvent, userInfo : UnsafeMutablePointer) -> Unmanaged? in
481 |
482 | let ctrlKeyHeld = (CGEventGetFlags(event).rawValue & CGEventFlags.MaskControl.rawValue) > 0;
483 | let shiftKeyHeld = (CGEventGetFlags(event).rawValue & CGEventFlags.MaskAlternate.rawValue) > 0;
484 |
485 | if ((ctrlKeyHeld || shiftKeyHeld) && CGEventGetIntegerValueField(event, .KeyboardEventAutorepeat) == 0) {
486 | // ctrl key and not an autorepeat
487 | let keyCode = CGEventGetIntegerValueField(event, .KeyboardEventKeycode)
488 |
489 | if (ctrlKeyHeld) {
490 | if type == .KeyDown {
491 | onKeyDown(keyCode)
492 | }
493 |
494 | if type == .KeyUp {
495 | onKeyUp(keyCode)
496 | }
497 | }
498 |
499 | if (shiftKeyHeld) {
500 | if type == .KeyDown {
501 | onShiftKeyDown(keyCode)
502 | }
503 |
504 | if type == .KeyUp {
505 | onShiftKeyUp(keyCode)
506 | }
507 | }
508 |
509 | if [.LeftMouseDown, .LeftMouseUp, .RightMouseDown, .RightMouseUp, .MouseMoved, .LeftMouseDragged, .ScrollWheel].contains(type) {
510 | CGEventSetFlags(event, CGEventFlags(rawValue: 0)!)
511 | return Unmanaged.passRetained(event)
512 | }
513 |
514 | return nil
515 | }
516 | return Unmanaged.passRetained(event)
517 | },
518 | nil) else {
519 | print("FAILED");
520 | exit(1)
521 | }
522 |
523 | let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
524 | CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes)
525 | CGEventTapEnable(eventTap, true)
526 | CFRunLoopRun()
527 |
528 | }
529 |
530 |
531 |
532 | func applicationWillTerminate(aNotification: NSNotification) {
533 | // Insert code here to tear down your application
534 | }
535 |
536 |
537 | }
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
--------------------------------------------------------------------------------
/asdfghjkl.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | C935D0291B9AC16400D8E9AC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C935D0281B9AC16400D8E9AC /* AppDelegate.swift */; };
11 | C935D02B1B9AC16400D8E9AC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C935D02A1B9AC16400D8E9AC /* Images.xcassets */; };
12 | C935D02E1B9AC16400D8E9AC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = C935D02C1B9AC16400D8E9AC /* MainMenu.xib */; };
13 | C935D03A1B9AC16400D8E9AC /* asdfghjklTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C935D0391B9AC16400D8E9AC /* asdfghjklTests.swift */; };
14 | C935D0441B9AC1C700D8E9AC /* bat27.png in Resources */ = {isa = PBXBuildFile; fileRef = C935D0431B9AC1C700D8E9AC /* bat27.png */; };
15 | C95632251B9C1C24003F8DE3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C95632241B9C1C24003F8DE3 /* CoreGraphics.framework */; };
16 | C95632281B9C1C5F003F8DE3 /* ScrollUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = C95632271B9C1C5F003F8DE3 /* ScrollUtils.m */; settings = {ASSET_TAGS = (); }; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | C935D0341B9AC16400D8E9AC /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = C935D01B1B9AC16400D8E9AC /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = C935D0221B9AC16400D8E9AC;
25 | remoteInfo = asdfghjkl;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXFileReference section */
30 | C935D0231B9AC16400D8E9AC /* asdfghjkl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = asdfghjkl.app; sourceTree = BUILT_PRODUCTS_DIR; };
31 | C935D0271B9AC16400D8E9AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | C935D0281B9AC16400D8E9AC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
33 | C935D02A1B9AC16400D8E9AC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
34 | C935D02D1B9AC16400D8E9AC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
35 | C935D0331B9AC16400D8E9AC /* asdfghjklTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = asdfghjklTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
36 | C935D0381B9AC16400D8E9AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | C935D0391B9AC16400D8E9AC /* asdfghjklTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = asdfghjklTests.swift; sourceTree = ""; };
38 | C935D0431B9AC1C700D8E9AC /* bat27.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bat27.png; sourceTree = ""; };
39 | C95632211B9C1B4F003F8DE3 /* asdfghjkl-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "asdfghjkl-Bridging-Header.h"; sourceTree = ""; };
40 | C95632241B9C1C24003F8DE3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
41 | C95632261B9C1C5F003F8DE3 /* ScrollUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollUtils.h; sourceTree = ""; };
42 | C95632271B9C1C5F003F8DE3 /* ScrollUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScrollUtils.m; sourceTree = ""; };
43 | /* End PBXFileReference section */
44 |
45 | /* Begin PBXFrameworksBuildPhase section */
46 | C935D0201B9AC16400D8E9AC /* Frameworks */ = {
47 | isa = PBXFrameworksBuildPhase;
48 | buildActionMask = 2147483647;
49 | files = (
50 | C95632251B9C1C24003F8DE3 /* CoreGraphics.framework in Frameworks */,
51 | );
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | C935D0301B9AC16400D8E9AC /* Frameworks */ = {
55 | isa = PBXFrameworksBuildPhase;
56 | buildActionMask = 2147483647;
57 | files = (
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | C935D01A1B9AC16400D8E9AC = {
65 | isa = PBXGroup;
66 | children = (
67 | C95632241B9C1C24003F8DE3 /* CoreGraphics.framework */,
68 | C935D0251B9AC16400D8E9AC /* asdfghjkl */,
69 | C935D0361B9AC16400D8E9AC /* asdfghjklTests */,
70 | C935D0241B9AC16400D8E9AC /* Products */,
71 | );
72 | sourceTree = "";
73 | };
74 | C935D0241B9AC16400D8E9AC /* Products */ = {
75 | isa = PBXGroup;
76 | children = (
77 | C935D0231B9AC16400D8E9AC /* asdfghjkl.app */,
78 | C935D0331B9AC16400D8E9AC /* asdfghjklTests.xctest */,
79 | );
80 | name = Products;
81 | sourceTree = "";
82 | };
83 | C935D0251B9AC16400D8E9AC /* asdfghjkl */ = {
84 | isa = PBXGroup;
85 | children = (
86 | C935D0281B9AC16400D8E9AC /* AppDelegate.swift */,
87 | C935D02A1B9AC16400D8E9AC /* Images.xcassets */,
88 | C935D02C1B9AC16400D8E9AC /* MainMenu.xib */,
89 | C935D0261B9AC16400D8E9AC /* Supporting Files */,
90 | C95632211B9C1B4F003F8DE3 /* asdfghjkl-Bridging-Header.h */,
91 | C95632261B9C1C5F003F8DE3 /* ScrollUtils.h */,
92 | C95632271B9C1C5F003F8DE3 /* ScrollUtils.m */,
93 | );
94 | path = asdfghjkl;
95 | sourceTree = "";
96 | };
97 | C935D0261B9AC16400D8E9AC /* Supporting Files */ = {
98 | isa = PBXGroup;
99 | children = (
100 | C935D0431B9AC1C700D8E9AC /* bat27.png */,
101 | C935D0271B9AC16400D8E9AC /* Info.plist */,
102 | );
103 | name = "Supporting Files";
104 | sourceTree = "";
105 | };
106 | C935D0361B9AC16400D8E9AC /* asdfghjklTests */ = {
107 | isa = PBXGroup;
108 | children = (
109 | C935D0391B9AC16400D8E9AC /* asdfghjklTests.swift */,
110 | C935D0371B9AC16400D8E9AC /* Supporting Files */,
111 | );
112 | path = asdfghjklTests;
113 | sourceTree = "";
114 | };
115 | C935D0371B9AC16400D8E9AC /* Supporting Files */ = {
116 | isa = PBXGroup;
117 | children = (
118 | C935D0381B9AC16400D8E9AC /* Info.plist */,
119 | );
120 | name = "Supporting Files";
121 | sourceTree = "";
122 | };
123 | /* End PBXGroup section */
124 |
125 | /* Begin PBXNativeTarget section */
126 | C935D0221B9AC16400D8E9AC /* asdfghjkl */ = {
127 | isa = PBXNativeTarget;
128 | buildConfigurationList = C935D03D1B9AC16400D8E9AC /* Build configuration list for PBXNativeTarget "asdfghjkl" */;
129 | buildPhases = (
130 | C935D01F1B9AC16400D8E9AC /* Sources */,
131 | C935D0201B9AC16400D8E9AC /* Frameworks */,
132 | C935D0211B9AC16400D8E9AC /* Resources */,
133 | );
134 | buildRules = (
135 | );
136 | dependencies = (
137 | );
138 | name = asdfghjkl;
139 | productName = asdfghjkl;
140 | productReference = C935D0231B9AC16400D8E9AC /* asdfghjkl.app */;
141 | productType = "com.apple.product-type.application";
142 | };
143 | C935D0321B9AC16400D8E9AC /* asdfghjklTests */ = {
144 | isa = PBXNativeTarget;
145 | buildConfigurationList = C935D0401B9AC16400D8E9AC /* Build configuration list for PBXNativeTarget "asdfghjklTests" */;
146 | buildPhases = (
147 | C935D02F1B9AC16400D8E9AC /* Sources */,
148 | C935D0301B9AC16400D8E9AC /* Frameworks */,
149 | C935D0311B9AC16400D8E9AC /* Resources */,
150 | );
151 | buildRules = (
152 | );
153 | dependencies = (
154 | C935D0351B9AC16400D8E9AC /* PBXTargetDependency */,
155 | );
156 | name = asdfghjklTests;
157 | productName = asdfghjklTests;
158 | productReference = C935D0331B9AC16400D8E9AC /* asdfghjklTests.xctest */;
159 | productType = "com.apple.product-type.bundle.unit-test";
160 | };
161 | /* End PBXNativeTarget section */
162 |
163 | /* Begin PBXProject section */
164 | C935D01B1B9AC16400D8E9AC /* Project object */ = {
165 | isa = PBXProject;
166 | attributes = {
167 | LastSwiftMigration = 0700;
168 | LastSwiftUpdateCheck = 0700;
169 | LastUpgradeCheck = 0700;
170 | ORGANIZATIONNAME = mattc;
171 | TargetAttributes = {
172 | C935D0221B9AC16400D8E9AC = {
173 | CreatedOnToolsVersion = 6.4;
174 | };
175 | C935D0321B9AC16400D8E9AC = {
176 | CreatedOnToolsVersion = 6.4;
177 | TestTargetID = C935D0221B9AC16400D8E9AC;
178 | };
179 | };
180 | };
181 | buildConfigurationList = C935D01E1B9AC16400D8E9AC /* Build configuration list for PBXProject "asdfghjkl" */;
182 | compatibilityVersion = "Xcode 3.2";
183 | developmentRegion = English;
184 | hasScannedForEncodings = 0;
185 | knownRegions = (
186 | en,
187 | Base,
188 | );
189 | mainGroup = C935D01A1B9AC16400D8E9AC;
190 | productRefGroup = C935D0241B9AC16400D8E9AC /* Products */;
191 | projectDirPath = "";
192 | projectRoot = "";
193 | targets = (
194 | C935D0221B9AC16400D8E9AC /* asdfghjkl */,
195 | C935D0321B9AC16400D8E9AC /* asdfghjklTests */,
196 | );
197 | };
198 | /* End PBXProject section */
199 |
200 | /* Begin PBXResourcesBuildPhase section */
201 | C935D0211B9AC16400D8E9AC /* Resources */ = {
202 | isa = PBXResourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | C935D0441B9AC1C700D8E9AC /* bat27.png in Resources */,
206 | C935D02B1B9AC16400D8E9AC /* Images.xcassets in Resources */,
207 | C935D02E1B9AC16400D8E9AC /* MainMenu.xib in Resources */,
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | };
211 | C935D0311B9AC16400D8E9AC /* Resources */ = {
212 | isa = PBXResourcesBuildPhase;
213 | buildActionMask = 2147483647;
214 | files = (
215 | );
216 | runOnlyForDeploymentPostprocessing = 0;
217 | };
218 | /* End PBXResourcesBuildPhase section */
219 |
220 | /* Begin PBXSourcesBuildPhase section */
221 | C935D01F1B9AC16400D8E9AC /* Sources */ = {
222 | isa = PBXSourcesBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | C95632281B9C1C5F003F8DE3 /* ScrollUtils.m in Sources */,
226 | C935D0291B9AC16400D8E9AC /* AppDelegate.swift in Sources */,
227 | );
228 | runOnlyForDeploymentPostprocessing = 0;
229 | };
230 | C935D02F1B9AC16400D8E9AC /* Sources */ = {
231 | isa = PBXSourcesBuildPhase;
232 | buildActionMask = 2147483647;
233 | files = (
234 | C935D03A1B9AC16400D8E9AC /* asdfghjklTests.swift in Sources */,
235 | );
236 | runOnlyForDeploymentPostprocessing = 0;
237 | };
238 | /* End PBXSourcesBuildPhase section */
239 |
240 | /* Begin PBXTargetDependency section */
241 | C935D0351B9AC16400D8E9AC /* PBXTargetDependency */ = {
242 | isa = PBXTargetDependency;
243 | target = C935D0221B9AC16400D8E9AC /* asdfghjkl */;
244 | targetProxy = C935D0341B9AC16400D8E9AC /* PBXContainerItemProxy */;
245 | };
246 | /* End PBXTargetDependency section */
247 |
248 | /* Begin PBXVariantGroup section */
249 | C935D02C1B9AC16400D8E9AC /* MainMenu.xib */ = {
250 | isa = PBXVariantGroup;
251 | children = (
252 | C935D02D1B9AC16400D8E9AC /* Base */,
253 | );
254 | name = MainMenu.xib;
255 | sourceTree = "";
256 | };
257 | /* End PBXVariantGroup section */
258 |
259 | /* Begin XCBuildConfiguration section */
260 | C935D03B1B9AC16400D8E9AC /* Debug */ = {
261 | isa = XCBuildConfiguration;
262 | buildSettings = {
263 | ALWAYS_SEARCH_USER_PATHS = NO;
264 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
265 | CLANG_CXX_LIBRARY = "libc++";
266 | CLANG_ENABLE_MODULES = YES;
267 | CLANG_ENABLE_OBJC_ARC = YES;
268 | CLANG_WARN_BOOL_CONVERSION = YES;
269 | CLANG_WARN_CONSTANT_CONVERSION = YES;
270 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
271 | CLANG_WARN_EMPTY_BODY = YES;
272 | CLANG_WARN_ENUM_CONVERSION = YES;
273 | CLANG_WARN_INT_CONVERSION = YES;
274 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
275 | CLANG_WARN_UNREACHABLE_CODE = YES;
276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
277 | CODE_SIGN_IDENTITY = "-";
278 | COPY_PHASE_STRIP = NO;
279 | DEBUG_INFORMATION_FORMAT = dwarf;
280 | ENABLE_STRICT_OBJC_MSGSEND = YES;
281 | ENABLE_TESTABILITY = YES;
282 | GCC_C_LANGUAGE_STANDARD = gnu99;
283 | GCC_DYNAMIC_NO_PIC = NO;
284 | GCC_NO_COMMON_BLOCKS = YES;
285 | GCC_OPTIMIZATION_LEVEL = 0;
286 | GCC_PREPROCESSOR_DEFINITIONS = (
287 | "DEBUG=1",
288 | "$(inherited)",
289 | );
290 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
291 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
292 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
293 | GCC_WARN_UNDECLARED_SELECTOR = YES;
294 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
295 | GCC_WARN_UNUSED_FUNCTION = YES;
296 | GCC_WARN_UNUSED_VARIABLE = YES;
297 | MACOSX_DEPLOYMENT_TARGET = 10.10;
298 | MTL_ENABLE_DEBUG_INFO = YES;
299 | ONLY_ACTIVE_ARCH = YES;
300 | SDKROOT = macosx;
301 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
302 | };
303 | name = Debug;
304 | };
305 | C935D03C1B9AC16400D8E9AC /* Release */ = {
306 | isa = XCBuildConfiguration;
307 | buildSettings = {
308 | ALWAYS_SEARCH_USER_PATHS = NO;
309 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
310 | CLANG_CXX_LIBRARY = "libc++";
311 | CLANG_ENABLE_MODULES = YES;
312 | CLANG_ENABLE_OBJC_ARC = YES;
313 | CLANG_WARN_BOOL_CONVERSION = YES;
314 | CLANG_WARN_CONSTANT_CONVERSION = YES;
315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
316 | CLANG_WARN_EMPTY_BODY = YES;
317 | CLANG_WARN_ENUM_CONVERSION = YES;
318 | CLANG_WARN_INT_CONVERSION = YES;
319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
320 | CLANG_WARN_UNREACHABLE_CODE = YES;
321 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
322 | CODE_SIGN_IDENTITY = "-";
323 | COPY_PHASE_STRIP = NO;
324 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
325 | ENABLE_NS_ASSERTIONS = NO;
326 | ENABLE_STRICT_OBJC_MSGSEND = YES;
327 | GCC_C_LANGUAGE_STANDARD = gnu99;
328 | GCC_NO_COMMON_BLOCKS = YES;
329 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
330 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
331 | GCC_WARN_UNDECLARED_SELECTOR = YES;
332 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
333 | GCC_WARN_UNUSED_FUNCTION = YES;
334 | GCC_WARN_UNUSED_VARIABLE = YES;
335 | MACOSX_DEPLOYMENT_TARGET = 10.10;
336 | MTL_ENABLE_DEBUG_INFO = NO;
337 | SDKROOT = macosx;
338 | };
339 | name = Release;
340 | };
341 | C935D03E1B9AC16400D8E9AC /* Debug */ = {
342 | isa = XCBuildConfiguration;
343 | buildSettings = {
344 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
345 | CLANG_ENABLE_MODULES = YES;
346 | COMBINE_HIDPI_IMAGES = YES;
347 | INFOPLIST_FILE = asdfghjkl/Info.plist;
348 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
349 | PRODUCT_BUNDLE_IDENTIFIER = "mat.tc.$(PRODUCT_NAME:rfc1034identifier)";
350 | PRODUCT_NAME = "$(TARGET_NAME)";
351 | SWIFT_OBJC_BRIDGING_HEADER = "asdfghjkl/asdfghjkl-Bridging-Header.h";
352 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
353 | };
354 | name = Debug;
355 | };
356 | C935D03F1B9AC16400D8E9AC /* Release */ = {
357 | isa = XCBuildConfiguration;
358 | buildSettings = {
359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
360 | CLANG_ENABLE_MODULES = YES;
361 | COMBINE_HIDPI_IMAGES = YES;
362 | INFOPLIST_FILE = asdfghjkl/Info.plist;
363 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
364 | PRODUCT_BUNDLE_IDENTIFIER = "mat.tc.$(PRODUCT_NAME:rfc1034identifier)";
365 | PRODUCT_NAME = "$(TARGET_NAME)";
366 | SWIFT_OBJC_BRIDGING_HEADER = "asdfghjkl/asdfghjkl-Bridging-Header.h";
367 | };
368 | name = Release;
369 | };
370 | C935D0411B9AC16400D8E9AC /* Debug */ = {
371 | isa = XCBuildConfiguration;
372 | buildSettings = {
373 | BUNDLE_LOADER = "$(TEST_HOST)";
374 | COMBINE_HIDPI_IMAGES = YES;
375 | FRAMEWORK_SEARCH_PATHS = (
376 | "$(DEVELOPER_FRAMEWORKS_DIR)",
377 | "$(inherited)",
378 | );
379 | GCC_PREPROCESSOR_DEFINITIONS = (
380 | "DEBUG=1",
381 | "$(inherited)",
382 | );
383 | INFOPLIST_FILE = asdfghjklTests/Info.plist;
384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
385 | PRODUCT_BUNDLE_IDENTIFIER = "mat.tc.$(PRODUCT_NAME:rfc1034identifier)";
386 | PRODUCT_NAME = "$(TARGET_NAME)";
387 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/asdfghjkl.app/Contents/MacOS/asdfghjkl";
388 | };
389 | name = Debug;
390 | };
391 | C935D0421B9AC16400D8E9AC /* Release */ = {
392 | isa = XCBuildConfiguration;
393 | buildSettings = {
394 | BUNDLE_LOADER = "$(TEST_HOST)";
395 | COMBINE_HIDPI_IMAGES = YES;
396 | FRAMEWORK_SEARCH_PATHS = (
397 | "$(DEVELOPER_FRAMEWORKS_DIR)",
398 | "$(inherited)",
399 | );
400 | INFOPLIST_FILE = asdfghjklTests/Info.plist;
401 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
402 | PRODUCT_BUNDLE_IDENTIFIER = "mat.tc.$(PRODUCT_NAME:rfc1034identifier)";
403 | PRODUCT_NAME = "$(TARGET_NAME)";
404 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/asdfghjkl.app/Contents/MacOS/asdfghjkl";
405 | };
406 | name = Release;
407 | };
408 | /* End XCBuildConfiguration section */
409 |
410 | /* Begin XCConfigurationList section */
411 | C935D01E1B9AC16400D8E9AC /* Build configuration list for PBXProject "asdfghjkl" */ = {
412 | isa = XCConfigurationList;
413 | buildConfigurations = (
414 | C935D03B1B9AC16400D8E9AC /* Debug */,
415 | C935D03C1B9AC16400D8E9AC /* Release */,
416 | );
417 | defaultConfigurationIsVisible = 0;
418 | defaultConfigurationName = Release;
419 | };
420 | C935D03D1B9AC16400D8E9AC /* Build configuration list for PBXNativeTarget "asdfghjkl" */ = {
421 | isa = XCConfigurationList;
422 | buildConfigurations = (
423 | C935D03E1B9AC16400D8E9AC /* Debug */,
424 | C935D03F1B9AC16400D8E9AC /* Release */,
425 | );
426 | defaultConfigurationIsVisible = 0;
427 | defaultConfigurationName = Release;
428 | };
429 | C935D0401B9AC16400D8E9AC /* Build configuration list for PBXNativeTarget "asdfghjklTests" */ = {
430 | isa = XCConfigurationList;
431 | buildConfigurations = (
432 | C935D0411B9AC16400D8E9AC /* Debug */,
433 | C935D0421B9AC16400D8E9AC /* Release */,
434 | );
435 | defaultConfigurationIsVisible = 0;
436 | defaultConfigurationName = Release;
437 | };
438 | /* End XCConfigurationList section */
439 | };
440 | rootObject = C935D01B1B9AC16400D8E9AC /* Project object */;
441 | }
442 |
--------------------------------------------------------------------------------