├── .gitignore ├── .gitmodules ├── Facebook.xm ├── Icon.psd ├── MBChatHeadWindow.h ├── MBChatHeadWindow.m ├── Makefile ├── MessageBox ├── MessageBox.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── MessageBox │ └── MessageBox-Prefix.pch ├── Paper.xm ├── README.mdown ├── SpringBoard.xm ├── Tweak.xmi ├── UIKit.xm ├── layout ├── DEBIAN │ └── control └── Library │ └── MobileSubstrate │ └── DynamicLibraries │ └── messagebox.plist ├── messagebox.h ├── messagebox.sublime-project ├── messagebox.sublime-workspace ├── messageboxpreferences ├── Makefile ├── Resources │ ├── Info.plist │ ├── MessageBox-Icon.png │ ├── MessageBox-Icon@2x.png │ ├── MessageBox.png │ ├── MessageBox@2x.png │ └── messageboxpreferences.plist ├── entry.plist ├── messageboxpreferences.mm └── theos ├── readme └── messageboxPreview.gif └── theos /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .theos 3 | *.deb 4 | _ 5 | obj 6 | .Trashes 7 | *.swp 8 | *.lock 9 | DerivedData/ 10 | build/ 11 | *.pbxuser 12 | *.mode1v3 13 | *.mode2v3 14 | *.perspectivev3 15 | !default.pbxuser 16 | !default.mode1v3 17 | !default.mode2v3 18 | !default.perspectivev3 19 | xcuserdata 20 | *.xccheckout 21 | xcdebugger 22 | UserInterfaceState.xcuserstate 23 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Xcode-Theos"] 2 | path = Xcode-Theos 3 | url = https://github.com/b3ll/Xcode-Theos 4 | -------------------------------------------------------------------------------- /Facebook.xm: -------------------------------------------------------------------------------- 1 | // 2 | // Facebook.xm 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-03-29. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import "messagebox.h" 10 | #import "MBChatHeadWindow.h" 11 | 12 | static BOOL _ignoreBackgroundedNotifications_facebook = YES; 13 | 14 | static BOOL _UIHiddenForMessageBox_facebook; 15 | 16 | static __weak FBMessengerModule *_messengerModule; 17 | 18 | GROUP(FacebookHooks) 19 | 20 | // Keyboards also need to be shown when the app is backgrounded 21 | HOOK(UITextEffectsWindow) 22 | 23 | - (id)init { 24 | UITextEffectsWindow *window = ORIG(); 25 | [window setKeepContextInBackground:YES]; 26 | return window; 27 | } 28 | 29 | - (void)setKeepContextInBackground:(BOOL)keepContext { 30 | ORIG(YES); 31 | } 32 | 33 | - (BOOL)keepContextInBackground { 34 | return YES; 35 | } 36 | 37 | - (CGFloat)windowLevel { 38 | return KEYBOARD_WINDOW_LEVEL; 39 | } 40 | 41 | - (void)setWindowLevel:(CGFloat)windowLevel { 42 | ORIG(KEYBOARD_WINDOW_LEVEL); 43 | } 44 | 45 | END() 46 | 47 | static void fbResignChatHeads(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 48 | [_messengerModule.chatHeadViewController resignChatHeadViews]; 49 | [[UIApplication sharedApplication].keyWindow endEditing:YES]; 50 | } 51 | 52 | static void fbForceActive(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 53 | _ignoreBackgroundedNotifications_facebook = YES; 54 | [_messengerModule.moduleSession enteredForeground]; 55 | } 56 | 57 | static void fbForceBackgrounded(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 58 | _ignoreBackgroundedNotifications_facebook = NO; 59 | 60 | [[[UIApplication sharedApplication] delegate] applicationDidEnterBackground:[UIApplication sharedApplication]]; 61 | [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil userInfo:nil]; 62 | } 63 | 64 | static void fbShouldRotate(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 65 | UIInterfaceOrientation newOrientation = UIInterfaceOrientationPortrait; 66 | 67 | DebugLog(@"FACEBOOK SHOULD ACTUALLY ROTATE"); 68 | 69 | if ([(__bridge NSString *)name isEqualToString:@ROTATION_PORTRAIT_UPSIDEDOWN_NOTIFICATION]) { 70 | newOrientation = UIInterfaceOrientationPortraitUpsideDown; 71 | } 72 | else if ([(__bridge NSString *)name isEqualToString:@ROTATION_LANDSCAPE_LEFT_NOTIFICATION]) { 73 | newOrientation = UIInterfaceOrientationLandscapeLeft; 74 | } 75 | else if ([(__bridge NSString *)name isEqualToString:@ROTATION_LANDSCAPE_RIGHT_NOTIFICATION]){ 76 | newOrientation = UIInterfaceOrientationLandscapeRight; 77 | } 78 | 79 | [(AppDelegate *)[UIApplication sharedApplication].delegate mb_forceRotationToInterfaceOrientation:newOrientation]; 80 | } 81 | 82 | 83 | HOOK(UIApplication) 84 | 85 | - (UIApplicationState)applicationState { 86 | if (_ignoreBackgroundedNotifications_facebook) { 87 | return UIApplicationStateActive; 88 | } 89 | else { 90 | return (UIApplicationState)ORIG_T(); 91 | } 92 | } 93 | 94 | END() 95 | 96 | // Need to force the app to believe it's still active... no notifications for you! >:D 97 | HOOK(NSNotificationCenter) 98 | 99 | - (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo { 100 | NSString *notification = [notificationName lowercaseString]; 101 | if ([notification rangeOfString:@"background"].location != NSNotFound && _ignoreBackgroundedNotifications_facebook) { 102 | notify_post("ca.adambell.messagebox.fbQuitting"); 103 | 104 | [[UIApplication sharedApplication].keyWindow endEditing:YES]; 105 | 106 | [(AppDelegate *)[UIApplication sharedApplication].delegate mb_setUIHiddenForMessageBox:YES]; 107 | 108 | return; 109 | } 110 | 111 | DebugLog(@"Notification Posted: %@ object: %@ userInfo: %@", notificationName, notificationSender, userInfo); 112 | 113 | ORIG(); 114 | } 115 | 116 | END() 117 | 118 | HOOK(AppDelegate) 119 | 120 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 121 | for (UIWindow *window in application.windows) { 122 | [window setKeepContextInBackground:YES]; 123 | } 124 | 125 | return ORIG_T(); 126 | } 127 | 128 | - (void)applicationDidBecomeActive:(UIApplication *)application { 129 | notify_post("ca.adambell.messagebox.fbLaunching"); 130 | DebugLog(@"FACEBOOK OPENING RIGHT NOW"); 131 | 132 | [self mb_setUIHiddenForMessageBox:NO]; 133 | 134 | ORIG(); 135 | } 136 | 137 | NEW() 138 | - (void)mb_setUIHiddenForMessageBox:(BOOL)hidden { 139 | _UIHiddenForMessageBox_facebook = hidden; 140 | 141 | [[UIApplication sharedApplication].keyWindow setKeepContextInBackground:hidden]; 142 | 143 | [UIApplication sharedApplication].keyWindow.backgroundColor = hidden ? [UIColor clearColor] : [UIColor blackColor]; 144 | 145 | FBChatHeadViewController *chatHeadController = _messengerModule.chatHeadViewController; 146 | [chatHeadController resignChatHeadViews]; 147 | [chatHeadController setHasInboxChatHead:hidden]; 148 | 149 | FBStackView *stackView = (FBStackView *)chatHeadController.view; 150 | UIView *chatHeadContainerView = stackView; 151 | 152 | while (![stackView isKindOfClass:GET_CLASS(FBStackView)]) { 153 | if (stackView.superview == nil) 154 | break; 155 | 156 | chatHeadContainerView = stackView; 157 | stackView = (FBStackView *)stackView.superview; 158 | } 159 | 160 | for (UIView *view in stackView.subviews) { 161 | if (view != chatHeadContainerView && ![view isKindOfClass:GET_CLASS(FBDimmingView)]) { 162 | view.hidden = hidden; 163 | } 164 | } 165 | 166 | chatHeadContainerView.backgroundColor = [UIColor clearColor]; 167 | 168 | UIView *topBarView = chatHeadContainerView.superview; 169 | while (![topBarView isKindOfClass:GET_CLASS(FBTopBarAndContentView)]) { 170 | if (topBarView.superview == nil) 171 | break; 172 | 173 | topBarView = topBarView.superview; 174 | } 175 | 176 | topBarView.backgroundColor = [UIColor clearColor]; 177 | } 178 | 179 | NEW() 180 | - (void)mb_openURL:(NSURL *)url { 181 | CPDistributedMessagingCenter *sbMessagingCenter = [GET_CLASS(CPDistributedMessagingCenter) centerNamed:@"ca.adambell.MessageBox.sbMessagingCenter"]; 182 | rocketbootstrap_distributedmessagingcenter_apply(sbMessagingCenter); 183 | 184 | [sbMessagingCenter sendMessageName:@"messageboxOpenURL" userInfo:@{ @"url" : [url absoluteString] }]; 185 | 186 | FBChatHeadViewController *chatHeadController = _messengerModule.chatHeadViewController; 187 | [chatHeadController resignChatHeadViews]; 188 | } 189 | 190 | NEW() 191 | - (void)mb_forceRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation { 192 | DebugLog(@"NEXT ORIENTATION: %d", (int)orientation); 193 | 194 | // Popover blows up when rotated 195 | FBChatHeadViewController *chatHeadController = _messengerModule.chatHeadViewController; 196 | [chatHeadController resignChatHeadViews]; 197 | 198 | [[UIApplication sharedApplication] setStatusBarOrientation:orientation]; 199 | 200 | for (UIWindow *window in [[UIApplication sharedApplication] windows]) { 201 | [window _setRotatableViewOrientation:orientation 202 | duration:0.0 203 | force:YES]; 204 | } 205 | 206 | /* 207 | Some crazy UIKeyboard hacks because for some reason UIKeyboard has a seizure when a suspended app tries to rotate... 208 | 209 | if orientation == 1 210 | revert to identity matrix 211 | if orientation == 2 212 | flip keyboard PI 213 | if orientation == 3 214 | flip keyboard PI/2 RAD 215 | set frame & bounds to screen size 216 | if orientation == 4 217 | flip keyboard -PI/2 RAD 218 | set frame & bounds to screen size 219 | */ 220 | 221 | UITextEffectsWindow *keyboardWindow = [UITextEffectsWindow sharedTextEffectsWindow]; 222 | 223 | switch (orientation) { 224 | case UIInterfaceOrientationPortrait: { 225 | keyboardWindow.transform = CGAffineTransformIdentity; 226 | break; 227 | } 228 | case UIInterfaceOrientationPortraitUpsideDown: { 229 | keyboardWindow.transform = CGAffineTransformMakeRotation(M_PI); 230 | break; 231 | } 232 | case UIInterfaceOrientationLandscapeLeft: { 233 | keyboardWindow.transform = CGAffineTransformMakeRotation(-M_PI / 2); 234 | keyboardWindow.bounds = [[UIScreen mainScreen] bounds]; 235 | keyboardWindow.frame = keyboardWindow.bounds; 236 | break; 237 | } 238 | case UIInterfaceOrientationLandscapeRight: { 239 | keyboardWindow.transform = CGAffineTransformMakeRotation(M_PI / 2); 240 | keyboardWindow.bounds = [[UIScreen mainScreen] bounds]; 241 | keyboardWindow.frame = keyboardWindow.bounds; 242 | break; 243 | } 244 | default: 245 | break; 246 | } 247 | 248 | [_messengerModule.chatHeadViewController.chatHeadSurfaceView performSelector:@selector(updateChatHeadsPosition) 249 | withObject:nil 250 | afterDelay:0.25f]; 251 | } 252 | 253 | END() 254 | 255 | HOOK(MessagesViewController) 256 | 257 | - (void)messageCell:(id)arg1 didSelectURL:(NSURL *)url { 258 | if (_UIHiddenForMessageBox_facebook && [url isKindOfClass:[NSURL class]] && url != nil) { 259 | [(AppDelegate *)[UIApplication sharedApplication].delegate mb_openURL:url]; 260 | } 261 | else { 262 | ORIG(); 263 | } 264 | } 265 | 266 | END() 267 | 268 | HOOK(FBChatHeadSurfaceView) 269 | 270 | - (void)setCurrentLayout:(FBChatHeadLayout *)currentLayout { 271 | CPDistributedMessagingCenter *sbMessagingCenter = [GET_CLASS(CPDistributedMessagingCenter) centerNamed:@"ca.adambell.MessageBox.sbMessagingCenter"]; 272 | rocketbootstrap_distributedmessagingcenter_apply(sbMessagingCenter); 273 | [sbMessagingCenter sendMessageName:@"messageboxUpdateChatHeadsState" userInfo:@{ @"opened" : @(currentLayout == self.openedLayout) }]; 274 | 275 | ORIG(); 276 | } 277 | 278 | END() 279 | 280 | HOOK(FBMessengerModule) 281 | 282 | // MOTHER OF METHOD 283 | // Totally not retyping this stupid thing with proper arguments :P 284 | - (id)initWithSession:(id)arg1 messengerModuleSessionProvider:(id)arg2 threadViewControllerProvider:(id)arg3 threadUserMapProvider:(id)arg4 jewelThreadListControllerProvider:(id)arg5 immersiveJewelThreadListControllerProvider:(id)arg6 threadSetProvider:(id)arg7 userSetProvider:(id)arg8 presenceNotificationManagerProvider:(id)arg9 authManagerProvider:(id)arg10 projectGatingChecker:(id)arg11 urlHandlerControllerProvider:(id)arg12 interstitialControllerProvider:(id)arg13 { 285 | id orig = ORIG(); 286 | _messengerModule = orig; 287 | return orig; 288 | } 289 | 290 | END() 291 | 292 | 293 | END_GROUP() 294 | -------------------------------------------------------------------------------- /Icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3ll/MessageBox/dd57cea1edcd3ab2001fde542682451e3082d513/Icon.psd -------------------------------------------------------------------------------- /MBChatHeadWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // MBChatHeadWindow.h 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-02-05. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MBChatHeadWindow : UIWindow { 13 | 14 | } 15 | 16 | + (instancetype)sharedInstance; 17 | 18 | - (void)hide; 19 | - (void)hideAnimated; 20 | - (void)show; 21 | - (void)showAnimated; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /MBChatHeadWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // MBChatHeadWindow.m 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-02-05. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import "MBChatHeadWindow.h" 10 | 11 | #define USE_SPRINGS 1 12 | #define CHAT_HEAD_TRANSITION_DELAY 0.5 13 | 14 | @interface MBChatHeadWindow () 15 | @end 16 | 17 | @implementation MBChatHeadWindow 18 | 19 | - (instancetype)init { 20 | self = [self initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | if (self != nil){ 22 | 23 | } 24 | 25 | return self; 26 | } 27 | 28 | + (instancetype)sharedInstance { 29 | static dispatch_once_t p = 0; 30 | 31 | __strong static id _sharedSelf = nil; 32 | 33 | dispatch_once(&p, ^{ 34 | _sharedSelf = [[self alloc] init]; 35 | }); 36 | 37 | return _sharedSelf; 38 | } 39 | 40 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 41 | //forward touches to everything beneath this window, unless a touch falls upon something within this windows subviews 42 | 43 | if (![[super hitTest:point withEvent:event] isKindOfClass:[MBChatHeadWindow class]]) { 44 | return [super hitTest:point withEvent:event]; 45 | } 46 | else { 47 | return nil; 48 | } 49 | } 50 | 51 | - (void)hide { 52 | self.hidden = YES; 53 | } 54 | 55 | - (void)show { 56 | self.hidden = NO; 57 | } 58 | 59 | - (void)hideAnimated { 60 | [self hide]; 61 | 62 | [self.layer removeAllAnimations]; 63 | 64 | CATransform3D scaleTransform = CATransform3DMakeScale(1.48, 1.48, 1.0); 65 | self.layer.transform = CATransform3DIdentity; 66 | 67 | #ifdef USE_SPRINGS 68 | [UIView animateWithDuration:0.6 69 | delay:0.0 70 | usingSpringWithDamping:0.8 71 | initialSpringVelocity:0.6 72 | options:0 73 | animations:^{ 74 | self.layer.transform = scaleTransform; 75 | } 76 | completion:nil]; 77 | #else 78 | [UIView animateWithDuration:0.4 79 | delay:0.0 80 | options:0 81 | animations:^{ 82 | self.layer.transform = scaleTransform; 83 | } 84 | completion:nil]; 85 | #endif 86 | } 87 | 88 | - (void)showAnimated { 89 | [self show]; 90 | 91 | [self.layer removeAllAnimations]; 92 | 93 | CATransform3D scaleTransform = CATransform3DMakeScale(1.48, 1.48, 1.0); 94 | self.layer.transform = scaleTransform; 95 | 96 | #ifdef USE_SPRINGS 97 | [UIView animateWithDuration:0.6 98 | delay:CHAT_HEAD_TRANSITION_DELAY 99 | usingSpringWithDamping:0.8 100 | initialSpringVelocity:0.6 101 | options:0 102 | animations:^{ 103 | self.layer.transform = CATransform3DIdentity; 104 | } 105 | completion:nil]; 106 | #else 107 | [UIView animateWithDuration:0.4 108 | delay:CHAT_HEAD_TRANSITION_DELAY 109 | options:0 110 | animations:^{ 111 | self.layer.transform = CATransform3DIdentity; 112 | } 113 | completion:nil]; 114 | #endif 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GO_EASY_ON_ME = 1 2 | THEOS_DEVICE_IP = 10.0.2.10 3 | THEOS_DEVICE_PORT = 22 4 | 5 | TARGET = iphone:clang:latest:7.0 6 | ARCHS = armv7 armv7s arm64 7 | 8 | include theos/makefiles/common.mk 9 | 10 | TWEAK_NAME = messagebox 11 | messagebox_CFLAGS = -fobjc-arc -IXcode-Theos 12 | messagebox_FILES = MBChatHeadWindow.m Tweak.xmi 13 | messagebox_LIBRARIES = substrate rocketbootstrap 14 | messagebox_FRAMEWORKS = Foundation CoreGraphics QuartzCore UIKit 15 | 16 | include $(THEOS_MAKE_PATH)/tweak.mk 17 | 18 | after-install:: 19 | install.exec "killall -9 backboardd" 20 | SUBPROJECTS += messageboxpreferences 21 | include $(THEOS_MAKE_PATH)/aggregate.mk 22 | -------------------------------------------------------------------------------- /MessageBox/MessageBox.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 66D1E06E18E35B9400AECE59 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66D1E06D18E35B9400AECE59 /* Foundation.framework */; }; 11 | 66D1E09718E35C1C00AECE59 /* Tweak.xmi in Sources */ = {isa = PBXBuildFile; fileRef = 66D1E09318E35BC500AECE59 /* Tweak.xmi */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 664C5D9718EA0CEC0057E987 /* UIKit.xm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; name = UIKit.xm; path = ../../UIKit.xm; sourceTree = ""; }; 16 | 6696275618E7537800F67BE4 /* Facebook.xm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; name = Facebook.xm; path = ../../Facebook.xm; sourceTree = ""; }; 17 | 66D1E06A18E35B9400AECE59 /* libMessageBox.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMessageBox.a; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | 66D1E06D18E35B9400AECE59 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 19 | 66D1E07118E35B9400AECE59 /* MessageBox-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MessageBox-Prefix.pch"; sourceTree = ""; }; 20 | 66D1E07B18E35B9400AECE59 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 21 | 66D1E07E18E35B9400AECE59 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 22 | 66D1E09318E35BC500AECE59 /* Tweak.xmi */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = Tweak.xmi; path = ../../Tweak.xmi; sourceTree = ""; }; 23 | 66D1E09418E35BD300AECE59 /* Paper.xm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = Paper.xm; path = ../../Paper.xm; sourceTree = ""; }; 24 | 66D1E09518E35BD300AECE59 /* SpringBoard.xm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = SpringBoard.xm; path = ../../SpringBoard.xm; sourceTree = ""; }; 25 | 66D1E09618E35BEA00AECE59 /* messagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = messagebox.h; path = ../../messagebox.h; sourceTree = ""; }; 26 | 66D1E09E18E362DA00AECE59 /* rocketbootstrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rocketbootstrap.h; path = /opt/theos/include/rocketbootstrap.h; sourceTree = ""; }; 27 | 66D1E09F18E362DA00AECE59 /* substrate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = substrate.h; path = /opt/theos/include/substrate.h; sourceTree = ""; }; 28 | /* End PBXFileReference section */ 29 | 30 | /* Begin PBXFrameworksBuildPhase section */ 31 | 66D1E06718E35B9400AECE59 /* Frameworks */ = { 32 | isa = PBXFrameworksBuildPhase; 33 | buildActionMask = 2147483647; 34 | files = ( 35 | 66D1E06E18E35B9400AECE59 /* Foundation.framework in Frameworks */, 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 66D1E06118E35B9300AECE59 = { 43 | isa = PBXGroup; 44 | children = ( 45 | 66D1E06F18E35B9400AECE59 /* MessageBox */, 46 | 66D1E06C18E35B9400AECE59 /* Frameworks */, 47 | 66D1E06B18E35B9400AECE59 /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | 66D1E06B18E35B9400AECE59 /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 66D1E06A18E35B9400AECE59 /* libMessageBox.a */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | 66D1E06C18E35B9400AECE59 /* Frameworks */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 66D1E06D18E35B9400AECE59 /* Foundation.framework */, 63 | 66D1E07B18E35B9400AECE59 /* XCTest.framework */, 64 | 66D1E07E18E35B9400AECE59 /* UIKit.framework */, 65 | ); 66 | name = Frameworks; 67 | sourceTree = ""; 68 | }; 69 | 66D1E06F18E35B9400AECE59 /* MessageBox */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 66D1E0A018E362DD00AECE59 /* Headers */, 73 | 66D1E09618E35BEA00AECE59 /* messagebox.h */, 74 | 66D1E09318E35BC500AECE59 /* Tweak.xmi */, 75 | 66D1E09418E35BD300AECE59 /* Paper.xm */, 76 | 66D1E09518E35BD300AECE59 /* SpringBoard.xm */, 77 | 6696275618E7537800F67BE4 /* Facebook.xm */, 78 | 664C5D9718EA0CEC0057E987 /* UIKit.xm */, 79 | 66D1E07018E35B9400AECE59 /* Supporting Files */, 80 | ); 81 | path = MessageBox; 82 | sourceTree = ""; 83 | }; 84 | 66D1E07018E35B9400AECE59 /* Supporting Files */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 66D1E07118E35B9400AECE59 /* MessageBox-Prefix.pch */, 88 | ); 89 | name = "Supporting Files"; 90 | sourceTree = ""; 91 | }; 92 | 66D1E0A018E362DD00AECE59 /* Headers */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 66D1E09E18E362DA00AECE59 /* rocketbootstrap.h */, 96 | 66D1E09F18E362DA00AECE59 /* substrate.h */, 97 | ); 98 | name = Headers; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 66D1E06918E35B9400AECE59 /* MessageBox */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 66D1E08D18E35B9400AECE59 /* Build configuration list for PBXNativeTarget "MessageBox" */; 107 | buildPhases = ( 108 | 66D1E06618E35B9400AECE59 /* Sources */, 109 | 66D1E06718E35B9400AECE59 /* Frameworks */, 110 | 66D1E09C18E35F5C00AECE59 /* ShellScript */, 111 | ); 112 | buildRules = ( 113 | ); 114 | dependencies = ( 115 | ); 116 | name = MessageBox; 117 | productName = MessageBox; 118 | productReference = 66D1E06A18E35B9400AECE59 /* libMessageBox.a */; 119 | productType = "com.apple.product-type.library.static"; 120 | }; 121 | /* End PBXNativeTarget section */ 122 | 123 | /* Begin PBXProject section */ 124 | 66D1E06218E35B9300AECE59 /* Project object */ = { 125 | isa = PBXProject; 126 | attributes = { 127 | LastUpgradeCheck = 0510; 128 | ORGANIZATIONNAME = "Adam Bell"; 129 | }; 130 | buildConfigurationList = 66D1E06518E35B9300AECE59 /* Build configuration list for PBXProject "MessageBox" */; 131 | compatibilityVersion = "Xcode 3.2"; 132 | developmentRegion = English; 133 | hasScannedForEncodings = 0; 134 | knownRegions = ( 135 | en, 136 | ); 137 | mainGroup = 66D1E06118E35B9300AECE59; 138 | productRefGroup = 66D1E06B18E35B9400AECE59 /* Products */; 139 | projectDirPath = ""; 140 | projectRoot = ""; 141 | targets = ( 142 | 66D1E06918E35B9400AECE59 /* MessageBox */, 143 | ); 144 | }; 145 | /* End PBXProject section */ 146 | 147 | /* Begin PBXShellScriptBuildPhase section */ 148 | 66D1E09C18E35F5C00AECE59 /* ShellScript */ = { 149 | isa = PBXShellScriptBuildPhase; 150 | buildActionMask = 2147483647; 151 | files = ( 152 | ); 153 | inputPaths = ( 154 | ); 155 | outputPaths = ( 156 | ); 157 | runOnlyForDeploymentPostprocessing = 0; 158 | shellPath = /bin/sh; 159 | shellScript = "PATH=${PATH}:/opt/local/bin\ncd ../\nmake clean package install"; 160 | }; 161 | /* End PBXShellScriptBuildPhase section */ 162 | 163 | /* Begin PBXSourcesBuildPhase section */ 164 | 66D1E06618E35B9400AECE59 /* Sources */ = { 165 | isa = PBXSourcesBuildPhase; 166 | buildActionMask = 2147483647; 167 | files = ( 168 | 66D1E09718E35C1C00AECE59 /* Tweak.xmi in Sources */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | /* End PBXSourcesBuildPhase section */ 173 | 174 | /* Begin XCBuildConfiguration section */ 175 | 66D1E08B18E35B9400AECE59 /* Debug */ = { 176 | isa = XCBuildConfiguration; 177 | buildSettings = { 178 | ALWAYS_SEARCH_USER_PATHS = NO; 179 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 180 | CLANG_CXX_LIBRARY = "libc++"; 181 | CLANG_ENABLE_MODULES = YES; 182 | CLANG_ENABLE_OBJC_ARC = YES; 183 | CLANG_WARN_BOOL_CONVERSION = YES; 184 | CLANG_WARN_CONSTANT_CONVERSION = YES; 185 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 186 | CLANG_WARN_EMPTY_BODY = YES; 187 | CLANG_WARN_ENUM_CONVERSION = YES; 188 | CLANG_WARN_INT_CONVERSION = YES; 189 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 190 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 191 | COPY_PHASE_STRIP = NO; 192 | GCC_C_LANGUAGE_STANDARD = gnu99; 193 | GCC_DYNAMIC_NO_PIC = NO; 194 | GCC_OPTIMIZATION_LEVEL = 0; 195 | GCC_PREPROCESSOR_DEFINITIONS = ( 196 | "DEBUG=1", 197 | "$(inherited)", 198 | ); 199 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 200 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 201 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 202 | GCC_WARN_UNDECLARED_SELECTOR = YES; 203 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 204 | GCC_WARN_UNUSED_FUNCTION = YES; 205 | GCC_WARN_UNUSED_VARIABLE = YES; 206 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 207 | ONLY_ACTIVE_ARCH = YES; 208 | SDKROOT = iphoneos; 209 | }; 210 | name = Debug; 211 | }; 212 | 66D1E08C18E35B9400AECE59 /* Release */ = { 213 | isa = XCBuildConfiguration; 214 | buildSettings = { 215 | ALWAYS_SEARCH_USER_PATHS = NO; 216 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 217 | CLANG_CXX_LIBRARY = "libc++"; 218 | CLANG_ENABLE_MODULES = YES; 219 | CLANG_ENABLE_OBJC_ARC = YES; 220 | CLANG_WARN_BOOL_CONVERSION = YES; 221 | CLANG_WARN_CONSTANT_CONVERSION = YES; 222 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 223 | CLANG_WARN_EMPTY_BODY = YES; 224 | CLANG_WARN_ENUM_CONVERSION = YES; 225 | CLANG_WARN_INT_CONVERSION = YES; 226 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 227 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 228 | COPY_PHASE_STRIP = YES; 229 | ENABLE_NS_ASSERTIONS = NO; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 232 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 233 | GCC_WARN_UNDECLARED_SELECTOR = YES; 234 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 235 | GCC_WARN_UNUSED_FUNCTION = YES; 236 | GCC_WARN_UNUSED_VARIABLE = YES; 237 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 238 | SDKROOT = iphoneos; 239 | VALIDATE_PRODUCT = YES; 240 | }; 241 | name = Release; 242 | }; 243 | 66D1E08E18E35B9400AECE59 /* Debug */ = { 244 | isa = XCBuildConfiguration; 245 | buildSettings = { 246 | ALWAYS_SEARCH_USER_PATHS = YES; 247 | DSTROOT = /tmp/MessageBox.dst; 248 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 249 | ONLY_ACTIVE_ARCH = NO; 250 | OTHER_CFLAGS = ( 251 | "-include", 252 | /opt/theos/include/substrate.h, 253 | "-include", 254 | /opt/theos/include/rocketbootstrap.h, 255 | ); 256 | OTHER_LDFLAGS = "-ObjC"; 257 | PRODUCT_NAME = "$(TARGET_NAME)"; 258 | SKIP_INSTALL = YES; 259 | USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../Xcode-Theos/"; 260 | }; 261 | name = Debug; 262 | }; 263 | 66D1E08F18E35B9400AECE59 /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = YES; 267 | DSTROOT = /tmp/MessageBox.dst; 268 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 269 | OTHER_CFLAGS = ( 270 | "-include", 271 | /opt/theos/include/substrate.h, 272 | "-include", 273 | /opt/theos/include/rocketbootstrap.h, 274 | ); 275 | OTHER_LDFLAGS = "-ObjC"; 276 | PRODUCT_NAME = "$(TARGET_NAME)"; 277 | SKIP_INSTALL = YES; 278 | USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../Xcode-Theos/"; 279 | }; 280 | name = Release; 281 | }; 282 | /* End XCBuildConfiguration section */ 283 | 284 | /* Begin XCConfigurationList section */ 285 | 66D1E06518E35B9300AECE59 /* Build configuration list for PBXProject "MessageBox" */ = { 286 | isa = XCConfigurationList; 287 | buildConfigurations = ( 288 | 66D1E08B18E35B9400AECE59 /* Debug */, 289 | 66D1E08C18E35B9400AECE59 /* Release */, 290 | ); 291 | defaultConfigurationIsVisible = 0; 292 | defaultConfigurationName = Release; 293 | }; 294 | 66D1E08D18E35B9400AECE59 /* Build configuration list for PBXNativeTarget "MessageBox" */ = { 295 | isa = XCConfigurationList; 296 | buildConfigurations = ( 297 | 66D1E08E18E35B9400AECE59 /* Debug */, 298 | 66D1E08F18E35B9400AECE59 /* Release */, 299 | ); 300 | defaultConfigurationIsVisible = 0; 301 | defaultConfigurationName = Release; 302 | }; 303 | /* End XCConfigurationList section */ 304 | }; 305 | rootObject = 66D1E06218E35B9300AECE59 /* Project object */; 306 | } 307 | -------------------------------------------------------------------------------- /MessageBox/MessageBox.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MessageBox/MessageBox/MessageBox-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /Paper.xm: -------------------------------------------------------------------------------- 1 | // 2 | // Paper.xm 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-02-04. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import "messagebox.h" 10 | 11 | #define KEYBOARD_WINDOW_LEVEL 1003.0f 12 | 13 | static FBApplicationController *_applicationController; 14 | static FBMessengerModule *_messengerModule_paper; 15 | 16 | static BOOL _shouldShowPublisherBar_paper = NO; 17 | 18 | static BOOL _ignoreBackgroundedNotifications_paper = YES; 19 | 20 | static BOOL _UIHiddenForMessageBox_paper; 21 | 22 | /** 23 | * Paper Hooks 24 | * 25 | */ 26 | GROUP(PaperHooks) 27 | 28 | static void paperResignChatHeads(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 29 | FBApplicationController *controller = [GET_CLASS(FBApplicationController) mb_sharedInstance]; 30 | [controller.messengerModule.chatHeadViewController resignChatHeadViews]; 31 | [[UIApplication sharedApplication].keyWindow endEditing:YES]; 32 | } 33 | 34 | static void paperForceActive(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 35 | _ignoreBackgroundedNotifications_paper = YES; 36 | FBApplicationController *controller = [GET_CLASS(FBApplicationController) mb_sharedInstance]; 37 | [controller.messengerModule.moduleSession enteredForeground]; 38 | } 39 | 40 | static void paperForceBackgrounded(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 41 | _ignoreBackgroundedNotifications_paper = NO; 42 | [[[UIApplication sharedApplication] delegate] applicationDidEnterBackground:[UIApplication sharedApplication]]; 43 | [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil userInfo:nil]; 44 | } 45 | 46 | // Keyboards also need to be shown when the app is backgrounded 47 | HOOK(UITextEffectsWindow) 48 | 49 | - (id)init { 50 | UITextEffectsWindow *window = ORIG(); 51 | [window setKeepContextInBackground:YES]; 52 | return window; 53 | } 54 | 55 | - (void)setKeepContextInBackground:(BOOL)keepContext { 56 | ORIG(YES); 57 | } 58 | 59 | - (BOOL)keepContextInBackground { 60 | return YES; 61 | } 62 | 63 | // Paper does some weird shit with window levels... no u 64 | - (CGFloat)windowLevel { 65 | return KEYBOARD_WINDOW_LEVEL; 66 | } 67 | 68 | - (void)setWindowLevel:(CGFloat)windowLevel { 69 | ORIG(KEYBOARD_WINDOW_LEVEL); 70 | } 71 | 72 | END() 73 | 74 | // Since UIMenuItems hate being displayed for some odd reason when an app is in a hosted view, force them to always appear... #yolo 75 | HOOK(UICalloutBar) 76 | - (void)expandAfterAlertOrBecomeActive:(id)arg1 { 77 | [self setValue:@(YES) forKey:@"m_shouldAppear"]; 78 | } 79 | 80 | - (void)flattenForAlertOrResignActive:(id)arg1 { 81 | [self setValue:@(YES) forKey:@"m_shouldAppear"]; 82 | } 83 | END() 84 | 85 | // Need to force the app to believe it's still active... no notifications for you! >:D 86 | HOOK(NSNotificationCenter) 87 | 88 | - (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo { 89 | NSString *notification = [notificationName lowercaseString]; 90 | if ([notification rangeOfString:@"background"].location != NSNotFound && _ignoreBackgroundedNotifications_paper) { 91 | notify_post("ca.adambell.messagebox.paperQuitting"); 92 | 93 | [[UIApplication sharedApplication].keyWindow endEditing:YES]; 94 | 95 | FBApplicationController *controller = [GET_CLASS(FBApplicationController) mb_sharedInstance]; 96 | [controller mb_setUIHiddenForMessageBox:YES]; 97 | 98 | return; 99 | } 100 | 101 | DebugLog(@"Notification Posted: %@ object: %@ userInfo: %@", notificationName, notificationSender, userInfo); 102 | 103 | ORIG(); 104 | } 105 | 106 | END() 107 | 108 | HOOK(UIApplication) 109 | 110 | - (UIApplicationState)applicationState { 111 | if (_ignoreBackgroundedNotifications_paper) { 112 | return UIApplicationStateActive; 113 | } 114 | else { 115 | return (UIApplicationState)ORIG_T(); 116 | } 117 | } 118 | 119 | END() 120 | 121 | HOOK(AppDelegate) 122 | 123 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 124 | for (UIWindow *window in application.windows) { 125 | [window setKeepContextInBackground:YES]; 126 | } 127 | 128 | return ORIG_T(); 129 | } 130 | 131 | - (void)applicationDidBecomeActive:(UIApplication *)application { 132 | notify_post("ca.adambell.messagebox.paperLaunching"); 133 | DebugLog(@"PAPER OPENING RIGHT NOW"); 134 | 135 | FBApplicationController *controller = [GET_CLASS(FBApplicationController) mb_sharedInstance]; 136 | [controller mb_setUIHiddenForMessageBox:NO]; 137 | 138 | ORIG(); 139 | } 140 | 141 | END() 142 | 143 | HOOK(FBApplicationController) 144 | 145 | - (id)initWithSession:(id)session { 146 | _applicationController = ORIG(); 147 | return _applicationController; 148 | } 149 | 150 | NEW() 151 | + (id)mb_sharedInstance { 152 | return _applicationController; 153 | } 154 | 155 | NEW() 156 | - (void)mb_setUIHiddenForMessageBox:(BOOL)hidden { 157 | _UIHiddenForMessageBox_paper = hidden; 158 | 159 | [[UIApplication sharedApplication].keyWindow setKeepContextInBackground:hidden]; 160 | 161 | [UIApplication sharedApplication].keyWindow.backgroundColor = hidden ? [UIColor clearColor] : [UIColor blackColor]; 162 | 163 | FBChatHeadViewController *chatHeadController = self.messengerModule.chatHeadViewController; 164 | [chatHeadController resignChatHeadViews]; 165 | [chatHeadController setHasInboxChatHead:hidden]; 166 | 167 | FBStackView *stackView = (FBStackView *)chatHeadController.view; 168 | UIView *chatHeadContainerView = stackView; 169 | 170 | while (![stackView isKindOfClass:GET_CLASS(FBStackView)]) { 171 | if (stackView.superview == nil) 172 | break; 173 | 174 | chatHeadContainerView = stackView; 175 | stackView = (FBStackView *)stackView.superview; 176 | } 177 | 178 | for (UIView *view in stackView.subviews) { 179 | if (view != chatHeadContainerView && ![view isKindOfClass:GET_CLASS(FBDimmingView)]) 180 | view.hidden = hidden; 181 | } 182 | 183 | // Account for status bar 184 | CGRect chatHeadWindowFrame = [UIScreen mainScreen].bounds; 185 | if (hidden) { 186 | chatHeadWindowFrame.origin.y += 20.0; 187 | chatHeadWindowFrame.size.height -= 20.0; 188 | } 189 | 190 | self.messengerModule.chatHeadViewController.chatHeadSurfaceView.frame = chatHeadWindowFrame; 191 | 192 | for (UIView *subview in [UIApplication sharedApplication].keyWindow.subviews) { 193 | [subview setNeedsLayout]; 194 | } 195 | 196 | _shouldShowPublisherBar_paper = hidden; 197 | } 198 | 199 | NEW() 200 | - (void)mb_openURL:(NSURL *)url { 201 | CPDistributedMessagingCenter *sbMessagingCenter = [GET_CLASS(CPDistributedMessagingCenter) centerNamed:@"ca.adambell.MessageBox.sbMessagingCenter"]; 202 | rocketbootstrap_distributedmessagingcenter_apply(sbMessagingCenter); 203 | 204 | [sbMessagingCenter sendMessageName:@"messageboxOpenURL" userInfo:@{ @"url" : [url absoluteString] }]; 205 | 206 | FBChatHeadViewController *chatHeadController = self.messengerModule.chatHeadViewController; 207 | [chatHeadController resignChatHeadViews]; 208 | } 209 | 210 | NEW() 211 | - (void)mb_forceRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation { 212 | DebugLog(@"NEXT ORIENTATION: %d", (int)orientation); 213 | 214 | // Popover blows up when rotated 215 | FBChatHeadViewController *chatHeadController = self.messengerModule.chatHeadViewController; 216 | [chatHeadController resignChatHeadViews]; 217 | 218 | [[UIApplication sharedApplication] setStatusBarOrientation:orientation]; 219 | 220 | for (UIWindow *window in [[UIApplication sharedApplication] windows]) { 221 | [window _setRotatableViewOrientation:orientation 222 | duration:0.0 223 | force:YES]; 224 | } 225 | 226 | /* 227 | Some crazy UIKeyboard hacks because for some reason UIKeyboard has a seizure when a suspended app tries to rotate... 228 | 229 | if orientation == 1 230 | revert to identity matrix 231 | if orientation == 2 232 | flip keyboard PI 233 | if orientation == 3 234 | flip keyboard PI/2 RAD 235 | set frame & bounds to screen size 236 | if orientation == 4 237 | flip keyboard -PI/2 RAD 238 | set frame & bounds to screen size 239 | */ 240 | 241 | UITextEffectsWindow *keyboardWindow = [UITextEffectsWindow sharedTextEffectsWindow]; 242 | 243 | switch (orientation) { 244 | case UIInterfaceOrientationPortrait: { 245 | keyboardWindow.transform = CGAffineTransformIdentity; 246 | break; 247 | } 248 | case UIInterfaceOrientationPortraitUpsideDown: { 249 | keyboardWindow.transform = CGAffineTransformMakeRotation(M_PI); 250 | break; 251 | } 252 | case UIInterfaceOrientationLandscapeLeft: { 253 | keyboardWindow.transform = CGAffineTransformMakeRotation(-M_PI / 2); 254 | keyboardWindow.bounds = [[UIScreen mainScreen] bounds]; 255 | keyboardWindow.frame = keyboardWindow.bounds; 256 | break; 257 | } 258 | case UIInterfaceOrientationLandscapeRight: { 259 | keyboardWindow.transform = CGAffineTransformMakeRotation(M_PI / 2); 260 | keyboardWindow.bounds = [[UIScreen mainScreen] bounds]; 261 | keyboardWindow.frame = keyboardWindow.bounds; 262 | break; 263 | } 264 | default: 265 | break; 266 | } 267 | } 268 | 269 | END() 270 | 271 | HOOK(FBMInboxViewController) 272 | 273 | - (void)viewWillAppear:(BOOL)animated { 274 | ORIG(); 275 | 276 | self.inboxView.showPublisherBar = 0; 277 | } 278 | 279 | END() 280 | 281 | HOOK(FBMInboxView) 282 | 283 | - (void)setShowPublisherBar:(BOOL)showPublisherBar { 284 | ORIG([self mb_shouldShowPublisherBar]); 285 | } 286 | 287 | NEW() 288 | - (BOOL)mb_shouldShowPublisherBar { 289 | return _shouldShowPublisherBar_paper; 290 | } 291 | 292 | END() 293 | 294 | HOOK(FBChatHeadSurfaceView) 295 | 296 | - (void)setCurrentLayout:(FBChatHeadLayout *)currentLayout { 297 | CPDistributedMessagingCenter *sbMessagingCenter = [GET_CLASS(CPDistributedMessagingCenter) centerNamed:@"ca.adambell.MessageBox.sbMessagingCenter"]; 298 | rocketbootstrap_distributedmessagingcenter_apply(sbMessagingCenter); 299 | [sbMessagingCenter sendMessageName:@"messageboxUpdateChatHeadsState" userInfo:@{ @"opened" : @(currentLayout == self.openedLayout) }]; 300 | 301 | ORIG(); 302 | } 303 | 304 | - (void)setFrame:(CGRect)frame { 305 | if (_UIHiddenForMessageBox_paper) { 306 | CGRect chatHeadWindowFrame = [UIScreen mainScreen].bounds; 307 | if (_UIHiddenForMessageBox_paper) { 308 | chatHeadWindowFrame.origin.y += 20.0; 309 | chatHeadWindowFrame.size.height -= 20.0; 310 | } 311 | 312 | ORIG(chatHeadWindowFrame); 313 | } 314 | else { 315 | ORIG(); 316 | } 317 | } 318 | 319 | END() 320 | 321 | HOOK_AND_DECLARE(MessagesViewController, UIViewController) 322 | 323 | - (void)messageCell:(id)arg1 didSelectURL:(NSURL *)url { 324 | if (_UIHiddenForMessageBox_paper && [url isKindOfClass:[NSURL class]] && url != nil) { 325 | FBApplicationController *applicationController = [GET_CLASS(FBApplicationController) mb_sharedInstance]; 326 | [applicationController mb_openURL:url]; 327 | } 328 | else { 329 | ORIG(); 330 | } 331 | } 332 | 333 | END() 334 | 335 | END_GROUP() 336 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | # MessageBox 2 | ## Breaking Facebook's Chat Heads out of the iOS Sandbox 3 | 4 | ### Intro 5 | MessageBox is a jailbreak extension for iOS that allows users to use Facebook Messenger's Chat Heads system-wide in iOS. Currently this only works in conjunction with [Paper](https://facebook.com/paper/) and iOS 7. 6 | 7 | [The Verge](http://www.theverge.com/2013/4/17/4235816/chat-heads-for-iphone-jailbreak-tweak) approves! :P 8 | 9 | For more technical info I did a [blog post](http://blog.adambell.ca/post/73338421921/breaking-chat-heads-out-of-the-ios-sandbox) as well! 10 | 11 | The [original hack](https://github.com/b3ll/MessageBox-olde) has been deprecated and will no longer be supported, however back-porting a lot of this to iOS 6 shouldn't be too difficult (for those of you still on iOS 6). 12 | 13 | ### How do I MessageBox? 14 | Open Paper, wait for everything to appear, press the Home button. Magic! :D 15 | 16 | **If you open the app and close it super quickly, you're going to have a bad time!** 17 | 18 | ![MessageBox Preview GIF](readme/messageboxPreview.gif) 19 | 20 | ### Price? 21 | Totally free! If you'd like to support my continuation of this project (and others!), feel free to [donate](http://www.adambell.ca/donate)! It'd be much appreciated :D 22 | 23 | ### How do I get? 24 | It's on Cydia under the BigBoss repo! 25 | 26 | ### How do I compile? 27 | [@DHowett](https://www.twitter.com/DHowett) was very sad when he realized I didn't use [theos](https://www.github.com/DHowett/theos) for my initial version of MessageBox, and seeing as how it's now the suggested route for [Cydia Substrate](http://cydiasubstrate.com/) so I've switched to that (though, I'm using [@rpetrich's fork](https://www.github.com/rpetrich/theos) since it's nicer for working with universal builds). 28 | 29 | Once you've got that setup, (nice writeup [here](http://iphonedevwiki.net/index.php/Theos/Getting_Started)) change the Makefile to your liking. After that simply run: 30 | 31 | THEOS_DEVICE_IP= THEOS_DEVICE_PORT= make package install 32 | 33 | ### License? 34 | Pretty much the BSD license, just don't repackage it and call it your own please! 35 | 36 | Also if you do make some changes, feel free to make a pull request and help make things more awesome! 37 | 38 | ### Contact Info? 39 | If you have any support requests please feel free to email me at messagebox[at]adambell[dot]me. 40 | 41 | Otherwise, feel free to follow me on twitter: [@b3ll](https:///www.twitter.com/b3ll)! 42 | 43 | ### Special Thanks 44 | me :P 45 | Facebook, for being awesome. 46 | -------------------------------------------------------------------------------- /SpringBoard.xm: -------------------------------------------------------------------------------- 1 | // 2 | // SpringBoard.xm 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-02-04. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import "messagebox.h" 10 | #import "MBChatHeadWindow.h" 11 | 12 | /** 13 | * SpringBoard Hooks 14 | * 15 | */ 16 | 17 | static MBChatHeadWindow *_chatHeadWindow; 18 | static BKSProcessAssertion *_keepAlive; 19 | 20 | static __weak SBWindowContextHostWrapperView *_hostView; 21 | 22 | static BOOL _chatHeadPopoverCanBeDismissed; 23 | 24 | GROUP(SpringBoardHooks) 25 | 26 | static void fbDidTapChatHead(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 27 | SBIconController *iconController = [GET_CLASS(SBIconController) sharedInstance]; 28 | 29 | //If icons are wiggling and a chat head is tapped, stop the wiggling 30 | if (iconController.isEditing) 31 | [iconController setIsEditing:NO]; 32 | } 33 | 34 | static void fbLaunching(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 35 | [[GET_CLASS(SBUIController) sharedInstance] mb_removeChatHeadWindow]; 36 | } 37 | 38 | static void fbQuitting(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 39 | /*if ([(__bridge NSString*)name rangeOfString:@"paper"].location != NSNotFound) 40 | [[GET_CLASS(SBUIController) sharedInstance] mb_addChatHeadWindowForApp:@"Paper"]; 41 | else 42 | [[GET_CLASS(SBUIController) sharedInstance] mb_addChatHeadWindowForApp:@"Facebook"];*/ 43 | } 44 | 45 | HOOK_AND_DECLARE(SBWorkspace, NSObject) 46 | 47 | - (void)workspace:(id)arg1 applicationSuspended:(NSString *)bundleIdentifier withSettings:(id)arg3 { 48 | if ([bundleIdentifier isEqualToString:@"com.facebook.Facebook"]) { 49 | [[GET_CLASS(SBUIController) sharedInstance] mb_addChatHeadWindowForApp:@"Facebook"]; 50 | } 51 | 52 | if ([bundleIdentifier isEqualToString:@"com.facebook.Paper"]) { 53 | [[GET_CLASS(SBUIController) sharedInstance] mb_addChatHeadWindowForApp:@"Paper"]; 54 | } 55 | 56 | UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 57 | forceFacebookApplicationRotation(orientation); 58 | 59 | ORIG(); 60 | } 61 | 62 | END() 63 | 64 | HOOK(SBUIController) 65 | 66 | //Stack up the chat heads when the home button is pressed 67 | 68 | - (BOOL)clickedMenuButton { 69 | //To keep in app as stock as possible, don't intercept the home button when the app is active 70 | //So only take action if FB is active but in the background 71 | if ([_keepAlive valid] && _chatHeadPopoverCanBeDismissed) { 72 | notify_post("ca.adambell.messagebox.paperResignChatHeads"); 73 | notify_post("ca.adambell.messagebox.fbResignChatHeads"); 74 | return YES; 75 | } 76 | 77 | return ORIG_T(); 78 | } 79 | 80 | - (BOOL)handleMenuDoubleTap { 81 | if ([_keepAlive valid]) { 82 | notify_post("ca.adambell.messagebox.paperResignChatHeads"); 83 | notify_post("ca.adambell.messagebox.fbResignChatHeads"); 84 | } 85 | 86 | return ORIG_T(); 87 | } 88 | 89 | - (id)init { 90 | SBUIController *controller = ORIG(); 91 | 92 | [[NSNotificationCenter defaultCenter] addObserver:self 93 | selector:@selector(mb_screenOn:) 94 | name:@"SBLockScreenUndimmedNotification" 95 | object:nil]; 96 | [[NSNotificationCenter defaultCenter] addObserver:self 97 | selector:@selector(mb_screenOff:) 98 | name:@"SBLockScreenDimmedNotification" 99 | object:nil]; 100 | 101 | CPDistributedMessagingCenter *sbMessagingCenter = [GET_CLASS(CPDistributedMessagingCenter) centerNamed:@"ca.adambell.MessageBox.sbMessagingCenter"]; 102 | rocketbootstrap_distributedmessagingcenter_apply(sbMessagingCenter); 103 | [sbMessagingCenter runServerOnCurrentThread]; 104 | [sbMessagingCenter registerForMessageName:@"messageboxOpenURL" 105 | target:self 106 | selector:@selector(mb_handleMessageBoxMessage:withUserInfo:)]; 107 | [sbMessagingCenter registerForMessageName:@"messageboxUpdateChatHeadsState" 108 | target:self 109 | selector:@selector(mb_updateChatHeadsState:withUserInfo:)]; 110 | 111 | return controller; 112 | } 113 | 114 | NEW() 115 | - (void)mb_handleMessageBoxMessage:(NSString *)message withUserInfo:(NSDictionary *)userInfo { 116 | if ([message isEqualToString:@"messageboxOpenURL"]) { 117 | NSString *urlString = userInfo[@"url"]; 118 | 119 | if (urlString != nil) { 120 | NSURL *url = [NSURL URLWithString:urlString]; 121 | 122 | if (url != nil) { 123 | [[UIApplication sharedApplication] openURL:url]; 124 | } 125 | } 126 | } 127 | } 128 | 129 | NEW() 130 | - (void)mb_updateChatHeadsState:(NSString *)message withUserInfo:(NSDictionary *)userInfo { 131 | if ([message isEqualToString:@"messageboxUpdateChatHeadsState"]) { 132 | NSNumber *chatHeadsPopoverOpened = userInfo[@"opened"]; 133 | 134 | if (chatHeadsPopoverOpened != nil) { 135 | _chatHeadPopoverCanBeDismissed = chatHeadsPopoverOpened.boolValue; 136 | } 137 | } 138 | } 139 | 140 | NEW() 141 | - (void)mb_screenOn:(NSNotification *)notification { 142 | notify_post("ca.adambell.messagebox.fbForceActive"); 143 | notify_post("ca.adambell.messagebox.paperForceActive"); 144 | } 145 | 146 | NEW() 147 | - (void)mb_screenOff:(NSNotification *)notification { 148 | notify_post("ca.adambell.messagebox.fbForceBackground"); 149 | notify_post("ca.adambell.messagebox.paperForceBackground"); 150 | } 151 | 152 | NEW() 153 | - (void)mb_addChatHeadWindowForApp:(NSString *)appName { 154 | int facebookPID = PIDForProcessNamed(appName); 155 | if (facebookPID == 0) 156 | return; 157 | 158 | if (_keepAlive != nil) 159 | [_keepAlive invalidate]; 160 | 161 | _keepAlive = [[GET_CLASS(BKSProcessAssertion) alloc] initWithPID:facebookPID 162 | flags:(ProcessAssertionFlagPreventSuspend | 163 | ProcessAssertionFlagAllowIdleSleep | 164 | ProcessAssertionFlagPreventThrottleDownCPU | 165 | ProcessAssertionFlagWantsForegroundResourcePriority) 166 | reason:kProcessAssertionReasonBackgroundUI 167 | name:@"epichax" 168 | withHandler:^void (void) 169 | { 170 | DebugLog(@"FACEBOOK PID: %d kept alive: %@", facebookPID, [_keepAlive valid] > 0 ? @"TRUE" : @"FALSE"); 171 | }]; 172 | 173 | // Remove hosting if we try to add it again, don't want double hosted views! 174 | if (_hostView != nil) { 175 | SBWindowContextHostManager *manager = [_hostView valueForKey:@"_manager"]; 176 | [manager disableHostingForRequester:@"hax"]; 177 | } 178 | 179 | SBApplication *facebookApplication = [[GET_CLASS(SBApplicationController) sharedInstance] applicationWithDisplayIdentifier:[NSString stringWithFormat:@"com.facebook.%@", appName]]; 180 | 181 | SBWindowContextHostManager *contextHostManager = [facebookApplication mainScreenContextHostManager]; 182 | 183 | SBWindowContextHostWrapperView *facebookHostView = [contextHostManager hostViewForRequester:@"hax" enableAndOrderFront: YES]; 184 | facebookHostView.backgroundColorWhileNotHosting = [UIColor clearColor]; 185 | facebookHostView.backgroundColorWhileHosting = [UIColor clearColor]; 186 | 187 | _hostView = facebookHostView; 188 | 189 | for (UIView *subview in facebookHostView.subviews) { 190 | subview.backgroundColor = [UIColor clearColor]; 191 | } 192 | 193 | for (UIView *subview in [_chatHeadWindow.subviews copy]) { 194 | [subview removeFromSuperview]; 195 | } 196 | 197 | [_chatHeadWindow addSubview:facebookHostView]; 198 | 199 | [NSObject cancelPreviousPerformRequestsWithTarget:_chatHeadWindow 200 | selector:@selector(showAnimated) 201 | object:nil]; 202 | [_chatHeadWindow performSelector:@selector(showAnimated) 203 | withObject:nil 204 | afterDelay:0.2]; 205 | } 206 | 207 | NEW() 208 | - (void)mb_removeChatHeadWindow { 209 | if (_keepAlive != nil) { 210 | // Kill the BKSProcessAssertion because it isn't needed anymore 211 | // Not sure if creating / removing it is necessary but I'd like to keep it as stock as possible when in app) 212 | 213 | [_keepAlive invalidate]; 214 | _keepAlive = nil; 215 | 216 | // Remove Paper (if necessary) 217 | SBApplication *facebookApplication = [[GET_CLASS(SBApplicationController) sharedInstance] applicationWithDisplayIdentifier:@"com.facebook.Paper"]; 218 | 219 | if (facebookApplication != nil) { 220 | SBWindowContextHostManager *contextHostManager = [facebookApplication mainScreenContextHostManager]; 221 | [contextHostManager disableHostingForRequester:@"hax"]; 222 | } 223 | 224 | // Remove Facebook (if necessary) 225 | facebookApplication = [[GET_CLASS(SBApplicationController) sharedInstance] applicationWithDisplayIdentifier:@"com.facebook.Facebook"]; 226 | 227 | if (facebookApplication != nil) { 228 | SBWindowContextHostManager *contextHostManager = [facebookApplication mainScreenContextHostManager]; 229 | [contextHostManager disableHostingForRequester:@"hax"]; 230 | } 231 | 232 | for (UIView *subview in [[MBChatHeadWindow sharedInstance].subviews copy]) { 233 | [subview removeFromSuperview]; 234 | } 235 | } 236 | 237 | [_chatHeadWindow hide]; 238 | } 239 | 240 | END() 241 | 242 | HOOK_AND_DECLARE(SBAppSliderController, NSObject) 243 | 244 | - (void)switcherWillBeDismissed:(BOOL)arg1 { 245 | [[MBChatHeadWindow sharedInstance] showAnimated]; 246 | ORIG(); 247 | } 248 | 249 | - (void)switcherWasPresented:(BOOL)arg1 { 250 | notify_post("ca.adambell.messagebox.paperResignChatHeads"); 251 | notify_post("ca.adambell.messagebox.fbResignChatHeads"); 252 | [[MBChatHeadWindow sharedInstance] hideAnimated]; 253 | ORIG(); 254 | } 255 | 256 | END() 257 | 258 | HOOK(UIWindow) 259 | 260 | - (void)makeKeyAndVisible { 261 | ORIG(); 262 | 263 | if (self != _chatHeadWindow) { 264 | if (_chatHeadWindow == nil) { 265 | _chatHeadWindow = [MBChatHeadWindow sharedInstance]; 266 | _chatHeadWindow.backgroundColor = [UIColor clearColor]; 267 | } 268 | 269 | _chatHeadWindow.windowLevel = 10; //1 below UIKeyboard //UIWindowLevelStatusBar; 270 | _chatHeadWindow.hidden = NO; 271 | _chatHeadWindow.backgroundColor = [UIColor clearColor]; 272 | } 273 | } 274 | 275 | END() 276 | 277 | HOOK(SBIconController) 278 | 279 | - (void)didRotateFromInterfaceOrientation:(long long)interfaceOrientation { 280 | ORIG(); 281 | 282 | UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 283 | forceFacebookApplicationRotation(orientation); 284 | } 285 | 286 | END() 287 | 288 | END_GROUP() 289 | -------------------------------------------------------------------------------- /Tweak.xmi: -------------------------------------------------------------------------------- 1 | // 2 | // Tweak.xm 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-02-04. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import "messagebox.h" 10 | 11 | #define ROTATION_PORTRAIT_NOTIFICATION "ca.adambell.messagebox.fbShouldRotatePortrait" 12 | #define ROTATION_PORTRAIT_UPSIDEDOWN_NOTIFICATION "ca.adambell.messagebox.fbShouldRotatePortraitUpsideDown" 13 | #define ROTATION_LANDSCAPE_LEFT_NOTIFICATION "ca.adambell.messagebox.fbShouldRotateLandscapeLeft" 14 | #define ROTATION_LANDSCAPE_RIGHT_NOTIFICATION "ca.adambell.messagebox.fbShouldRotateLandscapeRight" 15 | 16 | #define DEVICE_ORIENTATION_CHANGED_NOTIFICATION "ca.adambell.messagebox.fbShouldRotateToDeviceOrientation" 17 | 18 | #define PUSH_NOTIFICATION_RECEIVED "ca.adambell.messagebox.pushNotificationReceived" 19 | #define GENERAL_PUSH_NOTIFICATION_RECEIVED "ca.adambell.messagebox.generalPushNotificationReceived" 20 | 21 | #define KEY_ENABLED @"messageBoxEnabled" 22 | #define KEY_FORCE_ENABLED @"messageBoxForceEnabled" 23 | #define KEY_USE_PAPER @"messageBoxPaperEnabled" 24 | #define KEY_USE_FACEBOOK @"messageBoxFacebookEnabled" 25 | 26 | #define MESSAGE_BOX_PREFERENCES_PATH @"/User/Library/Preferences/ca.adambell.messagebox.plist" 27 | 28 | #define MAX_SUPPORTED_VERSION_PAPER @"1.0.2" 29 | #define MAX_SUPPORTED_VERSION_FACEBOOK @"8.0" 30 | 31 | extern "C" int xpc_connection_get_pid(id connection); 32 | 33 | #include "UIKit.xm" 34 | #include "Paper.xm" 35 | #include "Facebook.xm" 36 | #include "SpringBoard.xm" 37 | 38 | /** 39 | * backboardd Hooks 40 | * 41 | */ 42 | 43 | #define XPCObjects "/System/Library/PrivateFrameworks/XPCObjects.framework/XPCObjects" 44 | 45 | CONFIG(generator=MobileSubstrate); 46 | 47 | GROUP(backboarddHooks) 48 | 49 | static NSDictionary *_prefs; 50 | 51 | static int (*orig_XPConnectionHasEntitlement)(id connection, NSString *entitlement); 52 | 53 | static int fb_XPConnectionHasEntitlement(id connection, NSString *entitlement) { 54 | DebugLog(@"XPCConnectionHasEntitlement... no u"); 55 | 56 | //Only grant the required entitlement 57 | if (xpc_connection_get_pid(connection) == PIDForProcessNamed(@"SpringBoard") && [entitlement isEqualToString:@"com.apple.multitasking.unlimitedassertions"]) 58 | return true; 59 | 60 | return orig_XPConnectionHasEntitlement(connection, entitlement); 61 | } 62 | 63 | END_GROUP() 64 | 65 | static BOOL versionNumberIsSupported() { 66 | NSString *versionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 67 | NSString *maxSupportedVersion = nil; 68 | 69 | if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.facebook.Paper"]) { 70 | maxSupportedVersion = MAX_SUPPORTED_VERSION_PAPER; 71 | } 72 | else if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.facebook.Facebook"]) { 73 | maxSupportedVersion = MAX_SUPPORTED_VERSION_FACEBOOK; 74 | } 75 | else { 76 | return NO; 77 | } 78 | 79 | BOOL supported = YES; 80 | if (([versionString compare:maxSupportedVersion options:NSNumericSearch] == NSOrderedDescending)) { 81 | if (![_prefs[KEY_FORCE_ENABLED] boolValue]) { 82 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"MessageBox" 83 | message:@"Looks like you're using an unsupported version, MessageBox has been disabled :(\n\nYou can attempt to re-enable it using \"Ignore Version Check\" in Settings or wait for an updated version." 84 | delegate:nil 85 | cancelButtonTitle:@"OK" 86 | otherButtonTitles:nil]; 87 | [alertView performSelector:@selector(show) 88 | withObject:nil 89 | afterDelay:5.0]; 90 | supported = NO; 91 | } 92 | 93 | } 94 | 95 | return supported; 96 | } 97 | 98 | static void messageBoxPrefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 99 | _prefs = [[NSDictionary alloc] initWithContentsOfFile:MESSAGE_BOX_PREFERENCES_PATH]; 100 | } 101 | 102 | CTOR() { 103 | _prefs = [[NSDictionary alloc] initWithContentsOfFile:MESSAGE_BOX_PREFERENCES_PATH]; 104 | 105 | if (_prefs == nil) { 106 | _prefs = @{ KEY_ENABLED : @(YES), 107 | KEY_FORCE_ENABLED : @(NO), 108 | KEY_USE_PAPER : @(YES), 109 | KEY_USE_FACEBOOK : @(YES) }; 110 | [_prefs writeToFile:MESSAGE_BOX_PREFERENCES_PATH atomically:YES]; 111 | } 112 | 113 | if (_prefs[KEY_USE_FACEBOOK] == nil) { 114 | NSMutableDictionary *prefs = [_prefs mutableCopy]; 115 | prefs[KEY_USE_FACEBOOK] = @(YES); 116 | _prefs = [prefs copy]; 117 | } 118 | 119 | if (_prefs[KEY_USE_PAPER] == nil) { 120 | NSMutableDictionary *prefs = [_prefs mutableCopy]; 121 | prefs[KEY_USE_PAPER] = @(YES); 122 | _prefs = [prefs copy]; 123 | } 124 | 125 | if (![_prefs[KEY_ENABLED] boolValue]) { 126 | return; 127 | } 128 | 129 | CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter(); 130 | CFNotificationCenterAddObserver(darwin, NULL, messageBoxPrefsChanged, CFSTR("ca.adambell.messagebox.preferences-changed"), NULL, CFNotificationSuspensionBehaviorCoalesce); 131 | 132 | BOOL needsUIKitHooks = NO; 133 | NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; 134 | 135 | if ([bundleIdentifier isEqualToString:@"com.facebook.Paper"]) { 136 | if (![_prefs[KEY_USE_PAPER] boolValue] || !versionNumberIsSupported()) { 137 | return; 138 | } 139 | 140 | INIT(PaperHooks); 141 | 142 | CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter(); 143 | CFNotificationCenterAddObserver(darwin, NULL, paperResignChatHeads, CFSTR("ca.adambell.messagebox.paperResignChatHeads"), NULL, CFNotificationSuspensionBehaviorCoalesce); 144 | CFNotificationCenterAddObserver(darwin, NULL, paperForceActive, CFSTR("ca.adambell.messagebox.paperForceActive"), NULL, CFNotificationSuspensionBehaviorCoalesce); 145 | CFNotificationCenterAddObserver(darwin, NULL, paperForceBackgrounded, CFSTR("ca.adambell.messagebox.paperForceBackgrounded"), NULL, CFNotificationSuspensionBehaviorCoalesce); 146 | } 147 | else if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.facebook.Facebook"]) { 148 | // Placeholder for Facebook App 149 | if (![_prefs[KEY_USE_FACEBOOK] boolValue] || !versionNumberIsSupported()) { 150 | NSLog(@"GOT HERE SOMEHOW"); 151 | return; 152 | } 153 | 154 | INIT(FacebookHooks); 155 | 156 | CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter(); 157 | CFNotificationCenterAddObserver(darwin, NULL, fbResignChatHeads, CFSTR("ca.adambell.messagebox.fbResignChatHeads"), NULL, CFNotificationSuspensionBehaviorCoalesce); 158 | CFNotificationCenterAddObserver(darwin, NULL, fbForceActive, CFSTR("ca.adambell.messagebox.fbForceActive"), NULL, CFNotificationSuspensionBehaviorCoalesce); 159 | CFNotificationCenterAddObserver(darwin, NULL, fbForceBackgrounded, CFSTR("ca.adambell.messagebox.fbForceBackgrounded"), NULL, CFNotificationSuspensionBehaviorCoalesce); 160 | 161 | // Rotation Handling 162 | CFNotificationCenterAddObserver(darwin, NULL, fbShouldRotate, CFSTR(ROTATION_PORTRAIT_NOTIFICATION), NULL, CFNotificationSuspensionBehaviorCoalesce); 163 | CFNotificationCenterAddObserver(darwin, NULL, fbShouldRotate, CFSTR(ROTATION_PORTRAIT_UPSIDEDOWN_NOTIFICATION), NULL, CFNotificationSuspensionBehaviorCoalesce); 164 | CFNotificationCenterAddObserver(darwin, NULL, fbShouldRotate, CFSTR(ROTATION_LANDSCAPE_LEFT_NOTIFICATION), NULL, CFNotificationSuspensionBehaviorCoalesce); 165 | CFNotificationCenterAddObserver(darwin, NULL, fbShouldRotate, CFSTR(ROTATION_LANDSCAPE_RIGHT_NOTIFICATION), NULL, CFNotificationSuspensionBehaviorCoalesce); 166 | 167 | } 168 | else if ([bundleIdentifier isEqualToString:@"com.apple.springboard"]) { 169 | needsUIKitHooks = YES; 170 | 171 | INIT(SpringBoardHooks); 172 | 173 | DebugLog(@"BEGIN MESSAGEBOX HOOKS YAY"); 174 | 175 | CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter(); 176 | CFNotificationCenterAddObserver(darwin, NULL, fbLaunching, CFSTR("ca.adambell.messagebox.fbLaunching"), NULL, CFNotificationSuspensionBehaviorCoalesce); 177 | CFNotificationCenterAddObserver(darwin, NULL, fbLaunching, CFSTR("ca.adambell.messagebox.paperLaunching"), NULL, CFNotificationSuspensionBehaviorCoalesce); 178 | 179 | CFNotificationCenterAddObserver(darwin, NULL, fbQuitting, CFSTR("ca.adambell.messagebox.paperQuitting"), NULL, CFNotificationSuspensionBehaviorCoalesce); 180 | CFNotificationCenterAddObserver(darwin, NULL, fbQuitting, CFSTR("ca.adambell.messagebox.fbQuitting"), NULL, CFNotificationSuspensionBehaviorCoalesce); 181 | 182 | CFNotificationCenterAddObserver(darwin, NULL, fbDidTapChatHead, CFSTR("ca.adambell.MessageBox.fbDidTapChatHead"), NULL, CFNotificationSuspensionBehaviorCoalesce); 183 | 184 | DebugLog(@"END MESSAGEBOX HOOKS YAY"); 185 | } 186 | else if ([bundleIdentifier isEqualToString:@"com.apple.backboardd"]) { 187 | INIT(backboarddHooks); 188 | 189 | dlopen(XPCObjects, RTLD_LAZY); 190 | 191 | void *xpcFunction = MSFindSymbol(NULL, "_XPCConnectionHasEntitlement"); 192 | 193 | MSHookFunction(xpcFunction, (void *)fb_XPConnectionHasEntitlement, (void **)&orig_XPConnectionHasEntitlement); 194 | } 195 | else { 196 | needsUIKitHooks = YES; 197 | } 198 | 199 | if (needsUIKitHooks) { 200 | INIT(UIKitHooks); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /UIKit.xm: -------------------------------------------------------------------------------- 1 | // 2 | // UIKit.xm 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-03-31. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import "messagebox.h" 10 | 11 | GROUP(UIKitHooks) 12 | 13 | static void forceFacebookApplicationRotation(UIInterfaceOrientation orientation) { 14 | switch (orientation){ 15 | case UIInterfaceOrientationPortrait: 16 | notify_post(ROTATION_PORTRAIT_NOTIFICATION); 17 | break; 18 | case UIInterfaceOrientationPortraitUpsideDown: 19 | notify_post(ROTATION_PORTRAIT_UPSIDEDOWN_NOTIFICATION); 20 | break; 21 | case UIInterfaceOrientationLandscapeLeft: 22 | notify_post(ROTATION_LANDSCAPE_LEFT_NOTIFICATION); 23 | break; 24 | case UIInterfaceOrientationLandscapeRight: 25 | notify_post(ROTATION_LANDSCAPE_RIGHT_NOTIFICATION); 26 | break; 27 | default: 28 | notify_post(ROTATION_PORTRAIT_NOTIFICATION); 29 | break; 30 | } 31 | } 32 | 33 | HOOK(UIViewController) 34 | 35 | - (void)_willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration forwardToChildControllers:(BOOL)forwardToChildControllers skipSelf:(BOOL)skipSelf { 36 | ORIG(); 37 | 38 | forceFacebookApplicationRotation(orientation); 39 | } 40 | 41 | END() 42 | 43 | END_GROUP() 44 | -------------------------------------------------------------------------------- /layout/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: ca.adambell.messagebox 2 | Name: messagebox 3 | Depends: mobilesubstrate, com.rpetrich.rocketbootstrap, firmware (>= 7.0) 4 | Version: 2.0 5 | Architecture: iphoneos-arm 6 | Description: MessageBox is a jailbreak extension for iOS that allows users to use Facebook Messenger's Chat Heads system-wide in iOS. 7 | Maintainer: Adam Bell 8 | Author: Adam Bell 9 | Section: Tweaks 10 | -------------------------------------------------------------------------------- /layout/Library/MobileSubstrate/DynamicLibraries/messagebox.plist: -------------------------------------------------------------------------------- 1 | { 2 | Filter = { 3 | Bundles = ( 4 | "com.facebook.Paper", 5 | "com.apple.springboard", 6 | "com.facebook.Facebook", 7 | "com.apple.UIKit", 8 | ); 9 | Executables = ( 10 | backboardd, 11 | ); 12 | Mode = Any; 13 | }; 14 | } -------------------------------------------------------------------------------- /messagebox.h: -------------------------------------------------------------------------------- 1 | // 2 | // messagebox.h 3 | // MessageBox 4 | // 5 | // Created by Adam Bell on 2014-02-04. 6 | // Copyright (c) 2014 Adam Bell. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #import "substrate.h" 21 | #import "rocketbootstrap.h" 22 | 23 | #import 24 | 25 | #ifdef DEBUG 26 | #define DebugLog(str, ...) NSLog(str, ##__VA_ARGS__) 27 | #else 28 | #define DebugLog(str, ...) 29 | #endif 30 | 31 | @interface UIApplication (openURL) 32 | - (void)applicationOpenURL:(NSURL *)url; 33 | @end 34 | 35 | @interface UIWindow (backgroundContext) 36 | - (void)setKeepContextInBackground:(BOOL)keepContext; 37 | - (void)_setRotatableViewOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration force:(BOOL)force; 38 | @end 39 | 40 | @interface UITextEffectsWindow : UIWindow 41 | + (UITextEffectsWindow *)preferredTextEffectsWindow; 42 | + (UITextEffectsWindow *)sharedTextEffectsWindow; 43 | 44 | - (void)setKeepContextInBackground:(BOOL)keepContext; 45 | @end 46 | 47 | @interface UICalloutBar : UIView 48 | @end 49 | 50 | @interface CPDistributedMessagingCenter : NSObject 51 | + (CPDistributedMessagingCenter *)centerNamed:(NSString *)name; 52 | - (void)runServerOnCurrentThread; 53 | - (void)registerForMessageName:(NSString *)name target:(id)target selector:(SEL)selector; 54 | - (void)sendMessageName:(NSString *)message userInfo:(NSDictionary *)userInfo; 55 | - (NSDictionary *)sendMessageAndReceiveReplyName:(NSString *)reply userInfo:(NSDictionary *)dictionary; 56 | @end 57 | 58 | @interface SBWindowContextHostWrapperView : UIView 59 | @property(nonatomic, strong) UIColor *backgroundColorWhileNotHosting; 60 | @property(nonatomic, strong) UIColor *backgroundColorWhileHosting; 61 | @end 62 | 63 | @interface SBWindowContextHostManager : NSObject 64 | - (SBWindowContextHostWrapperView *)hostViewForRequester:(NSString *)requester enableAndOrderFront:(BOOL)enableAndOrderFront; 65 | - (void)disableHostingForRequester:(NSString *)requester; 66 | @end 67 | 68 | @interface SBApplication : NSObject 69 | - (SBWindowContextHostManager *)mainScreenContextHostManager; 70 | @end 71 | 72 | @interface SBApplicationController : NSObject 73 | + (instancetype)sharedInstance; 74 | - (SBApplication *)applicationWithDisplayIdentifier:(NSString *)identifier; 75 | @end 76 | 77 | @interface SBIconController : NSObject 78 | + (instancetype)sharedInstance; 79 | 80 | - (void)setIsEditing:(BOOL)editing; 81 | - (BOOL)isEditing; 82 | @end 83 | 84 | @interface SBUIController : NSObject 85 | + (instancetype)sharedInstance; 86 | 87 | - (void)mb_addChatHeadWindowForApp:(NSString *)appName; 88 | - (void)mb_removeChatHeadWindow; 89 | @end 90 | 91 | @interface BKProcessAssertion : NSObject 92 | - (instancetype)initWithReason:(unsigned int)arg1 identifier:(id)arg2; 93 | - (void)setWantsForegroundResourcePriority:(BOOL)arg1; 94 | - (void)setPreventThrottleDownCPU:(BOOL)arg1; 95 | - (void)setPreventThrottleDownUI:(BOOL)arg1; 96 | - (void)setPreventSuspend:(BOOL)arg1; 97 | - (void)setAllowIdleSleepOverrideEnabled:(BOOL)arg1; 98 | - (void)setPreventIdleSleep:(BOOL)arg1; 99 | - (void)setFlags:(unsigned int)arg1; 100 | - (void)invalidate; 101 | @end 102 | 103 | @interface BKSProcessAssertion : NSObject 104 | + (instancetype)NameForReason:(unsigned int)arg1; 105 | - (void)queue_notifyAssertionAcquired:(BOOL)arg1; 106 | - (void)queue_updateAssertion; 107 | - (void)queue_acquireAssertion; 108 | - (void)queue_registerWithServer; 109 | - (void)queue_invalidate:(BOOL)arg1; 110 | - (void)invalidate; 111 | - (void)setReason:(unsigned int)arg1; 112 | - (void)setValid:(BOOL)arg1; 113 | - (void)setFlags:(unsigned int)arg1; 114 | - (int)valid; 115 | - (instancetype)initWithPID:(int)arg1 flags:(unsigned int)arg2 reason:(unsigned int)arg3 name:(id)arg4 withHandler:(id)arg5; 116 | - (instancetype)initWithBundleIdentifier:(id)arg1 flags:(unsigned int)arg2 reason:(unsigned int)arg3 name:(id)arg4 withHandler:(id)arg5; 117 | - (instancetype)init; 118 | @end 119 | 120 | typedef NS_ENUM(NSUInteger, BKSProcessAssertionReason) 121 | { 122 | kProcessAssertionReasonAudio = 1, 123 | kProcessAssertionReasonLocation, 124 | kProcessAssertionReasonExternalAccessory, 125 | kProcessAssertionReasonFinishTask, 126 | kProcessAssertionReasonBluetooth, 127 | kProcessAssertionReasonNetworkAuthentication, 128 | kProcessAssertionReasonBackgroundUI, 129 | kProcessAssertionReasonInterAppAudioStreaming, 130 | kProcessAssertionReasonViewServices 131 | }; 132 | 133 | typedef NS_ENUM(NSUInteger, ProcessAssertionFlags) 134 | { 135 | ProcessAssertionFlagNone = 0, 136 | ProcessAssertionFlagPreventSuspend = 1 << 0, 137 | ProcessAssertionFlagPreventThrottleDownCPU = 1 << 1, 138 | ProcessAssertionFlagAllowIdleSleep = 1 << 2, 139 | ProcessAssertionFlagWantsForegroundResourcePriority = 1 << 3 140 | }; 141 | 142 | @interface FBChatHeadLayout : NSObject 143 | @end 144 | 145 | @interface FBChatHeadSurfaceView : UIView 146 | @property (nonatomic) BOOL hasComposer; 147 | @property(nonatomic) FBChatHeadLayout *currentLayout; 148 | 149 | @property(nonatomic, strong) FBChatHeadLayout *defaultLayout; 150 | @property(nonatomic, strong) FBChatHeadLayout *closedLayout; 151 | @property(nonatomic, strong) FBChatHeadLayout *openedLayout; 152 | 153 | - (void)sortChatHeads; 154 | - (void)updateChatHeadsPosition; 155 | @end 156 | 157 | @interface FBChatHeadViewController : UIViewController 158 | @property (nonatomic) BOOL hasInboxChatHead; 159 | 160 | - (FBChatHeadSurfaceView *)chatHeadSurfaceView; 161 | - (void)showComposerChatHead; 162 | - (void)resignChatHeadViews; 163 | @end 164 | 165 | @interface FBMessengerModuleSession : NSObject 166 | - (void)enteredForeground; 167 | @end 168 | 169 | @interface FBMessengerModule : NSObject 170 | - (FBChatHeadViewController *)chatHeadViewController; 171 | @property (nonatomic, strong) FBMessengerModuleSession *moduleSession; 172 | @end 173 | 174 | @interface FBApplicationController : NSObject 175 | + (instancetype)mb_sharedInstance; 176 | 177 | - (FBMessengerModule *)messengerModule; 178 | 179 | - (void)mb_setUIHiddenForMessageBox:(BOOL)hidden; 180 | - (void)mb_openURL:(NSURL *)url; 181 | @end 182 | 183 | @interface FBStackView : UIView 184 | @end 185 | 186 | @interface FBMInboxView : UIView 187 | @property(nonatomic) BOOL showPublisherBar; 188 | 189 | - (BOOL)mb_shouldShowPublisherBar; 190 | @end 191 | 192 | @interface FBMInboxViewController : UIViewController 193 | 194 | @property(nonatomic, strong) FBMInboxView *inboxView; 195 | @end 196 | 197 | @interface AppDelegate : NSObject 198 | - (void)mb_setUIHiddenForMessageBox:(BOOL)hidden; 199 | - (void)mb_openURL:(NSURL *)url; 200 | - (void)mb_forceRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation; 201 | @end 202 | 203 | inline int PIDForProcessNamed(NSString *passedInProcessName) { 204 | // Thanks to http://stackoverflow.com/questions/6610705/how-to-get-process-id-in-iphone-or-ipad 205 | // Faster than ps,grep,etc 206 | 207 | int pid = 0; 208 | 209 | int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; 210 | size_t miblen = 4; 211 | 212 | size_t size; 213 | int st = sysctl(mib, (u_int)miblen, NULL, &size, NULL, 0); 214 | 215 | struct kinfo_proc * process = NULL; 216 | struct kinfo_proc * newprocess = NULL; 217 | 218 | do { 219 | 220 | size += size / 10; 221 | newprocess = (kinfo_proc *)realloc(process, size); 222 | 223 | if (!newprocess) { 224 | if (process) { 225 | free(process); 226 | } 227 | return 0; 228 | } 229 | 230 | process = newprocess; 231 | st = sysctl(mib, (u_int)miblen, process, &size, NULL, 0); 232 | 233 | } while (st == -1 && errno == ENOMEM); 234 | 235 | if (st == 0) { 236 | 237 | if (size % sizeof(struct kinfo_proc) == 0) { 238 | int nprocess = (int)(size / sizeof(struct kinfo_proc)); 239 | 240 | if (nprocess) { 241 | for (int i = nprocess - 1; i >= 0; i--) { 242 | NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm]; 243 | 244 | if ([processName rangeOfString:passedInProcessName].location != NSNotFound) { 245 | pid = process[i].kp_proc.p_pid; 246 | } 247 | } 248 | 249 | free(process); 250 | } 251 | } 252 | } 253 | if (pid == 0) { 254 | DebugLog(@"GET PROCESS %@ FAILED.", [passedInProcessName uppercaseString]); 255 | } 256 | 257 | return pid; 258 | } 259 | -------------------------------------------------------------------------------- /messagebox.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "follow_symlinks": false, 6 | "path": ".", 7 | "file_exclude_patterns": [ 8 | "*.deb", 9 | ".gitignore" 10 | ], 11 | "folder_exclude_patterns": [ 12 | "_", 13 | "obj", 14 | "theos", 15 | ".theos" 16 | ] 17 | } 18 | ], 19 | "settings": 20 | { 21 | "show_panel_on_build": true 22 | }, 23 | "build_systems": 24 | [ 25 | { 26 | "name": "THEOS make package install", 27 | "shell_cmd": "make clean && make package install", 28 | "shell": false, 29 | "working_dir": "${project_path}" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /messagebox.sublime-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "auto_complete": 3 | { 4 | "selected_items": 5 | [ 6 | [ 7 | "Face", 8 | "facebookPreviouslyEnabled" 9 | ], 10 | [ 11 | "KEY_SE", 12 | "KEY_USE_FACEBOOK" 13 | ], 14 | [ 15 | "KEY", 16 | "KEY_FORCE_ENABLED" 17 | ], 18 | [ 19 | "PAP", 20 | "paperEnabled" 21 | ], 22 | [ 23 | "notif", 24 | "SBLockScreenDimmedNotification" 25 | ], 26 | [ 27 | "CATra", 28 | "CATransform3DIdentity" 29 | ], 30 | [ 31 | "CATransf", 32 | "CATransform3D" 33 | ], 34 | [ 35 | "scale", 36 | "scaleTransform" 37 | ], 38 | [ 39 | "mb_screen", 40 | "mb_screenOn" 41 | ], 42 | [ 43 | "keepCon", 44 | "setKeepContextInBackground" 45 | ], 46 | [ 47 | "FBChatHead", 48 | "FBChatHeadLayoutLine" 49 | ], 50 | [ 51 | "notifica", 52 | "notificationSender" 53 | ], 54 | [ 55 | "selector", 56 | "notificationSelector" 57 | ], 58 | [ 59 | "notifia", 60 | "notificationName" 61 | ], 62 | [ 63 | "application", 64 | "applicationWillEnterForeground" 65 | ], 66 | [ 67 | "MBChatHead", 68 | "MBChatHeadWindow.h" 69 | ], 70 | [ 71 | "facebook", 72 | "facebookHostView" 73 | ], 74 | [ 75 | "chatHead", 76 | "chatHeadContainerView" 77 | ], 78 | [ 79 | "stack", 80 | "stackView" 81 | ], 82 | [ 83 | "chatHeadCont", 84 | "chatHeadContainerview" 85 | ], 86 | [ 87 | "_", 88 | "_chatHeadViewController" 89 | ], 90 | [ 91 | "ret", 92 | "return" 93 | ], 94 | [ 95 | "mess", 96 | "messagebox.plist" 97 | ] 98 | ] 99 | }, 100 | "buffers": 101 | [ 102 | { 103 | "file": "messagebox.h", 104 | "settings": 105 | { 106 | "buffer_size": 7569, 107 | "line_ending": "Unix" 108 | } 109 | }, 110 | { 111 | "file": "Makefile", 112 | "settings": 113 | { 114 | "buffer_size": 566, 115 | "line_ending": "Unix" 116 | } 117 | }, 118 | { 119 | "file": "messagebox.sublime-project", 120 | "settings": 121 | { 122 | "buffer_size": 676, 123 | "line_ending": "Unix" 124 | } 125 | }, 126 | { 127 | "file": "Tweak.xmi", 128 | "settings": 129 | { 130 | "buffer_size": 9237, 131 | "line_ending": "Unix" 132 | } 133 | }, 134 | { 135 | "file": "SpringBoard.xm", 136 | "settings": 137 | { 138 | "buffer_size": 10776, 139 | "line_ending": "Unix" 140 | } 141 | }, 142 | { 143 | "file": "MBChatHeadWindow.m", 144 | "settings": 145 | { 146 | "buffer_size": 2795, 147 | "line_ending": "Unix" 148 | } 149 | }, 150 | { 151 | "file": "MBChatHeadWindow.h", 152 | "settings": 153 | { 154 | "buffer_size": 358, 155 | "line_ending": "Unix" 156 | } 157 | }, 158 | { 159 | "file": "Facebook.xm", 160 | "settings": 161 | { 162 | "buffer_size": 10246, 163 | "line_ending": "Unix" 164 | } 165 | }, 166 | { 167 | "file": "messageboxpreferences/messageboxpreferences.mm", 168 | "settings": 169 | { 170 | "buffer_size": 3132, 171 | "line_ending": "Unix" 172 | } 173 | } 174 | ], 175 | "build_system": "THEOS make package install", 176 | "command_palette": 177 | { 178 | "height": 400.0, 179 | "selected_items": 180 | [ 181 | [ 182 | "markdown", 183 | "Markdown Preview: Python Markdown: Preview in Browser" 184 | ], 185 | [ 186 | "install", 187 | "Package Control: Install Package" 188 | ], 189 | [ 190 | "remove pack", 191 | "Package Control: Remove Package" 192 | ], 193 | [ 194 | "pdf", 195 | "LaTeXTools: View PDF" 196 | ], 197 | [ 198 | "remove", 199 | "Package Control: Remove Package" 200 | ], 201 | [ 202 | "latex", 203 | "LaTeXTools: View PDF" 204 | ], 205 | [ 206 | "isntall", 207 | "Package Control: Install Package" 208 | ], 209 | [ 210 | "livereload", 211 | "LiveReload: Enable/disable plug-ins" 212 | ], 213 | [ 214 | "LiveReload: Enable/disable plugins", 215 | "LiveReload: Enable/disable plug-ins" 216 | ], 217 | [ 218 | "live", 219 | "LiveReload: Self test" 220 | ], 221 | [ 222 | "preview", 223 | "Markdown Preview: Python Markdown: Preview in Browser" 224 | ], 225 | [ 226 | "sublime", 227 | "Preferences: SublimeLint Settings – Default" 228 | ], 229 | [ 230 | "gist", 231 | "Package Control: Install Package" 232 | ], 233 | [ 234 | "instal", 235 | "Package Control: Install Package" 236 | ] 237 | ], 238 | "width": 655.0 239 | }, 240 | "console": 241 | { 242 | "height": 139.0, 243 | "history": 244 | [ 245 | "PluginFactory.listPlugins", 246 | "PluginFactory", 247 | "PluginFactor", 248 | "import urllib.request,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)", 249 | "import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'" 250 | ] 251 | }, 252 | "distraction_free": 253 | { 254 | "menu_visible": true, 255 | "show_minimap": false, 256 | "show_open_files": false, 257 | "show_tabs": false, 258 | "side_bar_visible": false, 259 | "status_bar_visible": false 260 | }, 261 | "file_history": 262 | [ 263 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/.git/COMMIT_EDITMSG", 264 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/README.mdown", 265 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/messagebox.sublime-project", 266 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/MBChatHeadWindow.h", 267 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/MBChatHeadWindow.m", 268 | "/Users/Adam/Dropbox/Dev/Sublime/User/Logos.tmLanguage", 269 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/Tweak.xm", 270 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/User/Logos.tmLanguage", 271 | "/Users/Adam/Dropbox/Dev/Sublime/User/SolarSooty (SL).tmTheme", 272 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/Default/Default (OSX).sublime-keymap", 273 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/Default/Preferences.sublime-settings", 274 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/User/Preferences.sublime-settings", 275 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/messagebox.plist", 276 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/Makefile", 277 | "/Users/Adam/Dropbox/Dev/iOS/Jailbreak_Dev/messagebox/backboarddHooks.xm", 278 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/User/JSON.sublime-settings", 279 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/AppDelegate.h", 280 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/AVAudioPlayerDelegate-Protocol.h", 281 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/Appirater.h", 282 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBGrpHackCajmereIsEnglishOnlySorryWeWillSupportOtherLanguagesSoon.h", 283 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBGraphQLConnection-Protocol.h", 284 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBGroup.h", 285 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBPhotoBottomGradientLayer.h", 286 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMemBookmark.h", 287 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/Facebook.h", 288 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBDirectionalPanGestureRecognizerDelegate-Protocol.h", 289 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBOpenGraphObjectMemProtocol-Protocol.h", 290 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBOpenGraphActionMemProtocol-Protocol.h", 291 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBPhotoGridCellProtocol-Protocol.h", 292 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBBugReportScreenshotListViewDelegate-Protocol.h", 293 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBBugReportModalViewControllerPresenting-Protocol.h", 294 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBOpenGraphObjectProtocol-Protocol.h", 295 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBOpenGraphAvatarEntity-Protocol.h", 296 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBOpenGraphActionProtocol-Protocol.h", 297 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBLiveGraphQLSessionDelegate-Protocol.h", 298 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBOpenGraphEntity-Protocol.h", 299 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBBugReportComposerDelegate-Protocol.h", 300 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBBugReportCategoriesDelegate-Protocol.h", 301 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMLeaveGroupThreadRequesterDelegate-Protocol.h", 302 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/GroupPinnedStoriesEdgeFragment.h", 303 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/GroupPinnedStoriesConnectionFragment.h", 304 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/GCDAsyncReadPacket.h", 305 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/GCDAsyncSocket.h", 306 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBAppModuleManager.h", 307 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBAppModule-Protocol.h", 308 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBApplication.h", 309 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBAPIResponse.h", 310 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBTabBarAnimatedNuxView.h", 311 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBBackboardView.h", 312 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBCropBottomBar.h", 313 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBManagedObject.h", 314 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBFaceBoxMemProtocol-Protocol.h", 315 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UINavigationController-FBAnalytics.h", 316 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/ZREmbeddedMapInterstitialViewController.h", 317 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/ZREmbeddedInterstitialPlaceholderViewController.h", 318 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBQuickPromotionInterstitialStepViewControllerDelegate-Protocol.h", 319 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UIViewController-FBAnalytics.h", 320 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBContactImporterInterstitialViewControllerDelegate-Protocol.h", 321 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBZeroOptinInterstitialViewController.h", 322 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInterstitialViewController.h", 323 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UIViewController-FBSwipeNavigationController.h", 324 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMessengerInterstitialViewController.h", 325 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/ZREmbeddedInterstitialViewController.h", 326 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UIViewController-NoAutolayout.h", 327 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMessengerInterstitialController.h", 328 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/MNInvalidTokenErrorNotificationHandler.h", 329 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBZeroOptinInterstitialViewControllerDelegate-Protocol.h", 330 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMessengerInterstitialViewControllerDelegate-Protocol.h", 331 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBNuxInterstitialViewController.h", 332 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBSupportedInterfaceOrientations-Protocol.h", 333 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/_FBInteractorsConnectionCoreDataProtocol-Protocol.h", 334 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/_FBInteractorsConnectionMemProtocol-Protocol.h", 335 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/_FBInteractorsConnectionProtocol-Protocol.h", 336 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInteractorsConnectionCoreDataProtocol-Protocol.h", 337 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInteractorsConnectionMemProtocol-Protocol.h", 338 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInteractorsConnectionProtocol-Protocol.h", 339 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/_FBMemInteractorsConnectionBuilder.h", 340 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMemInteractorsConnectionBuilder.h", 341 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInteractivePhotoNodeDelegate-Protocol.h", 342 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBStoryMetricsCalculatorCacheInternal.h", 343 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInterationLagLogger-Protocol.h", 344 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInterationLagAnalyticsLogger.h", 345 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInteractionLagTracker.h", 346 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBInteractionLagLogger.h", 347 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/PSTLegacyCollectionViewInternalPendingAnimation.h", 348 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UIViewController-FBBubbleControllerInternal.h", 349 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/ZRTariffedUxSessionInternal-Protocol.h", 350 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/NSMutableAttributedString-StoryStringsInternal.h", 351 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMStickerHelperInternal.h", 352 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UIView-FBViewNodeInternal.h", 353 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/CALayer-FBViewNodeInternal.h", 354 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBMTextViewInternal.h", 355 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/UIViewController-FBPopoverController_Internal.h", 356 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/FBNuxInterstitial.h", 357 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/InAppNotificationTapDelegate-Protocol.h", 358 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/InAppNotificationManager.h", 359 | "/Users/Adam/Downloads/fb/fb/Payload/PaperHeaders/Identifier.h", 360 | "/Users/Adam/Downloads/Logarithms.tex", 361 | "/Users/Adam/Downloads/Logarithms.latex", 362 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/User/Default (OSX).sublime-keymap", 363 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/Stratus-Info.plist", 364 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/Stratus-Prefix.pch", 365 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAWeatherForecast.h", 366 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SASolarActivityIndicator.h", 367 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SACrossfadingImageView.h", 368 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAAppDelegate.h", 369 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAWeatherLocation.m", 370 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAWeatherLocation.h", 371 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAWeatherForecast.m", 372 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAWeatherAPI.m", 373 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAWeatherAPI.h", 374 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAViewController.m", 375 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAViewController.h", 376 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SASolarActivityIndicator.m", 377 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SASearchScrollView.m", 378 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SASearchScrollView.h", 379 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SACrossfadingImageView.m", 380 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SABlurryTableViewCell.m", 381 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SABlurryTableViewCell.h", 382 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SABlurryTableView.m", 383 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SABlurryTableView.h", 384 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAAppDelegate.m", 385 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAAnimatedButton.m", 386 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/SAAnimatedButton.h", 387 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/NGAParallaxMotion.m", 388 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/NGAParallaxMotion.h", 389 | "/Users/Adam/Dropbox/Dev/iOS/Projects/Stratus/Stratus/main.m", 390 | "/Users/Adam/Library/Application Support/Sublime Text 3/Packages/Default/Default ().sublime-keymap" 391 | ], 392 | "find": 393 | { 394 | "height": 38.0 395 | }, 396 | "find_in_files": 397 | { 398 | "height": 0.0, 399 | "where_history": 400 | [ 401 | ] 402 | }, 403 | "find_state": 404 | { 405 | "case_sensitive": false, 406 | "find_history": 407 | [ 408 | "resignActiv", 409 | "background", 410 | "shouldShow", 411 | "level", 412 | "sharedIn", 413 | "storage", 414 | "(id", 415 | "id", 416 | "scope", 417 | "FFF", 418 | "FFFFFF", 419 | "A6E22E", 420 | "class", 421 | " ", 422 | " ", 423 | " ", 424 | "build", 425 | "_internal", 426 | "close", 427 | "open", 428 | "player" 429 | ], 430 | "highlight": true, 431 | "in_selection": false, 432 | "preserve_case": false, 433 | "regex": false, 434 | "replace_history": 435 | [ 436 | ], 437 | "reverse": false, 438 | "show_context": true, 439 | "use_buffer2": true, 440 | "whole_word": false, 441 | "wrap": true 442 | }, 443 | "groups": 444 | [ 445 | { 446 | "selected": 2, 447 | "sheets": 448 | [ 449 | { 450 | "buffer": 0, 451 | "file": "messagebox.h", 452 | "semi_transient": false, 453 | "settings": 454 | { 455 | "buffer_size": 7569, 456 | "regions": 457 | { 458 | }, 459 | "selection": 460 | [ 461 | [ 462 | 0, 463 | 0 464 | ] 465 | ], 466 | "settings": 467 | { 468 | "BracketHighlighterBusy": false, 469 | "WordCountShouldRun": true, 470 | "bh_regions": 471 | [ 472 | "bh_square", 473 | "bh_square_center", 474 | "bh_square_open", 475 | "bh_square_close", 476 | "bh_regex", 477 | "bh_regex_center", 478 | "bh_regex_open", 479 | "bh_regex_close", 480 | "bh_single_quote", 481 | "bh_single_quote_center", 482 | "bh_single_quote_open", 483 | "bh_single_quote_close", 484 | "bh_round", 485 | "bh_round_center", 486 | "bh_round_open", 487 | "bh_round_close", 488 | "bh_angle", 489 | "bh_angle_center", 490 | "bh_angle_open", 491 | "bh_angle_close", 492 | "bh_tag", 493 | "bh_tag_center", 494 | "bh_tag_open", 495 | "bh_tag_close", 496 | "bh_double_quote", 497 | "bh_double_quote_center", 498 | "bh_double_quote_open", 499 | "bh_double_quote_close", 500 | "bh_default", 501 | "bh_default_center", 502 | "bh_default_open", 503 | "bh_default_close", 504 | "bh_unmatched", 505 | "bh_unmatched_center", 506 | "bh_unmatched_open", 507 | "bh_unmatched_close", 508 | "bh_curly", 509 | "bh_curly_center", 510 | "bh_curly_open", 511 | "bh_curly_close" 512 | ], 513 | "codeintel": true, 514 | "codeintel_config": 515 | { 516 | "JavaScript": 517 | { 518 | "codeintel_max_recursive_dir_depth": 2, 519 | "codeintel_scan_files_in_project": false, 520 | "javascriptExtraPaths": 521 | [ 522 | ] 523 | }, 524 | "PHP": 525 | { 526 | "codeintel_max_recursive_dir_depth": 5, 527 | "codeintel_scan_files_in_project": false, 528 | "phpExtraPaths": 529 | [ 530 | ] 531 | }, 532 | "Python": 533 | { 534 | "env": 535 | { 536 | } 537 | } 538 | }, 539 | "codeintel_enabled_languages": 540 | [ 541 | "JavaScript", 542 | "Mason", 543 | "XBL", 544 | "XUL", 545 | "RHTML", 546 | "SCSS", 547 | "Python", 548 | "HTML", 549 | "Ruby", 550 | "Python3", 551 | "XML", 552 | "Sass", 553 | "XSLT", 554 | "Django", 555 | "HTML5", 556 | "Perl", 557 | "CSS", 558 | "Twig", 559 | "Less", 560 | "Smarty", 561 | "Node.js", 562 | "Tcl", 563 | "TemplateToolkit", 564 | "PHP" 565 | ], 566 | "codeintel_live": true, 567 | "codeintel_live_enabled_languages": 568 | [ 569 | "JavaScript", 570 | "Mason", 571 | "XBL", 572 | "XUL", 573 | "RHTML", 574 | "SCSS", 575 | "Python", 576 | "HTML", 577 | "Ruby", 578 | "Python3", 579 | "XML", 580 | "Sass", 581 | "XSLT", 582 | "Django", 583 | "HTML5", 584 | "Perl", 585 | "CSS", 586 | "Twig", 587 | "Less", 588 | "Smarty", 589 | "Node.js", 590 | "Tcl", 591 | "TemplateToolkit", 592 | "PHP" 593 | ], 594 | "codeintel_max_recursive_dir_depth": 10, 595 | "codeintel_scan_exclude_dir": 596 | { 597 | "JavaScript": 598 | [ 599 | "/build/", 600 | "/min/" 601 | ] 602 | }, 603 | "codeintel_scan_files_in_project": true, 604 | "codeintel_selected_catalogs": 605 | [ 606 | "PyWin32", 607 | "jQuery", 608 | "Rails" 609 | ], 610 | "codeintel_snippets": true, 611 | "codeintel_syntax_map": 612 | { 613 | "Python Django": "Python" 614 | }, 615 | "codeintel_tooltips": "popup", 616 | "sublime_auto_complete": true, 617 | "syntax": "Packages/User/Logos.tmLanguage" 618 | }, 619 | "translation.x": 0.0, 620 | "translation.y": 0.0, 621 | "zoom_level": 1.0 622 | }, 623 | "stack_index": 4, 624 | "type": "text" 625 | }, 626 | { 627 | "buffer": 1, 628 | "file": "Makefile", 629 | "semi_transient": false, 630 | "settings": 631 | { 632 | "buffer_size": 566, 633 | "regions": 634 | { 635 | }, 636 | "selection": 637 | [ 638 | [ 639 | 129, 640 | 70 641 | ] 642 | ], 643 | "settings": 644 | { 645 | "BracketHighlighterBusy": false, 646 | "WordCountShouldRun": true, 647 | "bh_regions": 648 | [ 649 | "bh_square", 650 | "bh_square_center", 651 | "bh_square_open", 652 | "bh_square_close", 653 | "bh_regex", 654 | "bh_regex_center", 655 | "bh_regex_open", 656 | "bh_regex_close", 657 | "bh_single_quote", 658 | "bh_single_quote_center", 659 | "bh_single_quote_open", 660 | "bh_single_quote_close", 661 | "bh_round", 662 | "bh_round_center", 663 | "bh_round_open", 664 | "bh_round_close", 665 | "bh_angle", 666 | "bh_angle_center", 667 | "bh_angle_open", 668 | "bh_angle_close", 669 | "bh_tag", 670 | "bh_tag_center", 671 | "bh_tag_open", 672 | "bh_tag_close", 673 | "bh_double_quote", 674 | "bh_double_quote_center", 675 | "bh_double_quote_open", 676 | "bh_double_quote_close", 677 | "bh_default", 678 | "bh_default_center", 679 | "bh_default_open", 680 | "bh_default_close", 681 | "bh_unmatched", 682 | "bh_unmatched_center", 683 | "bh_unmatched_open", 684 | "bh_unmatched_close", 685 | "bh_curly", 686 | "bh_curly_center", 687 | "bh_curly_open", 688 | "bh_curly_close" 689 | ], 690 | "codeintel": true, 691 | "codeintel_config": 692 | { 693 | "JavaScript": 694 | { 695 | "codeintel_max_recursive_dir_depth": 2, 696 | "codeintel_scan_files_in_project": false, 697 | "javascriptExtraPaths": 698 | [ 699 | ] 700 | }, 701 | "PHP": 702 | { 703 | "codeintel_max_recursive_dir_depth": 5, 704 | "codeintel_scan_files_in_project": false, 705 | "phpExtraPaths": 706 | [ 707 | ] 708 | }, 709 | "Python": 710 | { 711 | "env": 712 | { 713 | } 714 | } 715 | }, 716 | "codeintel_enabled_languages": 717 | [ 718 | "JavaScript", 719 | "Mason", 720 | "XBL", 721 | "XUL", 722 | "RHTML", 723 | "SCSS", 724 | "Python", 725 | "HTML", 726 | "Ruby", 727 | "Python3", 728 | "XML", 729 | "Sass", 730 | "XSLT", 731 | "Django", 732 | "HTML5", 733 | "Perl", 734 | "CSS", 735 | "Twig", 736 | "Less", 737 | "Smarty", 738 | "Node.js", 739 | "Tcl", 740 | "TemplateToolkit", 741 | "PHP" 742 | ], 743 | "codeintel_live": true, 744 | "codeintel_live_enabled_languages": 745 | [ 746 | "JavaScript", 747 | "Mason", 748 | "XBL", 749 | "XUL", 750 | "RHTML", 751 | "SCSS", 752 | "Python", 753 | "HTML", 754 | "Ruby", 755 | "Python3", 756 | "XML", 757 | "Sass", 758 | "XSLT", 759 | "Django", 760 | "HTML5", 761 | "Perl", 762 | "CSS", 763 | "Twig", 764 | "Less", 765 | "Smarty", 766 | "Node.js", 767 | "Tcl", 768 | "TemplateToolkit", 769 | "PHP" 770 | ], 771 | "codeintel_max_recursive_dir_depth": 10, 772 | "codeintel_scan_exclude_dir": 773 | { 774 | "JavaScript": 775 | [ 776 | "/build/", 777 | "/min/" 778 | ] 779 | }, 780 | "codeintel_scan_files_in_project": true, 781 | "codeintel_selected_catalogs": 782 | [ 783 | "PyWin32", 784 | "jQuery", 785 | "Rails" 786 | ], 787 | "codeintel_snippets": true, 788 | "codeintel_syntax_map": 789 | { 790 | "Python Django": "Python" 791 | }, 792 | "codeintel_tooltips": "popup", 793 | "sublime_auto_complete": true, 794 | "syntax": "Packages/Makefile Improved/Makefile Improved.tmLanguage" 795 | }, 796 | "translation.x": 0.0, 797 | "translation.y": 0.0, 798 | "zoom_level": 1.0 799 | }, 800 | "stack_index": 1, 801 | "type": "text" 802 | }, 803 | { 804 | "buffer": 2, 805 | "file": "messagebox.sublime-project", 806 | "semi_transient": false, 807 | "settings": 808 | { 809 | "buffer_size": 676, 810 | "regions": 811 | { 812 | }, 813 | "selection": 814 | [ 815 | [ 816 | 0, 817 | 676 818 | ] 819 | ], 820 | "settings": 821 | { 822 | "BracketHighlighterBusy": false, 823 | "WordCountShouldRun": true, 824 | "bh_regions": 825 | [ 826 | "bh_square", 827 | "bh_square_center", 828 | "bh_square_open", 829 | "bh_square_close", 830 | "bh_regex", 831 | "bh_regex_center", 832 | "bh_regex_open", 833 | "bh_regex_close", 834 | "bh_single_quote", 835 | "bh_single_quote_center", 836 | "bh_single_quote_open", 837 | "bh_single_quote_close", 838 | "bh_round", 839 | "bh_round_center", 840 | "bh_round_open", 841 | "bh_round_close", 842 | "bh_angle", 843 | "bh_angle_center", 844 | "bh_angle_open", 845 | "bh_angle_close", 846 | "bh_tag", 847 | "bh_tag_center", 848 | "bh_tag_open", 849 | "bh_tag_close", 850 | "bh_double_quote", 851 | "bh_double_quote_center", 852 | "bh_double_quote_open", 853 | "bh_double_quote_close", 854 | "bh_default", 855 | "bh_default_center", 856 | "bh_default_open", 857 | "bh_default_close", 858 | "bh_unmatched", 859 | "bh_unmatched_center", 860 | "bh_unmatched_open", 861 | "bh_unmatched_close", 862 | "bh_curly", 863 | "bh_curly_center", 864 | "bh_curly_open", 865 | "bh_curly_close" 866 | ], 867 | "syntax": "Packages/JavaScript/JSON.tmLanguage" 868 | }, 869 | "translation.x": 0.0, 870 | "translation.y": 0.0, 871 | "zoom_level": 1.0 872 | }, 873 | "stack_index": 0, 874 | "type": "text" 875 | }, 876 | { 877 | "buffer": 3, 878 | "file": "Tweak.xmi", 879 | "semi_transient": false, 880 | "settings": 881 | { 882 | "buffer_size": 9237, 883 | "regions": 884 | { 885 | }, 886 | "selection": 887 | [ 888 | [ 889 | 1039, 890 | 938 891 | ] 892 | ], 893 | "settings": 894 | { 895 | "BracketHighlighterBusy": false, 896 | "WordCountShouldRun": true, 897 | "bh_regions": 898 | [ 899 | "bh_square", 900 | "bh_square_center", 901 | "bh_square_open", 902 | "bh_square_close", 903 | "bh_regex", 904 | "bh_regex_center", 905 | "bh_regex_open", 906 | "bh_regex_close", 907 | "bh_single_quote", 908 | "bh_single_quote_center", 909 | "bh_single_quote_open", 910 | "bh_single_quote_close", 911 | "bh_round", 912 | "bh_round_center", 913 | "bh_round_open", 914 | "bh_round_close", 915 | "bh_angle", 916 | "bh_angle_center", 917 | "bh_angle_open", 918 | "bh_angle_close", 919 | "bh_tag", 920 | "bh_tag_center", 921 | "bh_tag_open", 922 | "bh_tag_close", 923 | "bh_double_quote", 924 | "bh_double_quote_center", 925 | "bh_double_quote_open", 926 | "bh_double_quote_close", 927 | "bh_default", 928 | "bh_default_center", 929 | "bh_default_open", 930 | "bh_default_close", 931 | "bh_unmatched", 932 | "bh_unmatched_center", 933 | "bh_unmatched_open", 934 | "bh_unmatched_close", 935 | "bh_curly", 936 | "bh_curly_center", 937 | "bh_curly_open", 938 | "bh_curly_close" 939 | ], 940 | "codeintel": true, 941 | "codeintel_config": 942 | { 943 | "JavaScript": 944 | { 945 | "codeintel_max_recursive_dir_depth": 2, 946 | "codeintel_scan_files_in_project": false, 947 | "javascriptExtraPaths": 948 | [ 949 | ] 950 | }, 951 | "PHP": 952 | { 953 | "codeintel_max_recursive_dir_depth": 5, 954 | "codeintel_scan_files_in_project": false, 955 | "phpExtraPaths": 956 | [ 957 | ] 958 | }, 959 | "Python": 960 | { 961 | "env": 962 | { 963 | } 964 | } 965 | }, 966 | "codeintel_enabled_languages": 967 | [ 968 | "JavaScript", 969 | "Mason", 970 | "XBL", 971 | "XUL", 972 | "RHTML", 973 | "SCSS", 974 | "Python", 975 | "HTML", 976 | "Ruby", 977 | "Python3", 978 | "XML", 979 | "Sass", 980 | "XSLT", 981 | "Django", 982 | "HTML5", 983 | "Perl", 984 | "CSS", 985 | "Twig", 986 | "Less", 987 | "Smarty", 988 | "Node.js", 989 | "Tcl", 990 | "TemplateToolkit", 991 | "PHP" 992 | ], 993 | "codeintel_live": true, 994 | "codeintel_live_enabled_languages": 995 | [ 996 | "JavaScript", 997 | "Mason", 998 | "XBL", 999 | "XUL", 1000 | "RHTML", 1001 | "SCSS", 1002 | "Python", 1003 | "HTML", 1004 | "Ruby", 1005 | "Python3", 1006 | "XML", 1007 | "Sass", 1008 | "XSLT", 1009 | "Django", 1010 | "HTML5", 1011 | "Perl", 1012 | "CSS", 1013 | "Twig", 1014 | "Less", 1015 | "Smarty", 1016 | "Node.js", 1017 | "Tcl", 1018 | "TemplateToolkit", 1019 | "PHP" 1020 | ], 1021 | "codeintel_max_recursive_dir_depth": 10, 1022 | "codeintel_scan_exclude_dir": 1023 | { 1024 | "JavaScript": 1025 | [ 1026 | "/build/", 1027 | "/min/" 1028 | ] 1029 | }, 1030 | "codeintel_scan_files_in_project": true, 1031 | "codeintel_selected_catalogs": 1032 | [ 1033 | "PyWin32", 1034 | "jQuery", 1035 | "Rails" 1036 | ], 1037 | "codeintel_snippets": true, 1038 | "codeintel_syntax_map": 1039 | { 1040 | "Python Django": "Python" 1041 | }, 1042 | "codeintel_tooltips": "popup", 1043 | "sublime_auto_complete": true, 1044 | "syntax": "Packages/User/Logos.tmLanguage" 1045 | }, 1046 | "translation.x": 0.0, 1047 | "translation.y": 0.0, 1048 | "zoom_level": 1.0 1049 | }, 1050 | "stack_index": 3, 1051 | "type": "text" 1052 | }, 1053 | { 1054 | "buffer": 4, 1055 | "file": "SpringBoard.xm", 1056 | "semi_transient": false, 1057 | "settings": 1058 | { 1059 | "buffer_size": 10776, 1060 | "regions": 1061 | { 1062 | }, 1063 | "selection": 1064 | [ 1065 | [ 1066 | 0, 1067 | 0 1068 | ] 1069 | ], 1070 | "settings": 1071 | { 1072 | "BracketHighlighterBusy": false, 1073 | "WordCountShouldRun": true, 1074 | "bh_regions": 1075 | [ 1076 | "bh_tag", 1077 | "bh_tag_center", 1078 | "bh_tag_open", 1079 | "bh_tag_close", 1080 | "bh_double_quote", 1081 | "bh_double_quote_center", 1082 | "bh_double_quote_open", 1083 | "bh_double_quote_close", 1084 | "bh_regex", 1085 | "bh_regex_center", 1086 | "bh_regex_open", 1087 | "bh_regex_close", 1088 | "bh_curly", 1089 | "bh_curly_center", 1090 | "bh_curly_open", 1091 | "bh_curly_close", 1092 | "bh_angle", 1093 | "bh_angle_center", 1094 | "bh_angle_open", 1095 | "bh_angle_close", 1096 | "bh_unmatched", 1097 | "bh_unmatched_center", 1098 | "bh_unmatched_open", 1099 | "bh_unmatched_close", 1100 | "bh_default", 1101 | "bh_default_center", 1102 | "bh_default_open", 1103 | "bh_default_close", 1104 | "bh_square", 1105 | "bh_square_center", 1106 | "bh_square_open", 1107 | "bh_square_close", 1108 | "bh_single_quote", 1109 | "bh_single_quote_center", 1110 | "bh_single_quote_open", 1111 | "bh_single_quote_close", 1112 | "bh_round", 1113 | "bh_round_center", 1114 | "bh_round_open", 1115 | "bh_round_close" 1116 | ], 1117 | "codeintel": true, 1118 | "codeintel_config": 1119 | { 1120 | "JavaScript": 1121 | { 1122 | "codeintel_max_recursive_dir_depth": 2, 1123 | "codeintel_scan_files_in_project": false, 1124 | "javascriptExtraPaths": 1125 | [ 1126 | ] 1127 | }, 1128 | "PHP": 1129 | { 1130 | "codeintel_max_recursive_dir_depth": 5, 1131 | "codeintel_scan_files_in_project": false, 1132 | "phpExtraPaths": 1133 | [ 1134 | ] 1135 | }, 1136 | "Python": 1137 | { 1138 | "env": 1139 | { 1140 | } 1141 | } 1142 | }, 1143 | "codeintel_enabled_languages": 1144 | [ 1145 | "JavaScript", 1146 | "Mason", 1147 | "XBL", 1148 | "XUL", 1149 | "RHTML", 1150 | "SCSS", 1151 | "Python", 1152 | "HTML", 1153 | "Ruby", 1154 | "Python3", 1155 | "XML", 1156 | "Sass", 1157 | "XSLT", 1158 | "Django", 1159 | "HTML5", 1160 | "Perl", 1161 | "CSS", 1162 | "Twig", 1163 | "Less", 1164 | "Smarty", 1165 | "Node.js", 1166 | "Tcl", 1167 | "TemplateToolkit", 1168 | "PHP" 1169 | ], 1170 | "codeintel_live": true, 1171 | "codeintel_live_enabled_languages": 1172 | [ 1173 | "JavaScript", 1174 | "Mason", 1175 | "XBL", 1176 | "XUL", 1177 | "RHTML", 1178 | "SCSS", 1179 | "Python", 1180 | "HTML", 1181 | "Ruby", 1182 | "Python3", 1183 | "XML", 1184 | "Sass", 1185 | "XSLT", 1186 | "Django", 1187 | "HTML5", 1188 | "Perl", 1189 | "CSS", 1190 | "Twig", 1191 | "Less", 1192 | "Smarty", 1193 | "Node.js", 1194 | "Tcl", 1195 | "TemplateToolkit", 1196 | "PHP" 1197 | ], 1198 | "codeintel_max_recursive_dir_depth": 10, 1199 | "codeintel_scan_exclude_dir": 1200 | { 1201 | "JavaScript": 1202 | [ 1203 | "/build/", 1204 | "/min/" 1205 | ] 1206 | }, 1207 | "codeintel_scan_files_in_project": true, 1208 | "codeintel_selected_catalogs": 1209 | [ 1210 | "PyWin32", 1211 | "jQuery", 1212 | "Rails" 1213 | ], 1214 | "codeintel_snippets": true, 1215 | "codeintel_syntax_map": 1216 | { 1217 | "Python Django": "Python" 1218 | }, 1219 | "codeintel_tooltips": "popup", 1220 | "sublime_auto_complete": true, 1221 | "syntax": "Packages/User/Logos.tmLanguage" 1222 | }, 1223 | "translation.x": 0.0, 1224 | "translation.y": 1572.0, 1225 | "zoom_level": 1.0 1226 | }, 1227 | "stack_index": 6, 1228 | "type": "text" 1229 | }, 1230 | { 1231 | "buffer": 5, 1232 | "file": "MBChatHeadWindow.m", 1233 | "semi_transient": false, 1234 | "settings": 1235 | { 1236 | "buffer_size": 2795, 1237 | "regions": 1238 | { 1239 | }, 1240 | "selection": 1241 | [ 1242 | [ 1243 | 0, 1244 | 0 1245 | ] 1246 | ], 1247 | "settings": 1248 | { 1249 | "BracketHighlighterBusy": false, 1250 | "WordCountShouldRun": true, 1251 | "bh_regions": 1252 | [ 1253 | "bh_default", 1254 | "bh_default_center", 1255 | "bh_default_open", 1256 | "bh_default_close", 1257 | "bh_regex", 1258 | "bh_regex_center", 1259 | "bh_regex_open", 1260 | "bh_regex_close", 1261 | "bh_double_quote", 1262 | "bh_double_quote_center", 1263 | "bh_double_quote_open", 1264 | "bh_double_quote_close", 1265 | "bh_square", 1266 | "bh_square_center", 1267 | "bh_square_open", 1268 | "bh_square_close", 1269 | "bh_angle", 1270 | "bh_angle_center", 1271 | "bh_angle_open", 1272 | "bh_angle_close", 1273 | "bh_curly", 1274 | "bh_curly_center", 1275 | "bh_curly_open", 1276 | "bh_curly_close", 1277 | "bh_unmatched", 1278 | "bh_unmatched_center", 1279 | "bh_unmatched_open", 1280 | "bh_unmatched_close", 1281 | "bh_tag", 1282 | "bh_tag_center", 1283 | "bh_tag_open", 1284 | "bh_tag_close", 1285 | "bh_round", 1286 | "bh_round_center", 1287 | "bh_round_open", 1288 | "bh_round_close", 1289 | "bh_single_quote", 1290 | "bh_single_quote_center", 1291 | "bh_single_quote_open", 1292 | "bh_single_quote_close" 1293 | ], 1294 | "codeintel": true, 1295 | "codeintel_config": 1296 | { 1297 | "JavaScript": 1298 | { 1299 | "codeintel_max_recursive_dir_depth": 2, 1300 | "codeintel_scan_files_in_project": false, 1301 | "javascriptExtraPaths": 1302 | [ 1303 | ] 1304 | }, 1305 | "PHP": 1306 | { 1307 | "codeintel_max_recursive_dir_depth": 5, 1308 | "codeintel_scan_files_in_project": false, 1309 | "phpExtraPaths": 1310 | [ 1311 | ] 1312 | }, 1313 | "Python": 1314 | { 1315 | "env": 1316 | { 1317 | } 1318 | } 1319 | }, 1320 | "codeintel_enabled_languages": 1321 | [ 1322 | "JavaScript", 1323 | "Mason", 1324 | "XBL", 1325 | "XUL", 1326 | "RHTML", 1327 | "SCSS", 1328 | "Python", 1329 | "HTML", 1330 | "Ruby", 1331 | "Python3", 1332 | "XML", 1333 | "Sass", 1334 | "XSLT", 1335 | "Django", 1336 | "HTML5", 1337 | "Perl", 1338 | "CSS", 1339 | "Twig", 1340 | "Less", 1341 | "Smarty", 1342 | "Node.js", 1343 | "Tcl", 1344 | "TemplateToolkit", 1345 | "PHP" 1346 | ], 1347 | "codeintel_live": true, 1348 | "codeintel_live_enabled_languages": 1349 | [ 1350 | "JavaScript", 1351 | "Mason", 1352 | "XBL", 1353 | "XUL", 1354 | "RHTML", 1355 | "SCSS", 1356 | "Python", 1357 | "HTML", 1358 | "Ruby", 1359 | "Python3", 1360 | "XML", 1361 | "Sass", 1362 | "XSLT", 1363 | "Django", 1364 | "HTML5", 1365 | "Perl", 1366 | "CSS", 1367 | "Twig", 1368 | "Less", 1369 | "Smarty", 1370 | "Node.js", 1371 | "Tcl", 1372 | "TemplateToolkit", 1373 | "PHP" 1374 | ], 1375 | "codeintel_max_recursive_dir_depth": 10, 1376 | "codeintel_scan_exclude_dir": 1377 | { 1378 | "JavaScript": 1379 | [ 1380 | "/build/", 1381 | "/min/" 1382 | ] 1383 | }, 1384 | "codeintel_scan_files_in_project": true, 1385 | "codeintel_selected_catalogs": 1386 | [ 1387 | "PyWin32", 1388 | "jQuery", 1389 | "Rails" 1390 | ], 1391 | "codeintel_snippets": true, 1392 | "codeintel_syntax_map": 1393 | { 1394 | "Python Django": "Python" 1395 | }, 1396 | "codeintel_tooltips": "popup", 1397 | "sublime_auto_complete": true, 1398 | "syntax": "Packages/User/Logos.tmLanguage" 1399 | }, 1400 | "translation.x": 0.0, 1401 | "translation.y": 0.0, 1402 | "zoom_level": 1.0 1403 | }, 1404 | "stack_index": 8, 1405 | "type": "text" 1406 | }, 1407 | { 1408 | "buffer": 6, 1409 | "file": "MBChatHeadWindow.h", 1410 | "semi_transient": false, 1411 | "settings": 1412 | { 1413 | "buffer_size": 358, 1414 | "regions": 1415 | { 1416 | }, 1417 | "selection": 1418 | [ 1419 | [ 1420 | 0, 1421 | 358 1422 | ] 1423 | ], 1424 | "settings": 1425 | { 1426 | "BracketHighlighterBusy": false, 1427 | "WordCountShouldRun": true, 1428 | "bh_regions": 1429 | [ 1430 | "bh_default", 1431 | "bh_default_center", 1432 | "bh_default_open", 1433 | "bh_default_close", 1434 | "bh_regex", 1435 | "bh_regex_center", 1436 | "bh_regex_open", 1437 | "bh_regex_close", 1438 | "bh_double_quote", 1439 | "bh_double_quote_center", 1440 | "bh_double_quote_open", 1441 | "bh_double_quote_close", 1442 | "bh_square", 1443 | "bh_square_center", 1444 | "bh_square_open", 1445 | "bh_square_close", 1446 | "bh_angle", 1447 | "bh_angle_center", 1448 | "bh_angle_open", 1449 | "bh_angle_close", 1450 | "bh_curly", 1451 | "bh_curly_center", 1452 | "bh_curly_open", 1453 | "bh_curly_close", 1454 | "bh_unmatched", 1455 | "bh_unmatched_center", 1456 | "bh_unmatched_open", 1457 | "bh_unmatched_close", 1458 | "bh_tag", 1459 | "bh_tag_center", 1460 | "bh_tag_open", 1461 | "bh_tag_close", 1462 | "bh_round", 1463 | "bh_round_center", 1464 | "bh_round_open", 1465 | "bh_round_close", 1466 | "bh_single_quote", 1467 | "bh_single_quote_center", 1468 | "bh_single_quote_open", 1469 | "bh_single_quote_close" 1470 | ], 1471 | "codeintel": true, 1472 | "codeintel_config": 1473 | { 1474 | "JavaScript": 1475 | { 1476 | "codeintel_max_recursive_dir_depth": 2, 1477 | "codeintel_scan_files_in_project": false, 1478 | "javascriptExtraPaths": 1479 | [ 1480 | ] 1481 | }, 1482 | "PHP": 1483 | { 1484 | "codeintel_max_recursive_dir_depth": 5, 1485 | "codeintel_scan_files_in_project": false, 1486 | "phpExtraPaths": 1487 | [ 1488 | ] 1489 | }, 1490 | "Python": 1491 | { 1492 | "env": 1493 | { 1494 | } 1495 | } 1496 | }, 1497 | "codeintel_enabled_languages": 1498 | [ 1499 | "JavaScript", 1500 | "Mason", 1501 | "XBL", 1502 | "XUL", 1503 | "RHTML", 1504 | "SCSS", 1505 | "Python", 1506 | "HTML", 1507 | "Ruby", 1508 | "Python3", 1509 | "XML", 1510 | "Sass", 1511 | "XSLT", 1512 | "Django", 1513 | "HTML5", 1514 | "Perl", 1515 | "CSS", 1516 | "Twig", 1517 | "Less", 1518 | "Smarty", 1519 | "Node.js", 1520 | "Tcl", 1521 | "TemplateToolkit", 1522 | "PHP" 1523 | ], 1524 | "codeintel_live": true, 1525 | "codeintel_live_enabled_languages": 1526 | [ 1527 | "JavaScript", 1528 | "Mason", 1529 | "XBL", 1530 | "XUL", 1531 | "RHTML", 1532 | "SCSS", 1533 | "Python", 1534 | "HTML", 1535 | "Ruby", 1536 | "Python3", 1537 | "XML", 1538 | "Sass", 1539 | "XSLT", 1540 | "Django", 1541 | "HTML5", 1542 | "Perl", 1543 | "CSS", 1544 | "Twig", 1545 | "Less", 1546 | "Smarty", 1547 | "Node.js", 1548 | "Tcl", 1549 | "TemplateToolkit", 1550 | "PHP" 1551 | ], 1552 | "codeintel_max_recursive_dir_depth": 10, 1553 | "codeintel_scan_exclude_dir": 1554 | { 1555 | "JavaScript": 1556 | [ 1557 | "/build/", 1558 | "/min/" 1559 | ] 1560 | }, 1561 | "codeintel_scan_files_in_project": true, 1562 | "codeintel_selected_catalogs": 1563 | [ 1564 | "PyWin32", 1565 | "jQuery", 1566 | "Rails" 1567 | ], 1568 | "codeintel_snippets": true, 1569 | "codeintel_syntax_map": 1570 | { 1571 | "Python Django": "Python" 1572 | }, 1573 | "codeintel_tooltips": "popup", 1574 | "sublime_auto_complete": true, 1575 | "syntax": "Packages/User/Logos.tmLanguage" 1576 | }, 1577 | "translation.x": 0.0, 1578 | "translation.y": 0.0, 1579 | "zoom_level": 1.0 1580 | }, 1581 | "stack_index": 7, 1582 | "type": "text" 1583 | }, 1584 | { 1585 | "buffer": 7, 1586 | "file": "Facebook.xm", 1587 | "semi_transient": false, 1588 | "settings": 1589 | { 1590 | "buffer_size": 10246, 1591 | "regions": 1592 | { 1593 | }, 1594 | "selection": 1595 | [ 1596 | [ 1597 | 0, 1598 | 0 1599 | ] 1600 | ], 1601 | "settings": 1602 | { 1603 | "BracketHighlighterBusy": false, 1604 | "WordCountShouldRun": true, 1605 | "bh_regions": 1606 | [ 1607 | "bh_square", 1608 | "bh_square_center", 1609 | "bh_square_open", 1610 | "bh_square_close", 1611 | "bh_regex", 1612 | "bh_regex_center", 1613 | "bh_regex_open", 1614 | "bh_regex_close", 1615 | "bh_single_quote", 1616 | "bh_single_quote_center", 1617 | "bh_single_quote_open", 1618 | "bh_single_quote_close", 1619 | "bh_round", 1620 | "bh_round_center", 1621 | "bh_round_open", 1622 | "bh_round_close", 1623 | "bh_angle", 1624 | "bh_angle_center", 1625 | "bh_angle_open", 1626 | "bh_angle_close", 1627 | "bh_tag", 1628 | "bh_tag_center", 1629 | "bh_tag_open", 1630 | "bh_tag_close", 1631 | "bh_double_quote", 1632 | "bh_double_quote_center", 1633 | "bh_double_quote_open", 1634 | "bh_double_quote_close", 1635 | "bh_default", 1636 | "bh_default_center", 1637 | "bh_default_open", 1638 | "bh_default_close", 1639 | "bh_unmatched", 1640 | "bh_unmatched_center", 1641 | "bh_unmatched_open", 1642 | "bh_unmatched_close", 1643 | "bh_curly", 1644 | "bh_curly_center", 1645 | "bh_curly_open", 1646 | "bh_curly_close" 1647 | ], 1648 | "codeintel": true, 1649 | "codeintel_config": 1650 | { 1651 | "JavaScript": 1652 | { 1653 | "codeintel_max_recursive_dir_depth": 2, 1654 | "codeintel_scan_files_in_project": false, 1655 | "javascriptExtraPaths": 1656 | [ 1657 | ] 1658 | }, 1659 | "PHP": 1660 | { 1661 | "codeintel_max_recursive_dir_depth": 5, 1662 | "codeintel_scan_files_in_project": false, 1663 | "phpExtraPaths": 1664 | [ 1665 | ] 1666 | }, 1667 | "Python": 1668 | { 1669 | "env": 1670 | { 1671 | } 1672 | } 1673 | }, 1674 | "codeintel_enabled_languages": 1675 | [ 1676 | "JavaScript", 1677 | "Mason", 1678 | "XBL", 1679 | "XUL", 1680 | "RHTML", 1681 | "SCSS", 1682 | "Python", 1683 | "HTML", 1684 | "Ruby", 1685 | "Python3", 1686 | "XML", 1687 | "Sass", 1688 | "XSLT", 1689 | "Django", 1690 | "HTML5", 1691 | "Perl", 1692 | "CSS", 1693 | "Twig", 1694 | "Less", 1695 | "Smarty", 1696 | "Node.js", 1697 | "Tcl", 1698 | "TemplateToolkit", 1699 | "PHP" 1700 | ], 1701 | "codeintel_live": true, 1702 | "codeintel_live_enabled_languages": 1703 | [ 1704 | "JavaScript", 1705 | "Mason", 1706 | "XBL", 1707 | "XUL", 1708 | "RHTML", 1709 | "SCSS", 1710 | "Python", 1711 | "HTML", 1712 | "Ruby", 1713 | "Python3", 1714 | "XML", 1715 | "Sass", 1716 | "XSLT", 1717 | "Django", 1718 | "HTML5", 1719 | "Perl", 1720 | "CSS", 1721 | "Twig", 1722 | "Less", 1723 | "Smarty", 1724 | "Node.js", 1725 | "Tcl", 1726 | "TemplateToolkit", 1727 | "PHP" 1728 | ], 1729 | "codeintel_max_recursive_dir_depth": 10, 1730 | "codeintel_scan_exclude_dir": 1731 | { 1732 | "JavaScript": 1733 | [ 1734 | "/build/", 1735 | "/min/" 1736 | ] 1737 | }, 1738 | "codeintel_scan_files_in_project": true, 1739 | "codeintel_selected_catalogs": 1740 | [ 1741 | "PyWin32", 1742 | "jQuery", 1743 | "Rails" 1744 | ], 1745 | "codeintel_snippets": true, 1746 | "codeintel_syntax_map": 1747 | { 1748 | "Python Django": "Python" 1749 | }, 1750 | "codeintel_tooltips": "popup", 1751 | "sublime_auto_complete": true, 1752 | "syntax": "Packages/User/Logos.tmLanguage" 1753 | }, 1754 | "translation.x": 0.0, 1755 | "translation.y": 207.0, 1756 | "zoom_level": 1.0 1757 | }, 1758 | "stack_index": 5, 1759 | "type": "text" 1760 | }, 1761 | { 1762 | "buffer": 8, 1763 | "file": "messageboxpreferences/messageboxpreferences.mm", 1764 | "semi_transient": false, 1765 | "settings": 1766 | { 1767 | "buffer_size": 3132, 1768 | "regions": 1769 | { 1770 | }, 1771 | "selection": 1772 | [ 1773 | [ 1774 | 1252, 1775 | 1252 1776 | ] 1777 | ], 1778 | "settings": 1779 | { 1780 | "BracketHighlighterBusy": false, 1781 | "WordCountShouldRun": true, 1782 | "bh_regions": 1783 | [ 1784 | "bh_square", 1785 | "bh_square_center", 1786 | "bh_square_open", 1787 | "bh_square_close", 1788 | "bh_regex", 1789 | "bh_regex_center", 1790 | "bh_regex_open", 1791 | "bh_regex_close", 1792 | "bh_single_quote", 1793 | "bh_single_quote_center", 1794 | "bh_single_quote_open", 1795 | "bh_single_quote_close", 1796 | "bh_round", 1797 | "bh_round_center", 1798 | "bh_round_open", 1799 | "bh_round_close", 1800 | "bh_angle", 1801 | "bh_angle_center", 1802 | "bh_angle_open", 1803 | "bh_angle_close", 1804 | "bh_tag", 1805 | "bh_tag_center", 1806 | "bh_tag_open", 1807 | "bh_tag_close", 1808 | "bh_double_quote", 1809 | "bh_double_quote_center", 1810 | "bh_double_quote_open", 1811 | "bh_double_quote_close", 1812 | "bh_default", 1813 | "bh_default_center", 1814 | "bh_default_open", 1815 | "bh_default_close", 1816 | "bh_unmatched", 1817 | "bh_unmatched_center", 1818 | "bh_unmatched_open", 1819 | "bh_unmatched_close", 1820 | "bh_curly", 1821 | "bh_curly_center", 1822 | "bh_curly_open", 1823 | "bh_curly_close" 1824 | ], 1825 | "codeintel": true, 1826 | "codeintel_config": 1827 | { 1828 | "JavaScript": 1829 | { 1830 | "codeintel_max_recursive_dir_depth": 2, 1831 | "codeintel_scan_files_in_project": false, 1832 | "javascriptExtraPaths": 1833 | [ 1834 | ] 1835 | }, 1836 | "PHP": 1837 | { 1838 | "codeintel_max_recursive_dir_depth": 5, 1839 | "codeintel_scan_files_in_project": false, 1840 | "phpExtraPaths": 1841 | [ 1842 | ] 1843 | }, 1844 | "Python": 1845 | { 1846 | "env": 1847 | { 1848 | } 1849 | } 1850 | }, 1851 | "codeintel_enabled_languages": 1852 | [ 1853 | "JavaScript", 1854 | "Mason", 1855 | "XBL", 1856 | "XUL", 1857 | "RHTML", 1858 | "SCSS", 1859 | "Python", 1860 | "HTML", 1861 | "Ruby", 1862 | "Python3", 1863 | "XML", 1864 | "Sass", 1865 | "XSLT", 1866 | "Django", 1867 | "HTML5", 1868 | "Perl", 1869 | "CSS", 1870 | "Twig", 1871 | "Less", 1872 | "Smarty", 1873 | "Node.js", 1874 | "Tcl", 1875 | "TemplateToolkit", 1876 | "PHP" 1877 | ], 1878 | "codeintel_live": true, 1879 | "codeintel_live_enabled_languages": 1880 | [ 1881 | "JavaScript", 1882 | "Mason", 1883 | "XBL", 1884 | "XUL", 1885 | "RHTML", 1886 | "SCSS", 1887 | "Python", 1888 | "HTML", 1889 | "Ruby", 1890 | "Python3", 1891 | "XML", 1892 | "Sass", 1893 | "XSLT", 1894 | "Django", 1895 | "HTML5", 1896 | "Perl", 1897 | "CSS", 1898 | "Twig", 1899 | "Less", 1900 | "Smarty", 1901 | "Node.js", 1902 | "Tcl", 1903 | "TemplateToolkit", 1904 | "PHP" 1905 | ], 1906 | "codeintel_max_recursive_dir_depth": 10, 1907 | "codeintel_scan_exclude_dir": 1908 | { 1909 | "JavaScript": 1910 | [ 1911 | "/build/", 1912 | "/min/" 1913 | ] 1914 | }, 1915 | "codeintel_scan_files_in_project": true, 1916 | "codeintel_selected_catalogs": 1917 | [ 1918 | "PyWin32", 1919 | "jQuery", 1920 | "Rails" 1921 | ], 1922 | "codeintel_snippets": true, 1923 | "codeintel_syntax_map": 1924 | { 1925 | "Python Django": "Python" 1926 | }, 1927 | "codeintel_tooltips": "popup", 1928 | "sublime_auto_complete": true, 1929 | "syntax": "Packages/User/Logos.tmLanguage" 1930 | }, 1931 | "translation.x": 0.0, 1932 | "translation.y": 0.0, 1933 | "zoom_level": 1.0 1934 | }, 1935 | "stack_index": 2, 1936 | "type": "text" 1937 | } 1938 | ] 1939 | } 1940 | ], 1941 | "incremental_find": 1942 | { 1943 | "height": 23.0 1944 | }, 1945 | "input": 1946 | { 1947 | "height": 29.0 1948 | }, 1949 | "layout": 1950 | { 1951 | "cells": 1952 | [ 1953 | [ 1954 | 0, 1955 | 0, 1956 | 1, 1957 | 1 1958 | ] 1959 | ], 1960 | "cols": 1961 | [ 1962 | 0.0, 1963 | 1.0 1964 | ], 1965 | "rows": 1966 | [ 1967 | 0.0, 1968 | 1.0 1969 | ] 1970 | }, 1971 | "menu_visible": true, 1972 | "output.exec": 1973 | { 1974 | "height": 195.0 1975 | }, 1976 | "output.find_results": 1977 | { 1978 | "height": 0.0 1979 | }, 1980 | "project": "messagebox.sublime-project", 1981 | "replace": 1982 | { 1983 | "height": 42.0 1984 | }, 1985 | "save_all_on_build": true, 1986 | "select_file": 1987 | { 1988 | "height": 0.0, 1989 | "selected_items": 1990 | [ 1991 | [ 1992 | "appdele", 1993 | "AppDelegate.h" 1994 | ], 1995 | [ 1996 | "fbgrphack", 1997 | "FBGrpHackCajmereIsEnglishOnlySorryWeWillSupportOtherLanguagesSoon.h" 1998 | ], 1999 | [ 2000 | "fbappmodulemana", 2001 | "FBAppModuleManager.h" 2002 | ], 2003 | [ 2004 | "fbbackboardviewcon", 2005 | "FBBackboardViewController.h" 2006 | ], 2007 | [ 2008 | "fbmainstac", 2009 | "FBMainStackViewController.h" 2010 | ] 2011 | ], 2012 | "width": 0.0 2013 | }, 2014 | "select_project": 2015 | { 2016 | "height": 0.0, 2017 | "selected_items": 2018 | [ 2019 | ], 2020 | "width": 0.0 2021 | }, 2022 | "select_symbol": 2023 | { 2024 | "height": 0.0, 2025 | "selected_items": 2026 | [ 2027 | ], 2028 | "width": 0.0 2029 | }, 2030 | "settings": 2031 | { 2032 | }, 2033 | "show_minimap": true, 2034 | "show_open_files": true, 2035 | "show_tabs": true, 2036 | "side_bar_visible": true, 2037 | "side_bar_width": 235.0, 2038 | "status_bar_visible": true, 2039 | "template_settings": 2040 | { 2041 | } 2042 | } 2043 | -------------------------------------------------------------------------------- /messageboxpreferences/Makefile: -------------------------------------------------------------------------------- 1 | GO_EASY_ON_ME=1 2 | 3 | TARGET = iphone:clang:latest:7.0 4 | ARCHS = armv7 armv7s arm64 5 | 6 | include theos/makefiles/common.mk 7 | 8 | BUNDLE_NAME = messageboxpreferences 9 | messageboxpreferences_FILES = messageboxpreferences.mm 10 | messageboxpreferences_INSTALL_PATH = /Library/PreferenceBundles 11 | messageboxpreferences_FRAMEWORKS = UIKit 12 | messageboxpreferences_PRIVATE_FRAMEWORKS = Preferences 13 | 14 | include $(THEOS_MAKE_PATH)/bundle.mk 15 | 16 | internal-stage:: 17 | $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) 18 | $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/messageboxpreferences.plist$(ECHO_END) 19 | -------------------------------------------------------------------------------- /messageboxpreferences/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | messageboxpreferences 9 | CFBundleIdentifier 10 | ca.adambell.messageboxpreferences 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | DTPlatformName 22 | iphoneos 23 | MinimumOSVersion 24 | 3.0 25 | NSPrincipalClass 26 | messageboxpreferencesListController 27 | 28 | 29 | -------------------------------------------------------------------------------- /messageboxpreferences/Resources/MessageBox-Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3ll/MessageBox/dd57cea1edcd3ab2001fde542682451e3082d513/messageboxpreferences/Resources/MessageBox-Icon.png -------------------------------------------------------------------------------- /messageboxpreferences/Resources/MessageBox-Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3ll/MessageBox/dd57cea1edcd3ab2001fde542682451e3082d513/messageboxpreferences/Resources/MessageBox-Icon@2x.png -------------------------------------------------------------------------------- /messageboxpreferences/Resources/MessageBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3ll/MessageBox/dd57cea1edcd3ab2001fde542682451e3082d513/messageboxpreferences/Resources/MessageBox.png -------------------------------------------------------------------------------- /messageboxpreferences/Resources/MessageBox@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3ll/MessageBox/dd57cea1edcd3ab2001fde542682451e3082d513/messageboxpreferences/Resources/MessageBox@2x.png -------------------------------------------------------------------------------- /messageboxpreferences/Resources/messageboxpreferences.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | entry 6 | 7 | cell 8 | PSLinkCell 9 | icon 10 | MessageBox.png 11 | label 12 | MessageBox 13 | 14 | items 15 | 16 | 17 | cell 18 | PSGroupCell 19 | 20 | 21 | PostNotification 22 | ca.adambell.messagebox.preferences-changed 23 | cell 24 | PSSwitchCell 25 | default 26 | 27 | defaults 28 | ca.adambell.messagebox 29 | key 30 | messageBoxEnabled 31 | label 32 | Enabled 33 | 34 | 35 | cell 36 | PSGroupCell 37 | footerText 38 | Enabling both of these will grant unexpected results (might cause the planet to implode). 39 | height 40 | 20 41 | 42 | 43 | PostNotification 44 | ca.adambell.messagebox.preferences-changed 45 | cell 46 | PSSwitchCell 47 | default 48 | 49 | defaults 50 | ca.adambell.messagebox 51 | key 52 | messageBoxPaperEnabled 53 | label 54 | Paper Enabled 55 | 56 | 57 | PostNotification 58 | ca.adambell.messagebox.preferences-changed 59 | cell 60 | PSSwitchCell 61 | default 62 | 63 | defaults 64 | ca.adambell.messagebox 65 | key 66 | messageBoxFacebookEnabled 67 | label 68 | Facebook Enabled 69 | 70 | 71 | cell 72 | PSGroupCell 73 | footerText 74 | MessageBox will disable itself if it detects an unsupported version. 75 | You can enable it manually using this. 76 | 77 | 78 | PostNotification 79 | ca.adambell.messagebox.preferences-changed 80 | cell 81 | PSSwitchCell 82 | default 83 | 84 | defaults 85 | ca.adambell.messagebox 86 | key 87 | messageBoxForceEnabled 88 | label 89 | Ignore Version Check 90 | 91 | 92 | cell 93 | PSGroupCell 94 | footerText 95 | © 2014 Adam Bell 96 | height 97 | 20 98 | 99 | 100 | title 101 | MessageBox 102 | 103 | 104 | -------------------------------------------------------------------------------- /messageboxpreferences/entry.plist: -------------------------------------------------------------------------------- 1 | { 2 | entry = { 3 | bundle = messageboxpreferences; 4 | cell = PSLinkCell; 5 | detail = messageboxpreferencesListController; 6 | icon = MessageBox.png; 7 | isController = 1; 8 | label = MessageBox; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /messageboxpreferences/messageboxpreferences.mm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #define KEY_ENABLED @"messageBoxEnabled" 5 | #define KEY_FORCE_ENABLED @"messageBoxForceEnabled" 6 | #define KEY_USE_PAPER @"messageBoxPaperEnabled" 7 | #define KEY_USE_FACEBOOK @"messageBoxFacebookEnabled" 8 | 9 | @interface messageboxpreferencesListController: PSListController { 10 | } 11 | @end 12 | 13 | @implementation messageboxpreferencesListController 14 | 15 | NSDictionary *_prefs; 16 | __weak messageboxpreferencesListController *_weakSelf; 17 | 18 | - (id)init { 19 | self = [super init]; 20 | _weakSelf = self; 21 | 22 | // stupid switch setup 23 | CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter(); 24 | CFNotificationCenterAddObserver(darwin, NULL, messageBoxPrefsChanged, CFSTR("ca.adambell.messagebox.preferences-changed"), NULL, CFNotificationSuspensionBehaviorCoalesce); 25 | 26 | _prefs = [[NSDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/ca.adambell.messagebox.plist"]; 27 | 28 | return self; 29 | } 30 | 31 | // dirty hack but apparently the confirmation dict doesn't work anymore :( 32 | static void messageBoxPrefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 33 | NSDictionary *prefs = [[NSDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/ca.adambell.messagebox.plist"]; 34 | 35 | BOOL enabled = [prefs[KEY_ENABLED] boolValue]; 36 | BOOL previouslyEnabled = [_prefs[KEY_ENABLED] boolValue]; 37 | 38 | BOOL forceEnabled = [prefs[KEY_FORCE_ENABLED] boolValue]; 39 | BOOL previouslyForceEnabled = [prefs[KEY_FORCE_ENABLED] boolValue]; 40 | 41 | if ((enabled != previouslyEnabled) || (forceEnabled != previouslyForceEnabled)) { 42 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"MessageBox" 43 | message:@"Changing this option requires you to restart SpringBoard." 44 | delegate:_weakSelf 45 | cancelButtonTitle:@"Cancel" 46 | otherButtonTitles:@"Respring", nil]; 47 | [alertView show]; 48 | } 49 | 50 | BOOL paperEnabled = [prefs[KEY_USE_PAPER] boolValue]; 51 | BOOL paperPreviouslyEnabled = [_prefs[KEY_USE_PAPER] boolValue]; 52 | 53 | if (paperEnabled != paperPreviouslyEnabled) { 54 | system("killall Paper"); 55 | } 56 | 57 | BOOL facebookEnabled = [prefs[KEY_USE_FACEBOOK] boolValue]; 58 | BOOL facebookPreviouslyEnabled = [_prefs[KEY_USE_FACEBOOK] boolValue]; 59 | 60 | if (facebookEnabled != facebookPreviouslyEnabled) { 61 | system("killall Facebook"); 62 | } 63 | 64 | _prefs = [[NSDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/ca.adambell.messagebox.plist"]; 65 | } 66 | 67 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 68 | if (buttonIndex == alertView.firstOtherButtonIndex) { 69 | // respring 70 | system("killall backboardd"); 71 | } 72 | } 73 | 74 | - (id)specifiers { 75 | if(_specifiers == nil) { 76 | _specifiers = [[self loadSpecifiersFromPlistName:@"messageboxpreferences" target:self] retain]; 77 | } 78 | return _specifiers; 79 | } 80 | 81 | @end 82 | 83 | // vim:ft=objc 84 | -------------------------------------------------------------------------------- /messageboxpreferences/theos: -------------------------------------------------------------------------------- 1 | /opt/theos -------------------------------------------------------------------------------- /readme/messageboxPreview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3ll/MessageBox/dd57cea1edcd3ab2001fde542682451e3082d513/readme/messageboxPreview.gif -------------------------------------------------------------------------------- /theos: -------------------------------------------------------------------------------- 1 | /opt/theos --------------------------------------------------------------------------------