├── .gitignore ├── DoctorDark-GUI ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── MainMenu.xib ├── Info.plist └── main.m ├── DoctorDark.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── w0lf.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── w0lf.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── DoctorDark-GUI.xcscheme │ ├── DoctorDark.xcscheme │ └── xcschememanagement.plist ├── DoctorDark ├── DoctorDark.m └── Info.plist ├── README.md ├── ZKSwizzle.h ├── ZKSwizzle.m ├── build ├── DoctorDark-GUI.zip ├── DoctorDark.bundle.zip └── DoctorDark.bundle │ └── Contents │ ├── Info.plist │ ├── MacOS │ └── DoctorDark │ └── _CodeSignature │ └── CodeResources └── preview.png /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ## Build generated 3 | build/ 4 | DerivedData/ 5 | 6 | ## Various settings 7 | *.pbxuser 8 | !default.pbxuser 9 | *.mode1v3 10 | !default.mode1v3 11 | *.mode2v3 12 | !default.mode2v3 13 | *.perspectivev3 14 | !default.perspectivev3 15 | xcuserdata/ 16 | 17 | ## Other 18 | *.moved-aside 19 | *.xccheckout 20 | *.xcscmblueprint 21 | *.DS_Store 22 | -------------------------------------------------------------------------------- /DoctorDark-GUI/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // zestyWin-GUI 4 | // 5 | // Created by Wolfgang Baird on 1/5/16. 6 | // Copyright © 2016 Wolfgang Baird. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @property (weak) IBOutlet NSWindow *mainWindow; 14 | @property (weak) IBOutlet NSView *mainView; 15 | @property (weak) IBOutlet NSButton *swaggA; 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /DoctorDark-GUI/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // zestyWin-GUI 4 | // 5 | // Created by Wolfgang Baird on 1/5/16. 6 | // Copyright © 2016 Wolfgang Baird. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | NSUserDefaults *sharedPrefs; 12 | NSDictionary *sharedDict; 13 | 14 | @interface AppDelegate () 15 | 16 | @property (weak) IBOutlet NSWindow *window; 17 | @end 18 | 19 | @implementation AppDelegate 20 | 21 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication { 22 | return YES; 23 | } 24 | 25 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 26 | // Insert code here to initialize your application 27 | 28 | [self.window setTitle:@"Doctor Dark Blacklister"]; 29 | 30 | // 31 | [self getAPPList]; 32 | [self setScrollView]; 33 | 34 | // display the window 35 | [_mainWindow makeKeyAndOrderFront:nil]; 36 | } 37 | 38 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 39 | // Insert code here to tear down your application 40 | } 41 | 42 | - (void)setScrollView { 43 | // create the scroll view so that it fills the entire window 44 | // to do that we'll grab the frame of the window's contentView 45 | // theWindow is an outlet connected to a window instance in Interface Builder 46 | NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: 47 | [[_mainWindow contentView] frame]]; 48 | 49 | // the scroll view should have both horizontal 50 | // and vertical scrollers 51 | [scrollView setHasVerticalScroller:YES]; 52 | // [scrollView setHasHorizontalScroller:YES]; 53 | 54 | // configure the scroller to have no visible border 55 | [scrollView setBorderType:NSNoBorder]; 56 | 57 | // set the autoresizing mask so that the scroll view will 58 | // resize with the window 59 | [scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; 60 | 61 | // set theImageView as the documentView of the scroll view 62 | [scrollView setDocumentView:_mainView]; 63 | 64 | // scroll to the top 65 | [scrollView.contentView scrollToPoint:NSMakePoint(0, ((NSView*)scrollView.documentView).frame.size.height - scrollView.contentSize.height)]; 66 | 67 | // set the scrollView as the window's contentView 68 | // this replaces the existing contentView and retains 69 | // the scrollView, so we can release it now 70 | // [_mainWindow setContentView:scrollView]; 71 | [[_mainWindow contentView] addSubview:scrollView]; 72 | } 73 | 74 | - (void)readFolder:(NSString *)str :(NSMutableDictionary *)dict { 75 | NSArray *appFolderContents = [[NSArray alloc] init]; 76 | appFolderContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:str error:nil]; 77 | for (NSString *app in appFolderContents) { 78 | if ([app containsString:@".app"]) 79 | { 80 | NSString *appName = [[app lastPathComponent] stringByDeletingPathExtension]; 81 | NSString *appPath = [NSString stringWithFormat:@"%@/%@", str, app]; 82 | NSString *appBundle = [[NSBundle bundleWithPath:appPath] bundleIdentifier]; 83 | // NSLog(@"%@ -- %@", appPath, appBundle); 84 | NSArray *jumboTron = [NSArray arrayWithObjects:appName, appPath, appBundle, nil]; 85 | [dict setObject:jumboTron forKey:appName]; 86 | } 87 | } 88 | } 89 | 90 | - (void)getAPPList { 91 | NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init]; 92 | 93 | [self readFolder:@"/Applications" :myDict]; 94 | [self readFolder:@"/Applications/Utilities" :myDict]; 95 | [self readFolder:@"/System/Library/CoreServices" :myDict]; 96 | [self readFolder:[NSString stringWithFormat:@"%@/Applications", NSHomeDirectory()] :myDict]; 97 | 98 | NSArray *keys = [myDict allKeys]; 99 | NSArray *sortedKeys = [keys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 100 | sortedKeys = [[sortedKeys reverseObjectEnumerator] allObjects]; 101 | 102 | sharedPrefs = [[NSUserDefaults alloc] initWithSuiteName:@"org.w0lf.drdark"]; 103 | sharedDict = [sharedPrefs dictionaryRepresentation]; 104 | 105 | CGRect frame = _mainView.frame; 106 | frame.size.height = 0; 107 | int count = 0; 108 | for (NSString *app in sortedKeys) 109 | { 110 | NSArray *myApp = [myDict valueForKey:app]; 111 | if ([myApp count] == 3) 112 | { 113 | CGRect buttonFrame = CGRectMake(10, (25 * count), 150, 22); 114 | NSButton *newButton = [[NSButton alloc] initWithFrame:buttonFrame]; 115 | [newButton setButtonType:NSSwitchButton]; 116 | [newButton setTitle:[myApp objectAtIndex:0]]; 117 | [newButton sizeToFit]; 118 | [newButton setAction:@selector(toggleItem:)]; 119 | if ([sharedDict valueForKey:[myApp objectAtIndex:2]] == [NSNumber numberWithUnsignedInteger:0]) { 120 | // NSLog(@"\n\nApplication: %@\nBundle ID: %@\n\n", app, bundleString); 121 | [newButton setState:NSOnState]; 122 | } else { 123 | [newButton setState:NSOffState]; 124 | } 125 | [_mainView addSubview:newButton]; 126 | count += 1; 127 | frame.size.height += 25; 128 | } 129 | } 130 | [_mainView setFrame:frame]; 131 | 132 | NSLog(@"%@", myDict); 133 | } 134 | 135 | - (IBAction)toggleItem:(NSButton*)btn { 136 | if ([sharedPrefs isEqual:nil]) 137 | { 138 | sharedPrefs = [[NSUserDefaults alloc] initWithSuiteName:@"org.w0lf.drdark"]; 139 | sharedDict = [sharedPrefs dictionaryRepresentation]; 140 | } 141 | 142 | NSArray *pathS = [NSArray arrayWithObjects:@"/Applications", @"/Applications/Utilities", @"/System/Library/CoreServices", [NSString stringWithFormat:@"%@/Applications", NSHomeDirectory()], nil]; 143 | for (NSString *items in pathS) 144 | { 145 | NSString *fullPath = [NSString stringWithFormat:@"%@/%@.app", items, btn.title]; 146 | // NSLog(@"%@", fullPath); 147 | if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) 148 | { 149 | NSBundle *bundle = [NSBundle bundleWithPath:fullPath]; 150 | NSString *bundleString = [bundle bundleIdentifier]; 151 | 152 | NSLog(@"%@ -- %@", fullPath, bundleString); 153 | 154 | if (btn.state == NSOnState) 155 | { 156 | // Add application to blacklist if it doesn't already exist 157 | NSLog(@"Adding key: %@", bundleString); 158 | [sharedPrefs setInteger:0 forKey:bundleString]; 159 | } else { 160 | NSLog(@"Deleting key: %@", bundleString); 161 | [sharedPrefs setInteger:1 forKey:bundleString]; 162 | } 163 | 164 | [sharedPrefs synchronize]; 165 | break; 166 | } 167 | } 168 | } 169 | 170 | @end 171 | -------------------------------------------------------------------------------- /DoctorDark-GUI/Assets.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 | } -------------------------------------------------------------------------------- /DoctorDark-GUI/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | Default 541 | 542 | 543 | 544 | 545 | 546 | 547 | Left to Right 548 | 549 | 550 | 551 | 552 | 553 | 554 | Right to Left 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | Default 566 | 567 | 568 | 569 | 570 | 571 | 572 | Left to Right 573 | 574 | 575 | 576 | 577 | 578 | 579 | Right to Left 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | -------------------------------------------------------------------------------- /DoctorDark-GUI/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 | 0.1.24 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.1.24 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2016 Wolfgang Baird. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /DoctorDark-GUI/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // zestyWin-GUI 4 | // 5 | // Created by Wolfgang Baird on 1/5/16. 6 | // Copyright © 2016 Wolfgang Baird. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FB520CE81D24A0F600FE378C /* DoctorDark.m in Sources */ = {isa = PBXBuildFile; fileRef = FB520CE61D24A0F600FE378C /* DoctorDark.m */; }; 11 | FB520CF01D24A10100FE378C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FB520CEA1D24A10100FE378C /* Assets.xcassets */; }; 12 | FB520CF21D24A10100FE378C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FB520CED1D24A10100FE378C /* AppDelegate.m */; }; 13 | FB520CF31D24A10100FE378C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FB520CEE1D24A10100FE378C /* main.m */; }; 14 | FB520CF81D24A11F00FE378C /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = FB520CF51D24A10800FE378C /* MainMenu.xib */; }; 15 | FBC27FE71E637D3F00F6516D /* ZKSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = FBC27FE61E637D3F00F6516D /* ZKSwizzle.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | FB16B34C1BA7D821009F455F /* DoctorDark.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DoctorDark.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | FB520CE61D24A0F600FE378C /* DoctorDark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DoctorDark.m; path = DoctorDark/DoctorDark.m; sourceTree = SOURCE_ROOT; }; 21 | FB520CE71D24A0F600FE378C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = DoctorDark/Info.plist; sourceTree = SOURCE_ROOT; }; 22 | FB520CEA1D24A10100FE378C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = "DoctorDark-GUI/Assets.xcassets"; sourceTree = SOURCE_ROOT; }; 23 | FB520CEC1D24A10100FE378C /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = "DoctorDark-GUI/AppDelegate.h"; sourceTree = SOURCE_ROOT; }; 24 | FB520CED1D24A10100FE378C /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = "DoctorDark-GUI/AppDelegate.m"; sourceTree = SOURCE_ROOT; }; 25 | FB520CEE1D24A10100FE378C /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = "DoctorDark-GUI/main.m"; sourceTree = SOURCE_ROOT; }; 26 | FB520CEF1D24A10100FE378C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "DoctorDark-GUI/Info.plist"; sourceTree = SOURCE_ROOT; }; 27 | FB520CF61D24A10800FE378C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "DoctorDark-GUI/Base.lproj/MainMenu.xib"; sourceTree = SOURCE_ROOT; }; 28 | FB61D73E1C3CA27D00FA3C4C /* DoctorDark-GUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DoctorDark-GUI.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | FBC27FE51E637D3F00F6516D /* ZKSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZKSwizzle.h; sourceTree = SOURCE_ROOT; }; 30 | FBC27FE61E637D3F00F6516D /* ZKSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZKSwizzle.m; sourceTree = SOURCE_ROOT; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | FB16B3491BA7D821009F455F /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | FB61D73B1C3CA27D00FA3C4C /* Frameworks */ = { 42 | isa = PBXFrameworksBuildPhase; 43 | buildActionMask = 2147483647; 44 | files = ( 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXFrameworksBuildPhase section */ 49 | 50 | /* Begin PBXGroup section */ 51 | FB16B3431BA7D821009F455F = { 52 | isa = PBXGroup; 53 | children = ( 54 | FB16B34E1BA7D821009F455F /* DoctorDark */, 55 | FB61D73F1C3CA27D00FA3C4C /* DoctorDark-GUI */, 56 | FB16B34D1BA7D821009F455F /* Products */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | FB16B34D1BA7D821009F455F /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | FB16B34C1BA7D821009F455F /* DoctorDark.bundle */, 64 | FB61D73E1C3CA27D00FA3C4C /* DoctorDark-GUI.app */, 65 | ); 66 | name = Products; 67 | sourceTree = ""; 68 | }; 69 | FB16B34E1BA7D821009F455F /* DoctorDark */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | FBC27FE81E637D4B00F6516D /* ZKSwizzle */, 73 | FB520CE61D24A0F600FE378C /* DoctorDark.m */, 74 | FB520CE71D24A0F600FE378C /* Info.plist */, 75 | ); 76 | name = DoctorDark; 77 | sourceTree = ""; 78 | }; 79 | FB61D73F1C3CA27D00FA3C4C /* DoctorDark-GUI */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | FB520CEA1D24A10100FE378C /* Assets.xcassets */, 83 | FB520CF51D24A10800FE378C /* MainMenu.xib */, 84 | FB520CEC1D24A10100FE378C /* AppDelegate.h */, 85 | FB520CED1D24A10100FE378C /* AppDelegate.m */, 86 | FB520CEE1D24A10100FE378C /* main.m */, 87 | FB520CEF1D24A10100FE378C /* Info.plist */, 88 | ); 89 | name = "DoctorDark-GUI"; 90 | sourceTree = ""; 91 | }; 92 | FBC27FE81E637D4B00F6516D /* ZKSwizzle */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | FBC27FE51E637D3F00F6516D /* ZKSwizzle.h */, 96 | FBC27FE61E637D3F00F6516D /* ZKSwizzle.m */, 97 | ); 98 | name = ZKSwizzle; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | FB16B34B1BA7D821009F455F /* DoctorDark */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = FB16B3521BA7D821009F455F /* Build configuration list for PBXNativeTarget "DoctorDark" */; 107 | buildPhases = ( 108 | FB16B3481BA7D821009F455F /* Sources */, 109 | FB16B3491BA7D821009F455F /* Frameworks */, 110 | FB16B34A1BA7D821009F455F /* Resources */, 111 | FB16B3581BA7D9E4009F455F /* Increment Build Number and Install Bundle */, 112 | ); 113 | buildRules = ( 114 | ); 115 | dependencies = ( 116 | ); 117 | name = DoctorDark; 118 | productName = zestyWin; 119 | productReference = FB16B34C1BA7D821009F455F /* DoctorDark.bundle */; 120 | productType = "com.apple.product-type.bundle"; 121 | }; 122 | FB61D73D1C3CA27D00FA3C4C /* DoctorDark-GUI */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = FB61D74C1C3CA27D00FA3C4C /* Build configuration list for PBXNativeTarget "DoctorDark-GUI" */; 125 | buildPhases = ( 126 | FB61D73A1C3CA27D00FA3C4C /* Sources */, 127 | FB61D73B1C3CA27D00FA3C4C /* Frameworks */, 128 | FB61D73C1C3CA27D00FA3C4C /* Resources */, 129 | FB4978921CFC154A005A2253 /* ShellScript */, 130 | ); 131 | buildRules = ( 132 | ); 133 | dependencies = ( 134 | ); 135 | name = "DoctorDark-GUI"; 136 | productName = "zestyWin-GUI"; 137 | productReference = FB61D73E1C3CA27D00FA3C4C /* DoctorDark-GUI.app */; 138 | productType = "com.apple.product-type.application"; 139 | }; 140 | /* End PBXNativeTarget section */ 141 | 142 | /* Begin PBXProject section */ 143 | FB16B3441BA7D821009F455F /* Project object */ = { 144 | isa = PBXProject; 145 | attributes = { 146 | LastUpgradeCheck = 0900; 147 | ORGANIZATIONNAME = "Wolfgang Baird"; 148 | TargetAttributes = { 149 | FB16B34B1BA7D821009F455F = { 150 | CreatedOnToolsVersion = 7.1; 151 | }; 152 | FB61D73D1C3CA27D00FA3C4C = { 153 | CreatedOnToolsVersion = 7.2; 154 | }; 155 | }; 156 | }; 157 | buildConfigurationList = FB16B3471BA7D821009F455F /* Build configuration list for PBXProject "DoctorDark" */; 158 | compatibilityVersion = "Xcode 3.2"; 159 | developmentRegion = English; 160 | hasScannedForEncodings = 0; 161 | knownRegions = ( 162 | en, 163 | Base, 164 | ); 165 | mainGroup = FB16B3431BA7D821009F455F; 166 | productRefGroup = FB16B34D1BA7D821009F455F /* Products */; 167 | projectDirPath = ""; 168 | projectRoot = ""; 169 | targets = ( 170 | FB16B34B1BA7D821009F455F /* DoctorDark */, 171 | FB61D73D1C3CA27D00FA3C4C /* DoctorDark-GUI */, 172 | ); 173 | }; 174 | /* End PBXProject section */ 175 | 176 | /* Begin PBXResourcesBuildPhase section */ 177 | FB16B34A1BA7D821009F455F /* Resources */ = { 178 | isa = PBXResourcesBuildPhase; 179 | buildActionMask = 2147483647; 180 | files = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | }; 184 | FB61D73C1C3CA27D00FA3C4C /* Resources */ = { 185 | isa = PBXResourcesBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | FB520CF01D24A10100FE378C /* Assets.xcassets in Resources */, 189 | FB520CF81D24A11F00FE378C /* MainMenu.xib in Resources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXResourcesBuildPhase section */ 194 | 195 | /* Begin PBXShellScriptBuildPhase section */ 196 | FB16B3581BA7D9E4009F455F /* Increment Build Number and Install Bundle */ = { 197 | isa = PBXShellScriptBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | ); 201 | inputPaths = ( 202 | ); 203 | name = "Increment Build Number and Install Bundle"; 204 | outputPaths = ( 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | shellPath = /bin/sh; 208 | shellScript = "# @desc Auto-increment the build number every time the project is run.\nVERSIONNUM=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\")\nNEWSUBVERSION=`echo $VERSIONNUM | awk -F \".\" '{print $3}'`\nNEWSUBVERSION=$(($NEWSUBVERSION + 1))\nNEWVERSIONSTRING=`echo $VERSIONNUM | awk -F \".\" '{print $1 \".\" $2 \".'$NEWSUBVERSION'\" }'`\n/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $NEWVERSIONSTRING\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\"\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $NEWVERSIONSTRING\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\"\n\n# @desc Move bundle to SIMBL plugins folder after building\nif [[ \"$WRAPPER_EXTENSION\" == \"bundle\" ]]; then\nif [[ -e /Library/Application\\ Support/SIMBL/Plugins ]]; then\ncp -Rf \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME}.$WRAPPER_EXTENSION\" /Library/Application\\ Support/SIMBL/Plugins\nfi\nfi\n\nif [[ ! -e \"${SRCROOT}/build\" ]]; then\nmkdir \"${SRCROOT}/build\"\nfi\ncp -Rf \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME}.$WRAPPER_EXTENSION\" \"${SRCROOT}/build\"\n#zip -r \"${SRCROOT}/build/${EXECUTABLE_NAME}_${NEWVERSIONSTRING}.zip\" \"${SRCROOT}/build/${EXECUTABLE_NAME}.bundle\"\n#/Users/w0lf/bin/trashman \"${SRCROOT}/build/${EXECUTABLE_NAME}.bundle\""; 209 | }; 210 | FB4978921CFC154A005A2253 /* ShellScript */ = { 211 | isa = PBXShellScriptBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | inputPaths = ( 216 | ); 217 | outputPaths = ( 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | shellPath = /bin/sh; 221 | shellScript = "# @desc Auto-increment the build number every time the project is run.\nVERSIONNUM=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\")\nNEWSUBVERSION=`echo $VERSIONNUM | awk -F \".\" '{print $3}'`\nNEWSUBVERSION=$(($NEWSUBVERSION + 1))\nNEWVERSIONSTRING=`echo $VERSIONNUM | awk -F \".\" '{print $1 \".\" $2 \".'$NEWSUBVERSION'\" }'`\n/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $NEWVERSIONSTRING\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\"\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $NEWVERSIONSTRING\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\"\n\n# @desc Move bundle to SIMBL plugins folder after building\nif [[ \"$WRAPPER_EXTENSION\" == \"bundle\" ]]; then\nif [[ -e /Library/Application\\ Support/SIMBL/Plugins ]]; then\ncp -Rf \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME}.$WRAPPER_EXTENSION\" /Library/Application\\ Support/SIMBL/Plugins\nfi\nfi\n\nif [[ ! -e \"${SRCROOT}/build\" ]]; then\nmkdir \"${SRCROOT}/build\"\nfi\ncp -Rf \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_NAME}.$WRAPPER_EXTENSION\" \"${SRCROOT}/build\"\n#zip -r \"${SRCROOT}/build/${EXECUTABLE_NAME}_${NEWVERSIONSTRING}.zip\" \"${SRCROOT}/build/${EXECUTABLE_NAME}.bundle\"\n#/Users/w0lf/bin/trashman \"${SRCROOT}/build/${EXECUTABLE_NAME}.bundle\""; 222 | }; 223 | /* End PBXShellScriptBuildPhase section */ 224 | 225 | /* Begin PBXSourcesBuildPhase section */ 226 | FB16B3481BA7D821009F455F /* Sources */ = { 227 | isa = PBXSourcesBuildPhase; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | FB520CE81D24A0F600FE378C /* DoctorDark.m in Sources */, 231 | FBC27FE71E637D3F00F6516D /* ZKSwizzle.m in Sources */, 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | }; 235 | FB61D73A1C3CA27D00FA3C4C /* Sources */ = { 236 | isa = PBXSourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | FB520CF31D24A10100FE378C /* main.m in Sources */, 240 | FB520CF21D24A10100FE378C /* AppDelegate.m in Sources */, 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | }; 244 | /* End PBXSourcesBuildPhase section */ 245 | 246 | /* Begin PBXVariantGroup section */ 247 | FB520CF51D24A10800FE378C /* MainMenu.xib */ = { 248 | isa = PBXVariantGroup; 249 | children = ( 250 | FB520CF61D24A10800FE378C /* Base */, 251 | ); 252 | name = MainMenu.xib; 253 | sourceTree = ""; 254 | }; 255 | /* End PBXVariantGroup section */ 256 | 257 | /* Begin XCBuildConfiguration section */ 258 | FB16B3501BA7D821009F455F /* Debug */ = { 259 | isa = XCBuildConfiguration; 260 | buildSettings = { 261 | ALWAYS_SEARCH_USER_PATHS = NO; 262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 263 | CLANG_CXX_LIBRARY = "libc++"; 264 | CLANG_ENABLE_MODULES = YES; 265 | CLANG_ENABLE_OBJC_ARC = YES; 266 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 267 | CLANG_WARN_BOOL_CONVERSION = YES; 268 | CLANG_WARN_COMMA = 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_INFINITE_RECURSION = YES; 274 | CLANG_WARN_INT_CONVERSION = YES; 275 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 276 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 279 | CLANG_WARN_STRICT_PROTOTYPES = YES; 280 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 281 | CLANG_WARN_UNREACHABLE_CODE = YES; 282 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 283 | CODE_SIGN_IDENTITY = "-"; 284 | COPY_PHASE_STRIP = NO; 285 | DEBUG_INFORMATION_FORMAT = dwarf; 286 | ENABLE_STRICT_OBJC_MSGSEND = YES; 287 | ENABLE_TESTABILITY = YES; 288 | GCC_C_LANGUAGE_STANDARD = gnu99; 289 | GCC_DYNAMIC_NO_PIC = NO; 290 | GCC_NO_COMMON_BLOCKS = YES; 291 | GCC_OPTIMIZATION_LEVEL = 0; 292 | GCC_PREPROCESSOR_DEFINITIONS = ( 293 | "DEBUG=1", 294 | "$(inherited)", 295 | ); 296 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 297 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 298 | GCC_WARN_UNDECLARED_SELECTOR = YES; 299 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 300 | GCC_WARN_UNUSED_FUNCTION = YES; 301 | GCC_WARN_UNUSED_VARIABLE = YES; 302 | MACOSX_DEPLOYMENT_TARGET = 10.10; 303 | MTL_ENABLE_DEBUG_INFO = YES; 304 | ONLY_ACTIVE_ARCH = YES; 305 | SDKROOT = macosx; 306 | }; 307 | name = Debug; 308 | }; 309 | FB16B3511BA7D821009F455F /* Release */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | ALWAYS_SEARCH_USER_PATHS = NO; 313 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 314 | CLANG_CXX_LIBRARY = "libc++"; 315 | CLANG_ENABLE_MODULES = YES; 316 | CLANG_ENABLE_OBJC_ARC = YES; 317 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 318 | CLANG_WARN_BOOL_CONVERSION = YES; 319 | CLANG_WARN_COMMA = YES; 320 | CLANG_WARN_CONSTANT_CONVERSION = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_EMPTY_BODY = YES; 323 | CLANG_WARN_ENUM_CONVERSION = YES; 324 | CLANG_WARN_INFINITE_RECURSION = YES; 325 | CLANG_WARN_INT_CONVERSION = YES; 326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 328 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 329 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 330 | CLANG_WARN_STRICT_PROTOTYPES = YES; 331 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 332 | CLANG_WARN_UNREACHABLE_CODE = YES; 333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 334 | CODE_SIGN_IDENTITY = "-"; 335 | COPY_PHASE_STRIP = NO; 336 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 337 | ENABLE_NS_ASSERTIONS = NO; 338 | ENABLE_STRICT_OBJC_MSGSEND = YES; 339 | GCC_C_LANGUAGE_STANDARD = gnu99; 340 | GCC_NO_COMMON_BLOCKS = YES; 341 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 342 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 343 | GCC_WARN_UNDECLARED_SELECTOR = YES; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.10; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | SDKROOT = macosx; 350 | }; 351 | name = Release; 352 | }; 353 | FB16B3531BA7D821009F455F /* Debug */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | COMBINE_HIDPI_IMAGES = YES; 357 | INFOPLIST_FILE = "${EXECUTABLE_NAME}/Info.plist"; 358 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 359 | PRODUCT_BUNDLE_IDENTIFIER = org.w0lf.drdark; 360 | PRODUCT_NAME = "$(TARGET_NAME)"; 361 | SKIP_INSTALL = YES; 362 | WRAPPER_EXTENSION = bundle; 363 | }; 364 | name = Debug; 365 | }; 366 | FB16B3541BA7D821009F455F /* Release */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | COMBINE_HIDPI_IMAGES = YES; 370 | INFOPLIST_FILE = "${EXECUTABLE_NAME}/Info.plist"; 371 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; 372 | PRODUCT_BUNDLE_IDENTIFIER = org.w0lf.drdark; 373 | PRODUCT_NAME = "$(TARGET_NAME)"; 374 | SKIP_INSTALL = YES; 375 | WRAPPER_EXTENSION = bundle; 376 | }; 377 | name = Release; 378 | }; 379 | FB61D74D1C3CA27D00FA3C4C /* Debug */ = { 380 | isa = XCBuildConfiguration; 381 | buildSettings = { 382 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 383 | COMBINE_HIDPI_IMAGES = YES; 384 | INFOPLIST_FILE = "${EXECUTABLE_NAME}/Info.plist"; 385 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 386 | MACOSX_DEPLOYMENT_TARGET = 10.10; 387 | PRODUCT_BUNDLE_IDENTIFIER = "org.w0lf.drdark-GUI"; 388 | PRODUCT_NAME = "$(TARGET_NAME)"; 389 | }; 390 | name = Debug; 391 | }; 392 | FB61D74E1C3CA27D00FA3C4C /* Release */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 396 | COMBINE_HIDPI_IMAGES = YES; 397 | INFOPLIST_FILE = "${EXECUTABLE_NAME}/Info.plist"; 398 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 399 | MACOSX_DEPLOYMENT_TARGET = 10.10; 400 | PRODUCT_BUNDLE_IDENTIFIER = "org.w0lf.drdark-GUI"; 401 | PRODUCT_NAME = "$(TARGET_NAME)"; 402 | }; 403 | name = Release; 404 | }; 405 | /* End XCBuildConfiguration section */ 406 | 407 | /* Begin XCConfigurationList section */ 408 | FB16B3471BA7D821009F455F /* Build configuration list for PBXProject "DoctorDark" */ = { 409 | isa = XCConfigurationList; 410 | buildConfigurations = ( 411 | FB16B3501BA7D821009F455F /* Debug */, 412 | FB16B3511BA7D821009F455F /* Release */, 413 | ); 414 | defaultConfigurationIsVisible = 0; 415 | defaultConfigurationName = Release; 416 | }; 417 | FB16B3521BA7D821009F455F /* Build configuration list for PBXNativeTarget "DoctorDark" */ = { 418 | isa = XCConfigurationList; 419 | buildConfigurations = ( 420 | FB16B3531BA7D821009F455F /* Debug */, 421 | FB16B3541BA7D821009F455F /* Release */, 422 | ); 423 | defaultConfigurationIsVisible = 0; 424 | defaultConfigurationName = Release; 425 | }; 426 | FB61D74C1C3CA27D00FA3C4C /* Build configuration list for PBXNativeTarget "DoctorDark-GUI" */ = { 427 | isa = XCConfigurationList; 428 | buildConfigurations = ( 429 | FB61D74D1C3CA27D00FA3C4C /* Debug */, 430 | FB61D74E1C3CA27D00FA3C4C /* Release */, 431 | ); 432 | defaultConfigurationIsVisible = 0; 433 | defaultConfigurationName = Release; 434 | }; 435 | /* End XCConfigurationList section */ 436 | }; 437 | rootObject = FB16B3441BA7D821009F455F /* Project object */; 438 | } 439 | -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/project.xcworkspace/xcuserdata/w0lf.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/DoctorDark/3ae24762ca24576d5ab2e54e62bf9cad8f666370/DoctorDark.xcodeproj/project.xcworkspace/xcuserdata/w0lf.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/xcuserdata/w0lf.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/xcuserdata/w0lf.xcuserdatad/xcschemes/DoctorDark-GUI.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 44 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 76 | 78 | 84 | 85 | 86 | 87 | 88 | 89 | 95 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/xcuserdata/w0lf.xcuserdatad/xcschemes/DoctorDark.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /DoctorDark.xcodeproj/xcuserdata/w0lf.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DoctorDark-GUI.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | DoctorDark.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | FB16B34B1BA7D821009F455F 21 | 22 | primary 23 | 24 | 25 | FB61D7091C3CA19700FA3C4C 26 | 27 | primary 28 | 29 | 30 | FB61D71E1C3CA19700FA3C4C 31 | 32 | primary 33 | 34 | 35 | FB61D7291C3CA19700FA3C4C 36 | 37 | primary 38 | 39 | 40 | FB61D73D1C3CA27D00FA3C4C 41 | 42 | primary 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /DoctorDark/DoctorDark.m: -------------------------------------------------------------------------------- 1 | // 2 | // drdark.m 3 | // drdark 4 | // 5 | // Created by Wolfgang Baird on 6/29/16. 6 | // Copyright © 2015 - 2016 Wolfgang Baird. All rights reserved. 7 | // 8 | 9 | @import AppKit; 10 | 11 | #import "ZKSwizzle.h" 12 | #import 13 | 14 | #define APP_BLACKLIST @[@"com.apple.loginwindow", @"com.apple.iTunes", @"com.apple.Terminal",\ 15 | @"com.sublimetext.2", @"com.sublimetext.3", @"com.googlecode.iterm2",\ 16 | @"com.google.Chrome.canary", @"com.google.Chrome", @"com.jriver.MediaCenter21",\ 17 | @"com.teamspeak.TeamSpeak3", @"com.cocoatech.PathFinder", @"com.github.GitHub",\ 18 | @"com.apple.ActivityMonitor"] 19 | 20 | #define APP_WHITELIST @[@"com.apple.finder", @"com.apple.systempreferences"] 21 | 22 | #define CLS_BLACKLIST @[@"NSStatusBarWindow", @"BookmarkBarFolderWindow", @"TShrinkToFitWindow",\ 23 | @"QLFullscreenWindow", @"QLPreviewPanel", @"TDesktopWindow",\ 24 | @"TDesktopIcon", @"TDesktopTitleBubbleView", @"TIconSelectionView",\ 25 | @"TNewIconView", @"TBasicImageView", @"TDesktopIconSelectionView",\ 26 | @"TDesktopIconView"] 27 | 28 | @interface drdark : NSObject 29 | @end 30 | 31 | drdark *plugin; 32 | BOOL resizing; 33 | BOOL useWhitelist; 34 | NSMutableArray *itemBlacklist; 35 | NSMutableArray *itemWhitelist; 36 | NSDictionary *sharedDict = nil; 37 | static void *dd_isActive = &dd_isActive; 38 | SEL setTFC; 39 | 40 | @implementation drdark 41 | 42 | /* Shared instance of this plugin so we can call it's methods elsewhere */ 43 | + (drdark*) sharedInstance { 44 | static drdark* plugin = nil; 45 | if (plugin == nil) 46 | plugin = [[drdark alloc] init]; 47 | return plugin; 48 | } 49 | 50 | - (NSAppearance *)darkAppearance { 51 | static NSAppearance *dark; 52 | static dispatch_once_t onceToken; 53 | dispatch_once(&onceToken, ^{ dark = [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]; }); 54 | return dark; 55 | } 56 | 57 | /* Called when the plugin first loads */ 58 | + (void)load { 59 | /* Initialize an instance of our plugin */ 60 | plugin = [drdark sharedInstance]; 61 | NSInteger osx_ver = [[NSProcessInfo processInfo] operatingSystemVersion].minorVersion; 62 | setTFC = NSSelectorFromString(@"setTitleFontColor:"); 63 | if (osx_ver >= 9) { 64 | /* Check if our current bundleIdentifier is blacklisted */ 65 | [plugin dd_initializePrefs]; 66 | 67 | if ([plugin shouldApply:@""]) { 68 | /* Loop through all our windows and set their appearance */ 69 | for (NSWindow *win in [[NSApplication sharedApplication] windows]) 70 | [plugin dd_applyDarkAppearanceToWindow:win]; 71 | 72 | /* Add an observer to set the appearence of all new windows we make that become a key window */ 73 | [[NSNotificationCenter defaultCenter] addObserver:plugin 74 | selector:@selector(dd_WindowDidBecomeKey:) 75 | name:NSWindowDidBecomeKeyNotification 76 | object:nil]; 77 | 78 | NSLog(@"%@ loaded into %@ on macOS 10.%ld", [self class], [[NSBundle mainBundle] bundleIdentifier], (long)osx_ver); 79 | } else { 80 | NSLog(@"winBuddy is blocked in this application because of issues"); 81 | } 82 | } else { 83 | NSLog(@"winBuddy is blocked in this application because of your version of macOS is too old"); 84 | } 85 | } 86 | 87 | /* Recieved a notification saying a window became the key window */ 88 | - (void)dd_WindowDidBecomeKey:(NSNotification *)notification { 89 | /* Call dd_setNSAppearance assuming the notification object is a NSWindow */ 90 | [plugin dd_applyDarkAppearanceToWindow:[notification object]]; 91 | } 92 | 93 | /* Set a windows appearance */ 94 | - (void)dd_applyDarkAppearanceToWindow:(NSWindow *)window { 95 | if ([self shouldApply:[window className]]) { 96 | if (![objc_getAssociatedObject(window, dd_isActive) boolValue]) { 97 | /* Set the appearence to NSAppearanceNameVibrantDark */ 98 | [window setAppearance:[plugin darkAppearance]]; 99 | [plugin dd_updateDarkModeStateForTreeStartingAtView:window.contentView]; 100 | 101 | /* Store a value in the window saying we've already set it's appearance */ 102 | objc_setAssociatedObject(window, dd_isActive, [NSNumber numberWithBool:true], OBJC_ASSOCIATION_RETAIN); 103 | } 104 | } 105 | } 106 | 107 | /* Update all subviews */ 108 | - (void)dd_updateDarkModeStateForTreeStartingAtView:(__kindof NSView *)rootView { 109 | for (NSView *view in rootView.subviews) { 110 | view.appearance = [plugin darkAppearance]; 111 | 112 | if ([view isKindOfClass:[NSVisualEffectView class]]) { 113 | [(NSVisualEffectView *)view setMaterial:NSVisualEffectMaterialDark]; 114 | } 115 | 116 | if ([view isKindOfClass:[NSClipView class]] || 117 | [view isKindOfClass:[NSScrollView class]] || 118 | [view isKindOfClass:[NSMatrix class]] || 119 | [view isKindOfClass:[NSTextView class]] || 120 | [view isKindOfClass:NSClassFromString(@"TBrowserTableView")] || 121 | [view isKindOfClass:NSClassFromString(@"TIconView")]) { 122 | [view performSelector:@selector(setBackgroundColor:) withObject:[NSColor colorWithCalibratedWhite:0.1 alpha:1.0]]; 123 | } 124 | 125 | // if ([view isKindOfClass:NSClassFromString(@"TStatusBarStackView")]) { 126 | // 127 | // } 128 | 129 | if ([view respondsToSelector:setTFC]) { 130 | [view performSelector:setTFC withObject:[NSColor whiteColor]]; 131 | } 132 | 133 | if ([view respondsToSelector:@selector(setTextColor:)]) { 134 | [(NSTextView*)view setTextColor:[NSColor whiteColor]]; 135 | [view display]; 136 | } 137 | 138 | if (view.subviews.count > 0) [self dd_updateDarkModeStateForTreeStartingAtView:view]; 139 | } 140 | 141 | // [rootView.window displayIfNeeded]; 142 | } 143 | 144 | /* Load and setup our bundles preferences */ 145 | -(void)dd_initializePrefs { 146 | /* Load existing preferences for our bundle */ 147 | itemWhitelist = [[NSMutableArray alloc] init]; 148 | itemBlacklist = [[NSMutableArray alloc] init]; 149 | useWhitelist = true; 150 | 151 | [itemBlacklist addObjectsFromArray:APP_BLACKLIST]; 152 | 153 | NSMutableDictionary *pluginPrefs = [NSMutableDictionary dictionaryWithContentsOfFile:[NSHomeDirectory() stringByAppendingPathComponent:@"Library/Preferences/org.w0lf.drdark.plist"]]; 154 | NSArray *addItems; 155 | addItems = [pluginPrefs objectForKey:@"bundleWhitelist"]; 156 | [itemWhitelist addObjectsFromArray:addItems]; 157 | [itemWhitelist addObjectsFromArray:APP_WHITELIST]; 158 | addItems = [pluginPrefs objectForKey:@"bundleBlacklist"]; 159 | [itemBlacklist addObjectsFromArray:addItems]; 160 | [itemBlacklist addObjectsFromArray:APP_BLACKLIST]; 161 | useWhitelist = ![[pluginPrefs objectForKey:@"useBlacklist"] boolValue]; 162 | 163 | /* Loop through blacklist and add all items to preferences if they don't already exist */ 164 | // NSLog(@"wb_ %@", pluginPrefs); 165 | // NSLog(@"wb_ %@", itemWhitelist); 166 | // NSLog(@"wb_ %@", itemBlacklist); 167 | } 168 | 169 | -(BOOL)shouldApply:(NSString*) class { 170 | if (useWhitelist) 171 | if (![itemWhitelist containsObject:[[NSBundle mainBundle] bundleIdentifier]]) 172 | return false; 173 | if ([itemBlacklist containsObject:class]) 174 | return false; 175 | if ([APP_BLACKLIST containsObject:[[NSBundle mainBundle] bundleIdentifier]]) 176 | return false; 177 | if ([CLS_BLACKLIST indexOfObject:class] != NSNotFound) 178 | return false; 179 | return true; 180 | } 181 | 182 | @end 183 | 184 | ZKSwizzleInterface(wbdd_NSCell, NSCell, NSObject) 185 | @implementation wbdd_NSCell 186 | 187 | - (void)drawWithFrame:(struct CGRect)arg1 inView:(id)arg2 { 188 | ZKOrig(void, arg1, arg2); 189 | // NSLog(@"wbdd - nscell - %@", self.className); 190 | } 191 | 192 | @end 193 | 194 | ZKSwizzleInterface(wbdd_TView, TView, NSView) 195 | @implementation wbdd_TView 196 | 197 | - (void)setFrameSize:(struct CGSize)arg1 { 198 | ZKOrig(void, arg1); 199 | if (!resizing) { 200 | if ([plugin shouldApply:[self className]]) { 201 | NSLog(@"wbdd - tview - %@ - %@", self.className, NSStringFromSelector(_cmd)); 202 | 203 | Boolean apply = true; 204 | for (NSString *cls in CLS_BLACKLIST) { 205 | if ([self isKindOfClass:NSClassFromString(cls)]) { 206 | apply = false; 207 | break; 208 | } 209 | } 210 | 211 | if ([self isKindOfClass:NSClassFromString(@"TNewIconView")]) { 212 | [self performSelector:setTFC withObject:[NSColor whiteColor]]; 213 | } 214 | 215 | if (apply) { 216 | [self performSelector:@selector(setBackgroundColor:) withObject:[NSColor colorWithCalibratedWhite:0.1 alpha:1.0]]; 217 | [plugin dd_updateDarkModeStateForTreeStartingAtView:self]; 218 | } 219 | } 220 | } 221 | } 222 | 223 | @end 224 | 225 | ZKSwizzleInterface(wbdd_TBrowserTableView, TBrowserTableView, NSTableView) 226 | @implementation wbdd_TBrowserTableView 227 | 228 | - (void)reloadData { 229 | NSLog(@"wbdd - TBrowserTableView - %@ - %@", self.className, NSStringFromSelector(_cmd)); 230 | ZKOrig(void); 231 | if ([plugin shouldApply:[self className]]) { 232 | [self performSelector:@selector(setBackgroundColor:) withObject:[NSColor colorWithCalibratedWhite:0.1 alpha:1.0]]; 233 | } 234 | } 235 | 236 | @end 237 | 238 | ZKSwizzleInterface(wbdd_NSView, NSView, NSObject) 239 | @implementation wbdd_NSView 240 | 241 | - (void)setFrameSize:(struct CGSize)arg1 { 242 | ZKOrig(void, arg1); 243 | if (!resizing) { 244 | if ([plugin shouldApply:[self className]]) { 245 | NSLog(@"wbdd - nsview - %@", self.className); 246 | Boolean apply = true; 247 | for (NSString *cls in CLS_BLACKLIST) { 248 | if ([self isKindOfClass:NSClassFromString(cls)]) { 249 | apply = false; 250 | break; 251 | } 252 | } 253 | 254 | if ([self isKindOfClass:NSClassFromString(@"TNewIconView")]) { 255 | [self performSelector:setTFC withObject:[NSColor whiteColor]]; 256 | } 257 | 258 | if (apply) { 259 | [plugin dd_updateDarkModeStateForTreeStartingAtView:(NSView*)self]; 260 | } 261 | } 262 | } 263 | } 264 | 265 | @end 266 | 267 | ZKSwizzleInterface(wbdd_NSWindow, NSWindow, NSObject) 268 | @implementation wbdd_NSWindow 269 | 270 | - (BOOL)_inLiveResize { 271 | resizing = ZKOrig(BOOL); 272 | return ZKOrig(BOOL); 273 | } 274 | 275 | @end 276 | -------------------------------------------------------------------------------- /DoctorDark/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 | 0.2.236 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 0.2.236 23 | NSHumanReadableCopyright 24 | Copyright © 2015 Wolfgang Baird. All rights reserved. 25 | NSPrincipalClass 26 | 27 | SIMBLTargetApplications 28 | 29 | 30 | BundleIdentifier 31 | * 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DoctorDark 2 | 3 | ![preview](preview.png) 4 | 5 | # Information: 6 | 7 | - Designed for 10.10+ 8 | - DoctorDark is a SIMBL plugin that tries to bring dark mode to every application window on macOS 9 | - Author: [w0lfschild](https://github.com/w0lfschild) 10 | 11 | # Note: 12 | 13 | - Some applications may look bad or crash 14 | - Applications with custom windows will likely not be effected 15 | - You can blacklist an app using the GUI or terminal: 16 | - `defaults write org.w0lf.drdark $(osascript -e 'id of app "Application Name"') 0` 17 | 18 | # Installation: 19 | 20 | 1. Download [mySIMBL](https://github.com/w0lfschild/app_updates/raw/master/mySIMBL/mySIMBL_0.2.5.zip) 21 | 2. Download [DoctorDark](https://github.com/w0lfschild/DoctorDark/raw/master/build/DoctorDark.bundle.zip) 22 | 3. Unzip downloads 23 | 4. Open `DoctorDark.bundle` with `mySIMBL.app` 24 | 5. Restart any application to have DoctorDark plugin loaded 25 | 26 | ### License: 27 | Pretty much the BSD license, just don't repackage it and call it your own please! 28 | Also if you do make some changes, feel free to make a pull request and help make things more awesome! 29 | -------------------------------------------------------------------------------- /ZKSwizzle.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZKSwizzle.h 3 | // ZKSwizzle 4 | // 5 | // Created by Alexander S Zielenski on 7/24/14. 6 | // Copyright (c) 2014 Alexander S Zielenski. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | // This is a class for streamlining swizzling. Simply create a new class of any name you want and 14 | // Example: 15 | /* 16 | @interface ZKHookClass : NSObject 17 | - (NSString *)description; // hooks -description on NSObject 18 | - (void)addedMethod; // all subclasses of NSObject now respond to -addedMethod 19 | @end 20 | 21 | @implementation ZKHookClass 22 | ... 23 | @end 24 | 25 | [ZKSwizzle swizzleClass:ZKClass(ZKHookClass) forClass:ZKClass(destination)]; 26 | */ 27 | 28 | #ifndef ZKSWIZZLE_DEFS 29 | #define ZKSWIZZLE_DEFS 30 | 31 | // CRAZY MACROS FOR DYNAMIC PROTOTYPE CREATION 32 | #define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(0, ## __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5 ,4 ,3 ,2, 1, 0) 33 | #define VA_NUM_ARGS_IMPL(_0, _1,_2,_3,_4,_5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 ,N,...) N 34 | 35 | #define WRAP0() 36 | #define WRAP1(VARIABLE) , typeof ( VARIABLE ) 37 | #define WRAP2(VARIABLE, ...) WRAP1(VARIABLE) WRAP1(__VA_ARGS__) 38 | #define WRAP3(VARIABLE, ...) WRAP1(VARIABLE) WRAP2(__VA_ARGS__) 39 | #define WRAP4(VARIABLE, ...) WRAP1(VARIABLE) WRAP3(__VA_ARGS__) 40 | #define WRAP5(VARIABLE, ...) WRAP1(VARIABLE) WRAP4(__VA_ARGS__) 41 | #define WRAP6(VARIABLE, ...) WRAP1(VARIABLE) WRAP5(__VA_ARGS__) 42 | #define WRAP7(VARIABLE, ...) WRAP1(VARIABLE) WRAP6(__VA_ARGS__) 43 | #define WRAP8(VARIABLE, ...) WRAP1(VARIABLE) WRAP7(__VA_ARGS__) 44 | #define WRAP9(VARIABLE, ...) WRAP1(VARIABLE) WRAP8(__VA_ARGS__) 45 | #define WRAP10(VARIABLE, ...) WRAP1(VARIABLE) WRAP9(__VA_ARGS__) 46 | #define WRAP11(VARIABLE, ...) WRAP1(VARIABLE) WRAP10(__VA_ARGS__) 47 | #define WRAP12(VARIABLE, ...) WRAP1(VARIABLE) WRAP11(__VA_ARGS__) 48 | #define WRAP13(VARIABLE, ...) WRAP1(VARIABLE) WRAP12(__VA_ARGS__) 49 | #define WRAP14(VARIABLE, ...) WRAP1(VARIABLE) WRAP13(__VA_ARGS__) 50 | #define WRAP15(VARIABLE, ...) WRAP1(VARIABLE) WRAP14(__VA_ARGS__) 51 | #define WRAP16(VARIABLE, ...) WRAP1(VARIABLE) WRAP15(__VA_ARGS__) 52 | #define WRAP17(VARIABLE, ...) WRAP1(VARIABLE) WRAP16(__VA_ARGS__) 53 | #define WRAP18(VARIABLE, ...) WRAP1(VARIABLE) WRAP17(__VA_ARGS__) 54 | #define WRAP19(VARIABLE, ...) WRAP1(VARIABLE) WRAP18(__VA_ARGS__) 55 | #define WRAP20(VARIABLE, ...) WRAP1(VARIABLE) WRAP19(__VA_ARGS__) 56 | 57 | #define CAT(A, B) A ## B 58 | #define INVOKE(MACRO, NUMBER, ...) CAT(MACRO, NUMBER)(__VA_ARGS__) 59 | #define WRAP_LIST(...) INVOKE(WRAP, VA_NUM_ARGS(__VA_ARGS__), __VA_ARGS__) 60 | 61 | // Gets the a class with the name CLASS 62 | #define ZKClass(CLASS) objc_getClass(#CLASS) 63 | 64 | // returns the value of an instance variable. 65 | #if !__has_feature(objc_arc) 66 | #define ZKHookIvar(OBJECT, TYPE, NAME) (*(TYPE *)ZKIvarPointer(OBJECT, NAME)) 67 | #else 68 | #define ZKHookIvar(OBJECT, TYPE, NAME) \ 69 | _Pragma("clang diagnostic push") \ 70 | _Pragma("clang diagnostic ignored \"-Wignored-attributes\"") \ 71 | (*(__unsafe_unretained TYPE *)ZKIvarPointer(OBJECT, NAME)) \ 72 | _Pragma("clang diagnostic pop") 73 | #endif 74 | // returns the original implementation of the swizzled function or null or not found 75 | #define ZKOrig(TYPE, ...) ((TYPE (*)(id, SEL WRAP_LIST(__VA_ARGS__)))(ZKOriginalImplementation(self, _cmd, __PRETTY_FUNCTION__)))(self, _cmd, ##__VA_ARGS__) 76 | 77 | // returns the original implementation of the superclass of the object swizzled 78 | #define ZKSuper(TYPE, ...) ((TYPE (*)(id, SEL WRAP_LIST(__VA_ARGS__)))(ZKSuperImplementation(self, _cmd, __PRETTY_FUNCTION__)))(self, _cmd, ##__VA_ARGS__) 79 | 80 | #define _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPERCLASS, GROUP, IMMEDIATELY) \ 81 | @interface _$ ## CLASS_NAME : SUPERCLASS @end \ 82 | @implementation _$ ## CLASS_NAME \ 83 | + (void)initialize {} \ 84 | @end \ 85 | @interface CLASS_NAME : _$ ## CLASS_NAME @end \ 86 | @implementation CLASS_NAME (ZKSWIZZLE) \ 87 | + (void)load { \ 88 | _$ZKRegisterInterface(self, #GROUP);\ 89 | if (IMMEDIATELY) { \ 90 | [self _ZK_unconditionallySwizzle]; \ 91 | } \ 92 | } \ 93 | + (void)_ZK_unconditionallySwizzle { \ 94 | ZKSwizzle(CLASS_NAME, TARGET_CLASS); \ 95 | } \ 96 | @end 97 | 98 | // Bootstraps your swizzling class so that it requires no setup 99 | // outside of this macro call 100 | // If you override +load you must call ZKSwizzle(CLASS_NAME, TARGET_CLASS) 101 | // yourself, otherwise the swizzling would not take place 102 | #define ZKSwizzleInterface(CLASS_NAME, TARGET_CLASS, SUPERCLASS) \ 103 | _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPERCLASS, ZK_UNGROUPED, YES) 104 | 105 | // Same as ZKSwizzleInterface, except 106 | #define ZKSwizzleInterfaceGroup(CLASS_NAME, TARGET_CLASS, SUPER_CLASS, GROUP) \ 107 | _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPER_CLASS, GROUP, NO) 108 | 109 | __BEGIN_DECLS 110 | 111 | // Make sure to cast this before you use it 112 | typedef id (*ZKIMP)(id, SEL, ...); 113 | 114 | // returns a pointer to the instance variable "name" on the object 115 | void *ZKIvarPointer(id self, const char *name); 116 | // returns the original implementation of a method with selector "sel" of an object hooked by the methods below 117 | ZKIMP ZKOriginalImplementation(id self, SEL sel, const char *info); 118 | // returns the implementation of a method with selector "sel" of the superclass of object 119 | ZKIMP ZKSuperImplementation(id object, SEL sel, const char *info); 120 | 121 | // hooks all the implemented methods of source with destination 122 | // adds any methods that arent implemented on destination to destination that are implemented in source 123 | #define ZKSwizzle(src, dst) _ZKSwizzle(ZKClass(src), ZKClass(dst)) 124 | BOOL _ZKSwizzle(Class src, Class dest); 125 | 126 | #define ZKSwizzleGroup(NAME) _ZKSwizzleGroup(#NAME) 127 | void _$ZKRegisterInterface(Class cls, const char *groupName); 128 | BOOL _ZKSwizzleGroup(const char *groupName); 129 | 130 | // Calls above method with the superclass of source for desination 131 | #define ZKSwizzleClass(src) _ZKSwizzleClass(ZKClass(src)) 132 | BOOL _ZKSwizzleClass(Class cls); 133 | 134 | __END_DECLS 135 | #endif 136 | 137 | -------------------------------------------------------------------------------- /ZKSwizzle.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZKSwizzle.m 3 | // ZKSwizzle 4 | // 5 | // Created by Alexander S Zielenski on 7/24/14. 6 | // Copyright (c) 2014 Alexander S Zielenski. All rights reserved. 7 | // 8 | 9 | #import "ZKSwizzle.h" 10 | static NSMutableDictionary *classTable; 11 | 12 | @interface NSObject (ZKSwizzle) 13 | + (void)_ZK_unconditionallySwizzle; 14 | @end 15 | 16 | void *ZKIvarPointer(id self, const char *name) { 17 | Ivar ivar = class_getInstanceVariable(object_getClass(self), name); 18 | return ivar == NULL ? NULL : (__bridge void *)self + ivar_getOffset(ivar); 19 | } 20 | 21 | static SEL destinationSelectorForSelector(SEL cmd, Class dst) { 22 | return NSSelectorFromString([@"_ZK_old_" stringByAppendingFormat:@"%s_%@", class_getName(dst), NSStringFromSelector(cmd)]); 23 | } 24 | 25 | static Class classFromInfo(const char *info) { 26 | NSUInteger bracket_index = -1; 27 | for (NSUInteger i = 0; i < strlen(info); i++) { 28 | if (info[i] == '[') { 29 | bracket_index = i; 30 | } 31 | } 32 | bracket_index++; 33 | 34 | if (bracket_index == -1) { 35 | [NSException raise:@"Failed to parse info" format:@"Couldn't find swizzle class for info: %s", info]; 36 | return NULL; 37 | } 38 | 39 | char after_bracket[255]; 40 | memcpy(after_bracket, &info[bracket_index], strlen(info) - bracket_index - 1); 41 | 42 | for (NSUInteger i = 0; i < strlen(info); i++) { 43 | if (after_bracket[i] == ' ') { 44 | after_bracket[i] = '\0'; 45 | } 46 | } 47 | 48 | return objc_getClass(after_bracket); 49 | } 50 | 51 | // takes __PRETTY_FUNCTION__ for info which gives the name of the swizzle source class 52 | /* 53 | 54 | We add the original implementation onto the swizzle class 55 | On ZKOrig, we use __PRETTY_FUNCTION__ to get the name of the swizzle class 56 | Then we get the implementation of that selector on the swizzle class 57 | Then we call it directly, passing in the correct selector and self 58 | 59 | */ 60 | ZKIMP ZKOriginalImplementation(id self, SEL sel, const char *info) { 61 | if (sel == NULL || self == NULL || info == NULL) { 62 | [NSException raise:@"Invalid Arguments" format:@"One of self: %@, self: %@, or info: %s is NULL", self, NSStringFromSelector(sel), info]; 63 | return NULL; 64 | } 65 | 66 | Class cls = classFromInfo(info); 67 | Class dest = object_getClass(self); 68 | 69 | if (cls == NULL || dest == NULL) { 70 | [NSException raise:@"Failed obtain class pair" format:@"src: %@ | dst: %@ | sel: %@", NSStringFromClass(cls), NSStringFromClass(dest), NSStringFromSelector(sel)]; 71 | return NULL; 72 | } 73 | 74 | SEL destSel = destinationSelectorForSelector(sel, cls); 75 | 76 | Method method = class_getInstanceMethod(dest, destSel); 77 | 78 | if (method == NULL) { 79 | [NSException raise:@"Failed to retrieve method" format:@"Got null for the source class %@ with selector %@ (%@)", NSStringFromClass(cls), NSStringFromSelector(sel), NSStringFromSelector(destSel)]; 80 | return NULL; 81 | } 82 | 83 | ZKIMP implementation = (ZKIMP)method_getImplementation(method); 84 | if (implementation == NULL) { 85 | [NSException raise:@"Failed to get implementation" format:@"The objective-c runtime could not get the implementation for %@ on the class %@. There is no fix for this", NSStringFromClass(cls), NSStringFromSelector(sel)]; 86 | } 87 | 88 | return implementation; 89 | } 90 | 91 | ZKIMP ZKSuperImplementation(id object, SEL sel, const char *info) { 92 | if (sel == NULL || object == NULL) { 93 | [NSException raise:@"Invalid Arguments" format:@"One of self: %@, self: %@ is NULL", object, NSStringFromSelector(sel)]; 94 | return NULL; 95 | } 96 | 97 | Class cls = object_getClass(object); 98 | if (cls == NULL) { 99 | [NSException raise:@"Invalid Argument" format:@"Could not obtain class for the passed object"]; 100 | return NULL; 101 | } 102 | 103 | // Two scenarios: 104 | // 1.) The superclass was not swizzled, no problem 105 | // 2.) The superclass was swizzled, problem 106 | 107 | // We want to return the swizzled class's superclass implementation 108 | // If this is a subclass of such a class, we want two behaviors: 109 | // a.) If this imp was also swizzled, no problem, return the superclass's swizzled imp 110 | // b.) This imp was not swizzled, return the class that was originally swizzled's superclass's imp 111 | Class sourceClass = classFromInfo(info); 112 | if (sourceClass != NULL) { 113 | BOOL isClassMethod = class_isMetaClass(cls); 114 | // This was called from a swizzled method, get the class it was swizzled with 115 | NSString *className = classTable[NSStringFromClass(sourceClass)]; 116 | if (className != NULL) { 117 | cls = NSClassFromString(className); 118 | // make sure we get a class method if we asked for one 119 | if (isClassMethod) { 120 | cls = object_getClass(cls); 121 | } 122 | } 123 | } 124 | 125 | cls = class_getSuperclass(cls); 126 | 127 | // This is a root class, it has no super class 128 | if (cls == NULL) { 129 | [NSException raise:@"Invalid Argument" format:@"Could not obtain superclass for the passed object"]; 130 | return NULL; 131 | } 132 | 133 | Method method = class_getInstanceMethod(cls, sel); 134 | if (method == NULL) { 135 | [NSException raise:@"Failed to retrieve method" format:@"We could not find the super implementation for the class %@ and selector %@, are you sure it exists?", NSStringFromClass(cls), NSStringFromSelector(sel)]; 136 | return NULL; 137 | } 138 | 139 | ZKIMP implementation = (ZKIMP)method_getImplementation(method); 140 | if (implementation == NULL) { 141 | [NSException raise:@"Failed to get implementation" format:@"The objective-c runtime could not get the implementation for %@ on the class %@. There is no fix for this", NSStringFromClass(cls), NSStringFromSelector(sel)]; 142 | } 143 | 144 | return implementation; 145 | } 146 | 147 | static BOOL enumerateMethods(Class, Class); 148 | BOOL _ZKSwizzle(Class src, Class dest) { 149 | if (dest == NULL) 150 | return NO; 151 | 152 | NSString *destName = NSStringFromClass(dest); 153 | if (!destName) { 154 | return NO; 155 | } 156 | 157 | if (!classTable) { 158 | classTable = [[NSMutableDictionary alloc] init]; 159 | } 160 | 161 | if ([classTable objectForKey:NSStringFromClass(src)]) { 162 | [NSException raise:@"Invalid Argument" 163 | format:@"This source class (%@) was already swizzled with another, (%@)", NSStringFromClass(src), classTable[NSStringFromClass(src)]]; 164 | return NO; 165 | } 166 | 167 | BOOL success = enumerateMethods(dest, src); 168 | // The above method only gets instance methods. Do the same method for the metaclass of the class 169 | success &= enumerateMethods(object_getClass(dest), object_getClass(src)); 170 | 171 | [classTable setObject:destName forKey:NSStringFromClass(src)]; 172 | return success; 173 | } 174 | 175 | BOOL _ZKSwizzleClass(Class cls) { 176 | return _ZKSwizzle(cls, [cls superclass]); 177 | } 178 | 179 | static BOOL enumerateMethods(Class destination, Class source) { 180 | #if OBJC_API_VERSION < 2 181 | [NSException raise:@"Unsupported feature" format:@"ZKSwizzle is only available in objc 2.0"]; 182 | return NO; 183 | 184 | #else 185 | 186 | unsigned int methodCount; 187 | Method *methodList = class_copyMethodList(source, &methodCount); 188 | BOOL success = YES; 189 | for (int i = 0; i < methodCount; i++) { 190 | Method method = methodList[i]; 191 | SEL selector = method_getName(method); 192 | NSString *methodName = NSStringFromSelector(selector); 193 | 194 | // Don't do anything with the unconditional swizzle 195 | if (sel_isEqual(selector, @selector(_ZK_unconditionallySwizzle))) { 196 | continue; 197 | } 198 | 199 | // We only swizzle methods that are implemented 200 | if (class_respondsToSelector(destination, selector)) { 201 | Method originalMethod = class_getInstanceMethod(destination, selector); 202 | 203 | const char *originalType = method_getTypeEncoding(originalMethod); 204 | const char *newType = method_getTypeEncoding(method); 205 | if (strcmp(originalType, newType) != 0) { 206 | NSLog(@"ZKSwizzle: incompatible type encoding for %@. (expected %s, got %s)", methodName, originalType, newType); 207 | // Incompatible type encoding 208 | success = NO; 209 | continue; 210 | } 211 | 212 | // We are re-adding the destination selector because it could be on a superclass and not on the class itself. This method could fail 213 | class_addMethod(destination, selector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 214 | 215 | SEL destSel = destinationSelectorForSelector(selector, source); 216 | if (!class_addMethod(destination, destSel, method_getImplementation(method), method_getTypeEncoding(originalMethod))) { 217 | NSLog(@"ZKSwizzle: failed to add method %@ onto class %@ with selector %@", NSStringFromSelector(selector), NSStringFromClass(source), NSStringFromSelector(destSel)); 218 | success = NO; 219 | continue; 220 | } 221 | 222 | method_exchangeImplementations(class_getInstanceMethod(destination, selector), class_getInstanceMethod(destination, destSel)); 223 | } else { 224 | // Add any extra methods to the class but don't swizzle them 225 | success &= class_addMethod(destination, selector, method_getImplementation(method), method_getTypeEncoding(method)); 226 | } 227 | } 228 | 229 | unsigned int propertyCount; 230 | objc_property_t *propertyList = class_copyPropertyList(source, &propertyCount); 231 | for (int i = 0; i < propertyCount; i++) { 232 | objc_property_t property = propertyList[i]; 233 | const char *name = property_getName(property); 234 | unsigned int attributeCount; 235 | objc_property_attribute_t *attributes = property_copyAttributeList(property, &attributeCount); 236 | 237 | if (class_getProperty(destination, name) == NULL) { 238 | class_addProperty(destination, name, attributes, attributeCount); 239 | } else { 240 | class_replaceProperty(destination, name, attributes, attributeCount); 241 | } 242 | 243 | free(attributes); 244 | } 245 | 246 | free(propertyList); 247 | free(methodList); 248 | return success; 249 | #endif 250 | } 251 | 252 | // Options were to use a group class and traverse its subclasses 253 | // or to create a groups dictionary 254 | // This works because +load on NSObject is called before attribute((constructor)) 255 | static NSMutableDictionary *groups = nil; 256 | void _$ZKRegisterInterface(Class cls, const char *groupName) { 257 | if (!groups) 258 | groups = [NSMutableDictionary dictionary]; 259 | 260 | NSString *groupString = @(groupName); 261 | NSMutableArray *groupList = groups[groupString]; 262 | if (!groupList) { 263 | groupList = [NSMutableArray array]; 264 | groups[groupString] = groupList; 265 | } 266 | 267 | [groupList addObject:NSStringFromClass(cls)]; 268 | } 269 | 270 | BOOL _ZKSwizzleGroup(const char *groupName) { 271 | NSArray *groupList = groups[@(groupName)]; 272 | if (!groupList) { 273 | [NSException raise:@"Invalid Argument" format:@"ZKSwizzle: There is no group by the name of %s", groupName]; 274 | return NO; 275 | } 276 | 277 | BOOL success = YES; 278 | for (NSString *className in groupList) { 279 | Class cls = NSClassFromString(className); 280 | if (cls == NULL) 281 | continue; 282 | 283 | if (class_respondsToSelector(object_getClass(cls), @selector(_ZK_unconditionallySwizzle))) { 284 | [cls _ZK_unconditionallySwizzle]; 285 | } else { 286 | success = NO; 287 | } 288 | } 289 | 290 | return success; 291 | } 292 | -------------------------------------------------------------------------------- /build/DoctorDark-GUI.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/DoctorDark/3ae24762ca24576d5ab2e54e62bf9cad8f666370/build/DoctorDark-GUI.zip -------------------------------------------------------------------------------- /build/DoctorDark.bundle.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/DoctorDark/3ae24762ca24576d5ab2e54e62bf9cad8f666370/build/DoctorDark.bundle.zip -------------------------------------------------------------------------------- /build/DoctorDark.bundle/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 17A360a 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | DoctorDark 11 | CFBundleIdentifier 12 | org.w0lf.drdark 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | DoctorDark 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 0.2.235 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 0.2.235 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 9M214v 33 | DTPlatformVersion 34 | GM 35 | DTSDKBuild 36 | 17A350a 37 | DTSDKName 38 | macosx10.13 39 | DTXcode 40 | 0900 41 | DTXcodeBuild 42 | 9M214v 43 | NSHumanReadableCopyright 44 | Copyright © 2015 Wolfgang Baird. All rights reserved. 45 | SIMBLTargetApplications 46 | 47 | 48 | BundleIdentifier 49 | * 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /build/DoctorDark.bundle/Contents/MacOS/DoctorDark: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/DoctorDark/3ae24762ca24576d5ab2e54e62bf9cad8f666370/build/DoctorDark.bundle/Contents/MacOS/DoctorDark -------------------------------------------------------------------------------- /build/DoctorDark.bundle/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | files2 8 | 9 | rules 10 | 11 | ^Resources/ 12 | 13 | ^Resources/.*\.lproj/ 14 | 15 | optional 16 | 17 | weight 18 | 1000 19 | 20 | ^Resources/.*\.lproj/locversion.plist$ 21 | 22 | omit 23 | 24 | weight 25 | 1100 26 | 27 | ^Resources/Base\.lproj/ 28 | 29 | weight 30 | 1010 31 | 32 | ^version.plist$ 33 | 34 | 35 | rules2 36 | 37 | .*\.dSYM($|/) 38 | 39 | weight 40 | 11 41 | 42 | ^(.*/)?\.DS_Store$ 43 | 44 | omit 45 | 46 | weight 47 | 2000 48 | 49 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 50 | 51 | nested 52 | 53 | weight 54 | 10 55 | 56 | ^.* 57 | 58 | ^Info\.plist$ 59 | 60 | omit 61 | 62 | weight 63 | 20 64 | 65 | ^PkgInfo$ 66 | 67 | omit 68 | 69 | weight 70 | 20 71 | 72 | ^Resources/ 73 | 74 | weight 75 | 20 76 | 77 | ^Resources/.*\.lproj/ 78 | 79 | optional 80 | 81 | weight 82 | 1000 83 | 84 | ^Resources/.*\.lproj/locversion.plist$ 85 | 86 | omit 87 | 88 | weight 89 | 1100 90 | 91 | ^Resources/Base\.lproj/ 92 | 93 | weight 94 | 1010 95 | 96 | ^[^/]+$ 97 | 98 | nested 99 | 100 | weight 101 | 10 102 | 103 | ^embedded\.provisionprofile$ 104 | 105 | weight 106 | 20 107 | 108 | ^version\.plist$ 109 | 110 | weight 111 | 20 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/DoctorDark/3ae24762ca24576d5ab2e54e62bf9cad8f666370/preview.png --------------------------------------------------------------------------------