├── .gitignore ├── Anemone.h ├── Asphaleia2.h ├── Backgrounding ├── BackgroundModeTogglerActivator.xm ├── IconIndicator.xm ├── Makefile ├── RABackgrounder.h ├── RABackgrounder.xm ├── ReachAppBackgrounding.plist ├── SpringBoard.xm ├── SpringBoard_UIAppCustomBackgroundModes.xm └── UnlimitedBackgrounding.xm ├── BioLockdown.h ├── ColorBadges.h ├── DRM └── Statistics.xm ├── Debugging └── Core.xm ├── GestureSupport ├── Hooks_iOS8.xm ├── Hooks_iOS9.xm ├── RAGestureCallback.h ├── RAGestureCallback.xm ├── RAGestureManager.h └── RAGestureManager.xm ├── IntroTutorial └── Intro.xm ├── KeyboardSupport ├── RAKeyboardStateListener.h ├── RAKeyboardStateListener.xm ├── RAKeyboardWindow.h ├── RAKeyboardWindow.mm ├── RARemoteKeyboardView.h ├── RARemoteKeyboardView.xm ├── RASpringBoardKeyboardActivation.h └── RASpringBoardKeyboardActivation.xm ├── Makefile ├── Messaging ├── RAMessaging.h ├── RAMessagingClient.h ├── RAMessagingClient.xm ├── RAMessagingServer.h ├── RAMessagingServer.xm └── overview.txt ├── MissionControl ├── ActivatorListener.xm ├── AppSwitcher.xm ├── Makefile ├── RAMissionControlManager.h ├── RAMissionControlManager.xm ├── RAMissionControlPreviewView.h ├── RAMissionControlPreviewView.xm ├── RAMissionControlWindow.h ├── RAMissionControlWindow.xm └── ReachAppMissionControl.plist ├── Multiplexer.h ├── Multiplexer.xm ├── NotificationCenterApp ├── NCHook.xm ├── RANCViewController.h └── RANCViewController.xm ├── PDFImage.h ├── PDFImage.m ├── PDFImageOptions.h ├── PDFImageOptions.m ├── RAAppKiller.h ├── RAAppKiller.xm ├── RAAppSelectorView.h ├── RAAppSelectorView.xm ├── RAAppSliderProvider.h ├── RAAppSliderProvider.mm ├── RAAppSliderProviderView.h ├── RAAppSliderProviderView.mm ├── RAAppSwitcherModelWrapper.h ├── RAAppSwitcherModelWrapper.xm ├── RACompatibilitySystem.h ├── RACompatibilitySystem.mm ├── RAControlCenterInhibitor.h ├── RAControlCenterInhibitor.xm ├── RAFakePhoneMode.h ├── RAFakePhoneMode.xm ├── RAHostManager.h ├── RAHostManager.xm ├── RAHostedAppView.h ├── RAHostedAppView.xm ├── RAHostedWidgetView.h ├── RAHostedWidgetView.xm ├── RAInsetLabel.h ├── RAInsetLabel.mm ├── RALocalizer.h ├── RALocalizer.mm ├── RAOrientationLocker.h ├── RAOrientationLocker.xm ├── RAResourceImageProvider.h ├── RAResourceImageProvider.mm ├── RARunningAppsProvider.h ├── RARunningAppsProvider.xm ├── RASBWorkspaceFetcher.h ├── RASBWorkspaceFetcher.xm ├── RASettings.h ├── RASettings.mm ├── RASnapshotProvider.h ├── RASnapshotProvider.xm ├── README.md ├── ReachApp.plist ├── ReachAppIntegrator.h ├── Reachability ├── RAReachabilityManager.h ├── RAReachabilityManager.mm ├── Reachability.xm └── UIKit.xm ├── SKBounceAnimation.h ├── SKBounceAnimation.m ├── SpringBoard.xm ├── SwipeOver ├── Makefile ├── RASwipeOverManager.h ├── RASwipeOverManager.xm ├── RASwipeOverOverlay.h ├── RASwipeOverOverlay.xm ├── ReachAppSwipeOver.plist └── SwipeOverGesture.xm ├── Theming ├── RATheme.h ├── RATheme.mm ├── RAThemeLoader.h ├── RAThemeLoader.mm ├── RAThemeManager.h └── RAThemeManager.mm ├── TutorialApp └── multiplexertutorial │ ├── Makefile │ ├── MultiplexerTutorial.plist │ ├── Tweak.xm │ └── layout │ ├── Applications │ └── Multiplexer.app │ │ ├── AppIcon29x29@2x.png │ │ ├── AppIcon29x29@2x~ipad.png │ │ ├── AppIcon29x29@3x.png │ │ ├── AppIcon29x29~ipad.png │ │ ├── AppIcon40x40@2x.png │ │ ├── AppIcon40x40@2x~ipad.png │ │ ├── AppIcon40x40@3x.png │ │ ├── AppIcon40x40~ipad.png │ │ ├── AppIcon60x60@2x.png │ │ ├── AppIcon60x60@3x.png │ │ ├── AppIcon76x76@2x~ipad.png │ │ ├── AppIcon76x76~ipad.png │ │ ├── Assets.car │ │ ├── Info.plist │ │ ├── Launch Screen.storyboardc │ │ ├── 01J-lp-oVM-view-Ze5-6b-2t3.nib │ │ ├── Info.plist │ │ └── UIViewController-01J-lp-oVM.nib │ │ ├── Multiplexer │ │ ├── PkgInfo │ │ ├── _CodeSignature │ │ └── CodeResources │ │ ├── archived-expanded-entitlements.xcent │ │ ├── au1.mp4 │ │ ├── au2.mp4 │ │ ├── au3.mp4 │ │ ├── au4.mp4 │ │ ├── au5.mp4 │ │ ├── au6.mp4 │ │ ├── em1.mp4 │ │ ├── em2.mp4 │ │ ├── em3.mp4 │ │ ├── em4.mp4 │ │ ├── em5.mp4 │ │ ├── em6.mp4 │ │ ├── embedded.mobileprovision │ │ ├── mc1.mp4 │ │ ├── mc2.mp4 │ │ ├── mc3.mp4 │ │ ├── mc4.mp4 │ │ ├── mc5.mp4 │ │ ├── mc6.mp4 │ │ ├── mc7.mp4 │ │ ├── qa1.mp4 │ │ ├── qa2.mp4 │ │ ├── ra1.mp4 │ │ ├── ra2.mp4 │ │ ├── ra3.mp4 │ │ ├── ra4.mp4 │ │ ├── so1.mp4 │ │ ├── so2.mp4 │ │ ├── so3.mp4 │ │ └── so4.mp4 │ └── DEBIAN │ └── control ├── Tweak.xm ├── UIColor+HexString.h ├── UIColor+HexString.m ├── UIKit.xm ├── WindowedMultitasking ├── ActivatorToggleEditModeListener.xm ├── LaunchToWindow.xm ├── RADesktopManager.h ├── RADesktopManager.xm ├── RADesktopWindow.h ├── RADesktopWindow.mm ├── RAWindowBar.h ├── RAWindowBar.xm ├── RAWindowOverlayView.h ├── RAWindowOverlayView.xm ├── RAWindowSnapDataProvider.h ├── RAWindowSnapDataProvider.xm ├── RAWindowSorter.h ├── RAWindowSorter.xm ├── RAWindowStatePreservationSystemManager.h ├── RAWindowStatePreservationSystemManager.xm ├── StartMultitaskingGesture.xm └── WindowSorterActivator.xm ├── dispatch_after_cancel.h ├── dispatch_after_cancel.m ├── headers.h ├── layout ├── DEBIAN │ ├── control │ ├── postinst │ └── prerm └── Library │ ├── Activator │ └── Listeners │ │ ├── com.efrederickson.reachapp.backgrounder.togglemode │ │ ├── Info.plist │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ └── icon-small@3x.png │ │ ├── com.efrederickson.reachapp.missioncontrol.activatorlistener │ │ ├── Info.plist │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ └── icon-small@3x.png │ │ ├── com.efrederickson.reachapp.windowedmultitasking.sortWindows │ │ ├── Info.plist │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ └── icon-small@3x.png │ │ └── com.efrederickson.reachapp.windowedmultitasking.toggleEditMode │ │ ├── Info.plist │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ └── icon-small@3x.png │ ├── LaunchDaemons │ └── com.efrederickson.reachapp.fsdaemon.plist │ └── Multiplexer │ ├── Localizations │ └── en.strings │ ├── Resources │ ├── Close.pdf │ ├── Grabber.pdf │ ├── Lock.pdf │ ├── Minus.pdf │ ├── Plus.pdf │ ├── SwipeOverDetachImage.pdf │ ├── Trash.png │ ├── Trash@2x.png │ ├── Trash@3x.png │ └── Unlocked.pdf │ └── Themes │ ├── Dark.plist │ ├── Default.plist │ └── Windows.plist ├── public_api ├── Multiplexer.h ├── RAAppKiller.h ├── RAAppSelectorView.h ├── RAAppSliderProvider.h ├── RAAppSliderProviderView.h ├── RABackgrounder.h ├── RAControlCenterInhibitor.h ├── RADesktopManager.h ├── RADesktopWindow.h ├── RAFakePhoneMode.h ├── RAGestureManager.h ├── RAHostedAppView.h ├── RAInsetLabel.h ├── RAMessaging.h ├── RAMessagingClient.h ├── RAMessagingServer.h ├── RAMissionControlManager.h ├── RAReachabilityManager.h ├── RAResourceImageProvider.h ├── RARunningAppsProvider.h ├── RASettings.h ├── RASwipeOverManager.h ├── RATheme.h ├── RAThemeManager.h ├── RAWindowBar.h ├── ReachAppIntegrator.h └── widgets │ ├── RADefaultWidgetSection.h │ ├── RAWidget.h │ ├── RAWidgetSection.h │ └── RAWidgetSectionManager.h ├── reachappassertiondhooks ├── Makefile ├── ReachAppAssertiondHooks.plist └── Tweak.xm ├── reachappbackboarddhooks ├── Makefile ├── ReachAppBackboarddHooks.plist └── Tweak.xm ├── reachappfakephonemode ├── Makefile ├── ReachAppFakePhoneMode.plist └── Tweak.xm ├── reachappflipswitch ├── FSSwitchDataSource.h ├── FSSwitchPanel.h ├── FSSwitchState.h ├── Makefile ├── Resources │ ├── Info.plist │ └── glyph.pdf └── Switch.x ├── reachappfsdaemon ├── Makefile └── main.mm ├── reachappsettings ├── BackgroundPerAppDetailsController.h ├── BackgroundPerAppDetailsController.xm ├── BackgrounderPerApp.xm ├── BackgrounderSettings.xm ├── Makefile ├── MissionControlSettings.xm ├── NCApp.xm ├── RAHeaderView.h ├── RAHeaderView.mm ├── RAListItemsController.xm ├── RASupportController.xm ├── ReachAppSettings.mm ├── Reachability.xm ├── Resources │ ├── Andi.png │ ├── Andi@2x.png │ ├── Andi@3x.png │ ├── BackgrounderHeader.pdf │ ├── Binders.png │ ├── Binders@2x.png │ ├── Binders@3x.png │ ├── Chon.png │ ├── Chon@2x.png │ ├── Chon@3x.png │ ├── David.png │ ├── David@2x.png │ ├── David@3x.png │ ├── EmpoleonHeader.pdf │ ├── EthanArbuckle.png │ ├── EthanArbuckle@2x.png │ ├── EthanArbuckle@3x.png │ ├── Info.plist │ ├── Jack.png │ ├── Jack@2x.png │ ├── Jack@3x.png │ ├── MainHeader.pdf │ ├── MissionControlHeader.pdf │ ├── Moshe.png │ ├── Moshe@2x.png │ ├── Moshe@3x.png │ ├── Multiplexer.png │ ├── Multiplexer@2x.png │ ├── Multiplexer@3x.png │ ├── NCAppHeader.pdf │ ├── ReachAppHeader.pdf │ ├── Reset.png │ ├── Reset@2x.png │ ├── Reset@3x.png │ ├── SharedRoutine.png │ ├── SharedRoutine@2x.png │ ├── SharedRoutine@3x.png │ ├── SwipeOverHeader.pdf │ ├── Wilson.png │ ├── Wilson@2x.png │ ├── Wilson@3x.png │ ├── Ziphon.png │ ├── Ziphon@2x.png │ ├── Ziphon@3x.png │ ├── andrew.png │ ├── andrew@2x.png │ ├── andrew@3x.png │ ├── aura.png │ ├── aura@2x.png │ ├── aura@3x.png │ ├── beta382.png │ ├── beta382@2x.png │ ├── beta382@3x.png │ ├── elijah.png │ ├── elijah@2x.png │ ├── elijah@3x.png │ ├── empoleon.png │ ├── empoleon@2x.png │ ├── empoleon@3x.png │ ├── github.png │ ├── github@2x.png │ ├── github@3x.png │ ├── missioncontrol.png │ ├── missioncontrol@2x.png │ ├── missioncontrol@3x.png │ ├── quickaccess.png │ ├── quickaccess@2x.png │ ├── quickaccess@3x.png │ ├── ra_enabled.png │ ├── ra_enabled@2x.png │ ├── ra_enabled@3x.png │ ├── ra_makers.png │ ├── ra_makers@2x.png │ ├── ra_makers@3x.png │ ├── ra_support.png │ ├── ra_support@2x.png │ ├── ra_support@3x.png │ ├── reachapp.png │ ├── reachapp@2x.png │ ├── reachapp@3x.png │ ├── swipeover.png │ ├── swipeover@2x.png │ ├── swipeover@3x.png │ ├── theme.png │ ├── theme@2x.png │ ├── theme@3x.png │ ├── tutorial.png │ ├── tutorial@2x.png │ └── tutorial@3x.png ├── SwipeOver.xm ├── WindowedMultitasking.xm └── entry.plist ├── update_status └── widgets ├── Core ├── RAReachabilityWidgetShim.h ├── RAReachabilityWidgetShim.xm ├── RAWidgetBase.h ├── RAWidgetBase.xm ├── RAWidgetHostManager.h └── RAWidgetHostManager.xm └── Reachability ├── RAAllAppsWidget.h ├── RAAllAppsWidget.xm ├── RADefaultWidgetSection.h ├── RADefaultWidgetSection.mm ├── RAFavoriteAppsWidget.h ├── RAFavoriteAppsWidget.xm ├── RARecentAppsWidget.h ├── RARecentAppsWidget.xm ├── RAWidget.h ├── RAWidget.mm ├── RAWidgetSection.h ├── RAWidgetSection.mm ├── RAWidgetSectionManager.h └── RAWidgetSectionManager.mm /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | ._* 3 | *.deb 4 | .debmake 5 | _ 6 | obj 7 | .theos 8 | *.bak 9 | debs/ 10 | theos 11 | backboardd 12 | backboardd_headers/ 13 | disabled* 14 | DISABLED* 15 | build_and_deploy.sh 16 | sloc.sh 17 | *_TODO 18 | *_TODO.* 19 | TODO_* 20 | _TODO_* 21 | -------------------------------------------------------------------------------- /Anemone.h: -------------------------------------------------------------------------------- 1 | // From: slack logs 2 | // Usage to get icon badge: 3 | // 4 | // @interface SBIconBadgeView 5 | // + (SBIconAccessoryImage *)_checkoutBackgroundImage; 6 | // @end 7 | // 8 | // [UIImage imageNamed:@"SBBadgeBG.png"] 9 | // 10 | // Notes: 11 | // Can convert to UIColor with +[UIColor colorWithPatternImage:] 12 | // Needs tested. Heard bad reports about colorWithPatternImage: and memory usage 13 | // 14 | 15 | @interface ANEMSettingsManager : NSObject { 16 | NSArray *_themeSettings; 17 | } 18 | + (instancetype)sharedManager; 19 | - (NSArray *)themeSettings; 20 | @end 21 | 22 | #define HAS_ANEMONE (objc_getClass("ANEMSettingsManager") != nil) 23 | -------------------------------------------------------------------------------- /Asphaleia2.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | // https://gist.github.com/evilGoldfish/49753c4aa247b727453e 4 | 5 | typedef NS_ENUM(NSInteger, ASAuthenticationAlertType) { 6 | ASAuthenticationAlertAppArranging, 7 | ASAuthenticationAlertSwitcher, 8 | ASAuthenticationAlertSpotlight, 9 | ASAuthenticationAlertPowerDown, 10 | ASAuthenticationAlertControlCentre, 11 | ASAuthenticationAlertControlPanel, 12 | ASAuthenticationAlertPhotos, 13 | ASAuthenticationAlertSettingsPanel, 14 | ASAuthenticationAlertFlipswitch 15 | }; 16 | 17 | typedef void (^ASCommonAuthenticationHandler) (BOOL wasCancelled); 18 | 19 | @interface ASCommon : NSObject { 20 | ASCommonAuthenticationHandler authHandler; 21 | } 22 | +(instancetype)sharedInstance; 23 | -(UIAlertView *)currentAuthAlert; 24 | -(BOOL)authenticateAppWithDisplayIdentifier:(NSString *)appIdentifier customMessage:(NSString *)customMessage dismissedHandler:(ASCommonAuthenticationHandler)handler; 25 | -(BOOL)authenticateFunction:(ASAuthenticationAlertType)alertType dismissedHandler:(ASCommonAuthenticationHandler)handler; 26 | 27 | @end 28 | 29 | #define LOAD_ASPHALEIA if ([NSFileManager.defaultManager fileExistsAtPath:@"/usr/lib/libasphaleiaui.dylib"]) dlopen("/usr/lib/libasphaleiaui.dylib", RTLD_LAZY); 30 | 31 | #define HAS_ASPHALEIA2 (objc_getClass("ASCommon") != nil) 32 | #define IF_ASPHALEIA2 if (HAS_ASPHALEIA2) 33 | 34 | #define ASPHALEIA2_AUTHENTICATE_APP(ident, success, failure_) \ 35 | BOOL isAppProtected = [[objc_getClass("ASCommon") sharedInstance] authenticateAppWithDisplayIdentifier:ident customMessage:nil dismissedHandler:^(BOOL wasCancelled) { \ 36 | if (!wasCancelled) \ 37 | success(); \ 38 | else \ 39 | failure_(); \ 40 | }]; \ 41 | if (!isAppProtected) { \ 42 | success(); \ 43 | } -------------------------------------------------------------------------------- /Backgrounding/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | 3 | CFLAGS = -I../ -I../Theming/ 4 | CFLAGS += -fno-objc-arc 5 | LDFLAGS += -Wl,-segalign,4000 6 | 7 | include $(THEOS)/makefiles/common.mk 8 | 9 | TWEAK_NAME = ReachAppBackgrounding 10 | ReachAppBackgrounding_FILES = $(wildcard *.xm) $(wildcard *.mm) $(wildcard *.m) ../Tweak.xm 11 | ReachAppBackgrounding_FRAMEWORKS = UIKit CoreGraphics 12 | ReachAppBackgrounding_LIBRARIES = applist 13 | 14 | include $(THEOS_MAKE_PATH)/tweak.mk 15 | 16 | after-install:: 17 | install.exec "killall -9 SpringBoard" 18 | -------------------------------------------------------------------------------- /Backgrounding/RABackgrounder.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | enum RABackgroundMode { 4 | RABackgroundModeNative = 1, 5 | RABackgroundModeForceNativeForOldApps = 2, 6 | RABackgroundModeForcedForeground = 3, 7 | RABackgroundModeForceNone = 4, 8 | RABackgroundModeSuspendImmediately = 5, 9 | RABackgroundModeUnlimitedBackgroundingTime = 6, 10 | }; 11 | 12 | enum RAIconIndicatorViewInfo { 13 | RAIconIndicatorViewInfoNone = 0, 14 | RAIconIndicatorViewInfoNative = 1, 15 | RAIconIndicatorViewInfoForced = 2, 16 | RAIconIndicatorViewInfoSuspendImmediately = 4, 17 | 18 | RAIconIndicatorViewInfoUnkillable = 8, 19 | RAIconIndicatorViewInfoForceDeath = 16, 20 | 21 | RAIconIndicatorViewInfoUnlimitedBackgroundTime = 32, 22 | 23 | 24 | RAIconIndicatorViewInfoTemporarilyInhibit = 1024, 25 | RAIconIndicatorViewInfoInhibit = 2048, 26 | RAIconIndicatorViewInfoUninhibit = 4096, 27 | }; 28 | 29 | NSString *FriendlyNameForBackgroundMode(RABackgroundMode mode); 30 | 31 | @interface RABackgrounder : NSObject 32 | +(id) sharedInstance; 33 | 34 | -(BOOL) shouldAutoLaunchApplication:(NSString*)identifier; 35 | -(BOOL) shouldAutoRelaunchApplication:(NSString*)identifier; 36 | 37 | -(BOOL) shouldKeepInForeground:(NSString*)identifier; 38 | -(BOOL) shouldSuspendImmediately:(NSString*)identifier; 39 | 40 | -(BOOL) killProcessOnExit:(NSString*)identifier; 41 | -(BOOL) shouldRemoveFromSwitcherWhenKilledOnExit:(NSString*)identifier; 42 | -(BOOL) preventKillingOfIdentifier:(NSString*)identifier; 43 | -(NSInteger) backgroundModeForIdentifier:(NSString*)identifier; 44 | -(BOOL) hasUnlimitedBackgroundTime:(NSString*)identifier; 45 | 46 | -(void) temporarilyApplyBackgroundingMode:(RABackgroundMode)mode forApplication:(SBApplication*)app andCloseForegroundApp:(BOOL)close; 47 | -(void) queueRemoveTemporaryOverrideForIdentifier:(NSString*)identifier; 48 | -(void) removeTemporaryOverrideForIdentifier:(NSString*)identifier; 49 | 50 | -(NSInteger) application:(NSString*)identifier overrideBackgroundMode:(NSString*)mode; 51 | 52 | -(RAIconIndicatorViewInfo) allAggregatedIndicatorInfoForIdentifier:(NSString*)identifier; 53 | -(void) updateIconIndicatorForIdentifier:(NSString*)identifier withInfo:(RAIconIndicatorViewInfo)info; 54 | -(BOOL) shouldShowIndicatorForIdentifier:(NSString*)identifier; 55 | -(BOOL) shouldShowStatusBarIconForIdentifier:(NSString*)identifier; 56 | @end -------------------------------------------------------------------------------- /Backgrounding/ReachAppBackgrounding.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.UIKit" ); }; } 2 | -------------------------------------------------------------------------------- /Backgrounding/SpringBoard_UIAppCustomBackgroundModes.xm: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RABackgrounder.h" 3 | #include 4 | #include 5 | #include 6 | 7 | @interface FBApplicationInfo : NSObject 8 | @property (nonatomic, copy) NSString *bundleIdentifier; 9 | -(BOOL) isExitsOnSuspend; 10 | @end 11 | 12 | %hook FBApplicationInfo 13 | - (BOOL)supportsBackgroundMode:(__unsafe_unretained NSString *)mode 14 | { 15 | int override = [RABackgrounder.sharedInstance application:self.bundleIdentifier overrideBackgroundMode:mode]; 16 | if (override == -1) 17 | return %orig; 18 | return override; 19 | } 20 | %end 21 | 22 | %hook BKSProcessAssertion 23 | - (id)initWithPID:(int)arg1 flags:(unsigned int)arg2 reason:(unsigned int)arg3 name:(unsafe_id)arg4 withHandler:(unsafe_id)arg5 24 | { 25 | if ((arg3 == kProcessAssertionReasonViewServices) == NO && // whitelist this to allow share menu to work 26 | [arg4 isEqualToString:@"Called by iOS6_iCleaner, from unknown method"] == NO && // whitelist iCleaner to prevent crash on open 27 | [arg4 isEqualToString:@"Called by Filza_main, from -[AppDelegate applicationDidEnterBackground:]"] == NO && // Whitelist filza to prevent iOS hang (?!) 28 | [NSBundle.mainBundle.bundleIdentifier isEqualToString:@"com.apple.springboard"] == NO) // FIXME: this is a hack that prevents SpringBoard from not starting 29 | { 30 | NSString *identifier = NSBundle.mainBundle.bundleIdentifier; 31 | 32 | if (!identifier) 33 | goto ORIGINAL; 34 | 35 | //NSLog(@"[ReachApp] BKSProcessAssertion initWithPID:'%d' flags:'%d' reason:'%d' name:'%@' withHandler:'%@' process identifier:'%@'", arg1, arg2, arg3, arg4, arg5, identifier); 36 | 37 | if ([RABackgrounder.sharedInstance shouldSuspendImmediately:identifier]) 38 | { 39 | if ((arg3 >= kProcessAssertionReasonAudio && arg3 <= kProcessAssertionReasonVOiP)) // In most cases arg3 == 4 (finish task) 40 | { 41 | //NSLog(@"[ReachApp] blocking BKSProcessAssertion"); 42 | 43 | //if (arg5) 44 | //{ 45 | //void (^arg5fix)() = arg5; 46 | //arg5fix(); 47 | // ^^ causes crashes with share menu 48 | //} 49 | return nil; 50 | } 51 | //else if (arg3 == kProcessAssertionReasonActivation) 52 | //{ 53 | // arg2 = ProcessAssertionFlagAllowIdleSleep; 54 | //} 55 | } 56 | } 57 | ORIGINAL: 58 | return %orig(arg1, arg2, arg3, arg4, arg5); 59 | } 60 | %end 61 | -------------------------------------------------------------------------------- /Backgrounding/UnlimitedBackgrounding.xm: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RABackgrounder.h" 3 | #import "RARunningAppsProvider.h" 4 | 5 | NSMutableDictionary *processAssertions = [NSMutableDictionary dictionary]; 6 | BKSProcessAssertion *keepAlive$temp; 7 | 8 | %hook FBUIApplicationWorkspaceScene 9 | -(void) host:(__unsafe_unretained FBScene*)arg1 didUpdateSettings:(__unsafe_unretained FBSSceneSettings*)arg2 withDiff:(unsafe_id)arg3 transitionContext:(unsafe_id)arg4 completion:(unsafe_id)arg5 10 | { 11 | if ([RABackgrounder.sharedInstance hasUnlimitedBackgroundTime:arg1.identifier] && arg2.backgrounded == YES && [processAssertions objectForKey:arg1.identifier] == nil) 12 | { 13 | SBApplication *app = [[%c(SBApplicationController) sharedInstance] applicationWithBundleIdentifier:arg1.identifier]; 14 | 15 | keepAlive$temp = [[%c(BKSProcessAssertion) alloc] initWithPID:[app pid] 16 | flags:(ProcessAssertionFlagPreventSuspend | ProcessAssertionFlagAllowIdleSleep | ProcessAssertionFlagPreventThrottleDownCPU | ProcessAssertionFlagWantsForegroundResourcePriority) 17 | reason:kProcessAssertionReasonBackgroundUI 18 | name:@"reachapp" 19 | withHandler:^{ 20 | NSLog(@"ReachApp: %d kept alive: %@", [app pid], [keepAlive$temp valid] ? @"TRUE" : @"FALSE"); 21 | if (keepAlive$temp.valid) 22 | processAssertions[arg1.identifier] = keepAlive$temp; 23 | else 24 | { 25 | 26 | } 27 | }]; 28 | } 29 | %orig(arg1, arg2, arg3, arg4, arg5); 30 | } 31 | %end 32 | 33 | @interface RAUnlimitedBackgroundingAppWatcher : NSObject 34 | +(void) load; 35 | @end 36 | 37 | RAUnlimitedBackgroundingAppWatcher *sharedInstance$RAUnlimitedBackgroundingAppWatcher; 38 | 39 | @implementation RAUnlimitedBackgroundingAppWatcher 40 | +(void) load 41 | { 42 | IF_SPRINGBOARD { 43 | sharedInstance$RAUnlimitedBackgroundingAppWatcher = [[RAUnlimitedBackgroundingAppWatcher alloc] init]; 44 | [[%c(RARunningAppsProvider) sharedInstance] addTarget:sharedInstance$RAUnlimitedBackgroundingAppWatcher]; 45 | } 46 | } 47 | 48 | -(void) appDidDie:(__unsafe_unretained SBApplication*)app 49 | { 50 | if (/*W[RABackgrounder.sharedInstance preventKillingOfIdentifier:app.bundleIdentifier] == NO && */[processAssertions objectForKey:app.bundleIdentifier]) 51 | { 52 | [processAssertions[app.bundleIdentifier] invalidate]; 53 | [processAssertions removeObjectForKey:app.bundleIdentifier]; 54 | } 55 | } 56 | @end -------------------------------------------------------------------------------- /BioLockdown.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @class SBApplication; 5 | 6 | __attribute__((visibility("hidden"))) 7 | @interface BioLockdownController : NSObject 8 | 9 | + (BioLockdownController *)sharedController; 10 | 11 | - (BOOL)requiresAuthenticationForIdentifier:(NSString *)identifier; 12 | - (BOOL)requiresAuthenticationForApplication:(SBApplication *)application; 13 | - (BOOL)requiresAuthenticationForRecord:(ABRecordRef)record; 14 | 15 | - (BOOL)authenticateForIdentifier:(NSString *)identifier actionDescription:(NSString *)actionDescription completion:(dispatch_block_t)completion failure:(dispatch_block_t)failure; 16 | - (BOOL)authenticateForApplication:(SBApplication *)application actionText:(NSString *)actionText completion:(dispatch_block_t)completion failure:(dispatch_block_t)failure; 17 | - (BOOL)authenticateForSwitchIdentifier:(NSString *)switchIdentifier actionText:(NSString *)actionText completion:(dispatch_block_t)completion failure:(dispatch_block_t)failure; 18 | - (BOOL)authenticateForRecord:(ABRecordRef)record actionText:(NSString *)actionText completion:(dispatch_block_t)completion failure:(dispatch_block_t)failure; 19 | 20 | @end 21 | 22 | 23 | #define HAS_BIOLOCKDOWN (objc_getClass("BioLockdownController") != nil) 24 | #define IF_BIOLOCKDOWN if (HAS_BIOLOCKDOWN) 25 | 26 | #define BIOLOCKDOWN_AUTHENTICATE_APP(ident, success, failure_) \ 27 | if ([[objc_getClass("BioLockdownController") sharedController] requiresAuthenticationForIdentifier:ident]) \ 28 | { \ 29 | [[objc_getClass("BioLockdownController") sharedController] authenticateForIdentifier:ident actionDescription:LOCALIZE(@"BIOLOCKDOWN_AUTH_DESCRIPTION") completion:success failure:failure_]; \ 30 | } \ 31 | else \ 32 | success() -------------------------------------------------------------------------------- /ColorBadges.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // https://github.com/DavidGoldman/TweakAPIs/blob/master/ColorBadges.h 5 | 6 | #define GETRED(rgb) ((rgb >> 16) & 0xFF) 7 | #define GETGREEN(rgb) ((rgb >> 8) & 0xFF) 8 | #define GETBLUE(rgb) (rgb & 0xFF) 9 | #define UIColorFromRGB(rgb) [UIColor colorWithRed:GETRED(rgb)/255.0 green:GETGREEN(rgb)/255.0 blue:GETBLUE(rgb)/255.0 alpha:1.0] 10 | 11 | @interface ColorBadges : NSObject 12 | + (instancetype)sharedInstance; 13 | + (BOOL)isDarkColor:(int)color; 14 | + (BOOL)areBordersEnabled; 15 | + (BOOL)isEnabled; 16 | 17 | // Return RGB ints. i.e. 0xRRGGBB. 18 | - (int)colorForImage:(UIImage *)image; 19 | - (int)colorForIcon:(id)icon; // Must be an SBIcon * 20 | 21 | @end 22 | 23 | // You can use the API like the following. Note that you may need to dlopen ColorBadges first. 24 | /* 25 | @implementation YourObject 26 | - (void)configureMyBadge:(id)badge forIcon:(id)icon { 27 | Class cb = %c(ColorBadges); 28 | if ([cb isEnabled]) { 29 | int color = [[cb sharedInstance] colorForIcon:icon]; 30 | badge.tintColor = UIColorFromRGB(color); 31 | UIColor *textColor = ([cb isDarkColor:color]) ? [UIColor whiteColor] : [UIColor blackColor]; 32 | badge.textColor = textColor; 33 | if ([cb areBordersEnabled]) { 34 | UIColor *borderColor = textColor; 35 | // Add border. 36 | } 37 | } else { 38 | badge.tintColor = [UIColor redColor]; // Default color 39 | } 40 | } 41 | @end 42 | */ 43 | 44 | static inline int RGBFromUIColor(UIColor *self) 45 | { 46 | CGFloat red, green, blue; 47 | if ([self getRed:&red green:&green blue:&blue alpha:NULL]) 48 | { 49 | NSUInteger redInt = (NSUInteger)(red * 255 + 0.5); 50 | NSUInteger greenInt = (NSUInteger)(green * 255 + 0.5); 51 | NSUInteger blueInt = (NSUInteger)(blue * 255 + 0.5); 52 | 53 | return (redInt << 16) | (greenInt << 8) | blueInt; 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | #define HAS_COLORBADGES (objc_getClass("ColorBadges") != nil) 60 | #define GET_COLORBADGES_COLOR(icon, alt) HAS_COLORBADGES ? ([objc_getClass("ColorBadges") isEnabled] ? UIColorFromRGB([[objc_getClass("ColorBadges") sharedInstance] colorForIcon:icon]) : alt) : alt 61 | -------------------------------------------------------------------------------- /DRM/Statistics.xm: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | %ctor 4 | { 5 | IF_SPRINGBOARD { 6 | #if DEBUG 7 | NSLog(@"[ReachApp][DRM] Not checking statistics on debug build"); 8 | #else 9 | dispatch_async(dispatch_get_main_queue(), ^(void){ 10 | NSString *statsPath = @"/var/mobile/Library/Preferences/.multiplexer.stats_checked"; 11 | if ([NSFileManager.defaultManager fileExistsAtPath:statsPath] == NO) 12 | { 13 | CFStringRef (*$MGCopyAnswer)(CFStringRef); 14 | 15 | void *gestalt = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_GLOBAL | RTLD_LAZY); 16 | $MGCopyAnswer = (CFStringRef (*)(CFStringRef))dlsym(gestalt, "MGCopyAnswer"); 17 | 18 | NSString *udid = (__bridge NSString*)$MGCopyAnswer(CFSTR("UniqueDeviceID")); 19 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://elijahandandrew.com/multiplexer/stats.php?udid=%@", udid]] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0]; 20 | [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 21 | NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; 22 | int code = [httpResponse statusCode]; 23 | if (error == nil && (code == 0 || code == 200)) 24 | { 25 | [NSFileManager.defaultManager createFileAtPath:statsPath contents:[NSData new] attributes:nil]; 26 | } 27 | }]; 28 | } 29 | }); 30 | #endif 31 | } 32 | } -------------------------------------------------------------------------------- /Debugging/Core.xm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "RACompatibilitySystem.h" 4 | #include 5 | #include 6 | #include 7 | #import "headers.h" 8 | 9 | %hook NSObject 10 | -(void)doesNotRecognizeSelector:(SEL)selector 11 | { 12 | NSLog(@"[ReachApp] doesNotRecognizeSelector: selector '%@' on class '%s' (image: %s)", NSStringFromSelector(selector), class_getName(self.class), class_getImageName(self.class)); 13 | 14 | void *array[10]; 15 | size_t size; 16 | char **strings; 17 | size_t i; 18 | 19 | size = backtrace (array, 10); 20 | strings = backtrace_symbols (array, size); 21 | 22 | NSLog(@"[ReachApp] Obtained %zd stack frames:\n", size); 23 | 24 | for (i = 0; i < size; i++) 25 | { 26 | NSLog(@"[ReachApp] %s\n", strings[i]); 27 | } 28 | 29 | free(strings); 30 | 31 | %orig; 32 | } 33 | %end 34 | 35 | /*Class (*orig$objc_getClass)(const char *name); 36 | Class hook$objc_getClass(const char *name) 37 | { 38 | Class cls = orig$objc_getClass(name); 39 | if (!cls) 40 | { 41 | NSLog(@"[ReachApp] something attempted to access nil class '%s'", name); 42 | } 43 | return cls; 44 | }*/ 45 | 46 | %ctor 47 | { 48 | IF_SPRINGBOARD { 49 | 50 | // Causes cycript to not function 51 | //MSHookFunction((void*)objc_getClass, (void*)hook$objc_getClass, (void**)&orig$objc_getClass); 52 | 53 | %init; 54 | } 55 | //NSLog(@"[ReachApp] %s", class_getImageName(orig$objc_getClass("RAMissionControlManager"))); 56 | } 57 | -------------------------------------------------------------------------------- /GestureSupport/RAGestureCallback.h: -------------------------------------------------------------------------------- 1 | #import "RAGestureManager.h" 2 | 3 | @interface RAGestureCallback : NSObject 4 | 5 | @property (nonatomic, copy) RAGestureCallbackBlock callbackBlock; 6 | @property (nonatomic, copy) RAGestureConditionBlock conditionBlock; 7 | // OR 8 | @property (nonatomic, strong) NSObject *target; 9 | 10 | @property (nonatomic) UIRectEdge screenEdge; 11 | @property (nonatomic) NSUInteger priority; 12 | @property (nonatomic, retain) NSString *identifier; 13 | 14 | @end -------------------------------------------------------------------------------- /GestureSupport/RAGestureCallback.xm: -------------------------------------------------------------------------------- 1 | #import "RAGestureCallback.h" 2 | 3 | @implementation RAGestureCallback 4 | 5 | @end -------------------------------------------------------------------------------- /GestureSupport/RAGestureManager.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @class RAGestureCallback; 4 | 5 | typedef enum { 6 | RAGestureCallbackResultSuccessAndContinue, 7 | RAGestureCallbackResultFailure, 8 | RAGestureCallbackResultSuccessAndStop, 9 | 10 | RAGestureCallbackResultSuccess = RAGestureCallbackResultSuccessAndContinue, 11 | } RAGestureCallbackResult; 12 | 13 | @protocol RAGestureCallbackProtocol 14 | -(BOOL) RAGestureCallback_canHandle:(CGPoint)point velocity:(CGPoint)velocity; 15 | -(RAGestureCallbackResult) RAGestureCallback_handle:(UIGestureRecognizerState)state withPoint:(CGPoint)location velocity:(CGPoint)velocity forEdge:(UIRectEdge)edge; 16 | @end 17 | 18 | typedef BOOL(^RAGestureConditionBlock)(CGPoint location, CGPoint velocity); 19 | typedef RAGestureCallbackResult(^RAGestureCallbackBlock)(UIGestureRecognizerState state, CGPoint location, CGPoint velocity); 20 | 21 | const NSUInteger RAGesturePriorityLow = 0; 22 | const NSUInteger RAGesturePriorityHigh = 10; 23 | const NSUInteger RAGesturePriorityDefault = RAGesturePriorityLow; 24 | 25 | @interface RAGestureManager : NSObject { 26 | NSMutableArray *gestures; 27 | NSMutableDictionary *ignoredAreas; 28 | } 29 | +(id) sharedInstance; 30 | 31 | -(void) addGestureRecognizer:(RAGestureCallbackBlock)callbackBlock withCondition:(RAGestureConditionBlock)conditionBlock forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier priority:(NSUInteger)priority; 32 | -(void) addGestureRecognizer:(RAGestureCallbackBlock)callbackBlock withCondition:(RAGestureConditionBlock)conditionBlock forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier; 33 | -(void) addGestureRecognizerWithTarget:(NSObject*)target forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier; 34 | -(void) addGestureRecognizerWithTarget:(NSObject*)target forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier priority:(NSUInteger)priority; 35 | -(void) addGesture:(RAGestureCallback*)callback; 36 | -(void) removeGestureWithIdentifier:(NSString*)identifier; 37 | 38 | -(BOOL) canHandleMovementWithPoint:(CGPoint)point velocity:(CGPoint)velocity forEdge:(UIRectEdge)edge; 39 | -(BOOL) handleMovementOrStateUpdate:(UIGestureRecognizerState)state withPoint:(CGPoint)point velocity:(CGPoint)velocity forEdge:(UIRectEdge)edge; 40 | 41 | -(void) ignoreSwipesBeginningInRect:(CGRect)area forIdentifier:(NSString*)identifier; 42 | -(void) stopIgnoringSwipesForIdentifier:(NSString*)identifier; 43 | -(void) ignoreSwipesBeginningOnSide:(UIRectEdge)side aboveYAxis:(NSUInteger)axis forIdentifier:(NSString*)identifier; 44 | -(void) ignoreSwipesBeginningOnSide:(UIRectEdge)side belowYAxis:(NSUInteger)axis forIdentifier:(NSString*)identifier; 45 | @end -------------------------------------------------------------------------------- /IntroTutorial/Intro.xm: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RASettings.h" 3 | 4 | %hook SBLockScreenViewController 5 | - (void)finishUIUnlockFromSource:(int)arg1 6 | { 7 | %orig; 8 | if ([RASettings.sharedInstance isFirstRun]) 9 | { 10 | BBBulletinRequest *request = [[%c(BBBulletinRequest) alloc] init]; 11 | request.title = LOCALIZE(@"MULTIPLEXER"); 12 | request.message = LOCALIZE(@"THANK_YOU_TEXT"); 13 | request.sectionID = @"com.andrewabosh.Multiplexer"; 14 | request.date = [NSDate date]; 15 | request.defaultAction = [%c(BBAction) actionWithLaunchBundleID:@"com.andrewabosh.Multiplexer" callblock:nil]; 16 | request.expirationDate = [[NSDate date] dateByAddingTimeInterval:10]; 17 | SBBulletinBannerController *bannerController = [%c(SBBulletinBannerController) sharedInstance]; 18 | if ([bannerController respondsToSelector:@selector(observer:addBulletin:forFeed:playLightsAndSirens:withReply:)]) 19 | [bannerController observer:nil addBulletin:request forFeed:2 playLightsAndSirens:YES withReply:nil]; 20 | else 21 | [bannerController observer:nil addBulletin:request forFeed:2]; 22 | 23 | [RASettings.sharedInstance setFirstRun:NO]; 24 | } 25 | } 26 | %end -------------------------------------------------------------------------------- /KeyboardSupport/RAKeyboardStateListener.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAKeyboardStateListener : NSObject 4 | +(instancetype) sharedInstance; 5 | @property (nonatomic, readonly) BOOL visible; 6 | @property (nonatomic, readonly) CGSize size; 7 | 8 | 9 | -(void) _setVisible:(BOOL)val; 10 | -(void) _setSize:(CGSize)size; 11 | @end 12 | 13 | -------------------------------------------------------------------------------- /KeyboardSupport/RAKeyboardWindow.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RARemoteKeyboardView.h" 3 | 4 | @interface RAKeyboardWindow : UIWindow { 5 | RARemoteKeyboardView *kbView; 6 | } 7 | 8 | -(void) setupForKeyboardAndShow:(NSString*)identifier; 9 | -(void) removeKeyboard; 10 | 11 | -(unsigned int) contextId; 12 | @end 13 | -------------------------------------------------------------------------------- /KeyboardSupport/RAKeyboardWindow.mm: -------------------------------------------------------------------------------- 1 | #import "RAKeyboardWindow.h" 2 | #import "headers.h" 3 | #import "RAKeyboardStateListener.h" 4 | #import "RADesktopManager.h" 5 | 6 | @implementation RAKeyboardWindow 7 | -(void) setupForKeyboardAndShow:(NSString*)identifier 8 | { 9 | self.userInteractionEnabled = YES; 10 | self.backgroundColor = UIColor.clearColor; 11 | 12 | if (kbView) 13 | [self removeKeyboard]; 14 | 15 | kbView = [[RARemoteKeyboardView alloc] initWithFrame:UIScreen.mainScreen.bounds]; 16 | [kbView connectToKeyboardWindowForApp:identifier]; 17 | [self addSubview:kbView]; 18 | 19 | self.windowLevel = 9999; 20 | self.frame = UIScreen.mainScreen.bounds; 21 | [self makeKeyAndVisible]; 22 | } 23 | 24 | -(void) removeKeyboard 25 | { 26 | [kbView connectToKeyboardWindowForApp:nil]; 27 | [kbView removeFromSuperview]; 28 | kbView = nil; 29 | } 30 | 31 | -(unsigned int) contextId { return kbView.layerHost.contextId; } 32 | @end 33 | -------------------------------------------------------------------------------- /KeyboardSupport/RARemoteKeyboardView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface CALayerHost : CALayer 4 | @property (nonatomic, assign) unsigned int contextId; 5 | @end 6 | 7 | @interface RARemoteKeyboardView : UIView { 8 | BOOL update; 9 | NSString *_identifier; 10 | } 11 | @property (nonatomic, retain) CALayerHost *layerHost; 12 | -(void) connectToKeyboardWindowForApp:(NSString*)identifier; 13 | @end 14 | -------------------------------------------------------------------------------- /KeyboardSupport/RARemoteKeyboardView.xm: -------------------------------------------------------------------------------- 1 | #import "RARemoteKeyboardView.h" 2 | #import "headers.h" 3 | #import 4 | #import 5 | #import "RAMessagingServer.h" 6 | 7 | @interface RARemoteKeyboardView () { 8 | BOOL cancelFetchingContextId; 9 | } 10 | @end 11 | 12 | @implementation RARemoteKeyboardView 13 | @synthesize layerHost = _layerHost; 14 | 15 | -(void) connectToKeyboardWindowForApp:(NSString*)identifier 16 | { 17 | if (!identifier) 18 | { 19 | self.layerHost.contextId = 0; 20 | cancelFetchingContextId = YES; 21 | return; 22 | } 23 | _identifier = identifier; 24 | 25 | unsigned int value = [RAMessagingServer.sharedInstance getStoredKeyboardContextIdForApp:identifier]; 26 | self.layerHost.contextId = value; 27 | 28 | NSLog(@"[ReachApp] loaded keyboard view with %d", value); 29 | if (value == 0 && cancelFetchingContextId == NO) 30 | { 31 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 32 | [self connectToKeyboardWindowForApp:identifier]; 33 | }); 34 | } 35 | } 36 | 37 | -(id)initWithFrame:(CGRect)frame 38 | { 39 | self = [super initWithFrame:frame]; 40 | if (self) 41 | { 42 | self.userInteractionEnabled = YES; 43 | self.layerHost = [[CALayerHost alloc] init]; 44 | self.layerHost.anchorPoint = CGPointMake(0, 0); 45 | if (SYSTEM_VERSION_LESS_THAN(@"9.0")) 46 | self.layerHost.transform = CATransform3DMakeScale(1/[UIScreen mainScreen].scale, 1/[UIScreen mainScreen].scale, 1); 47 | self.layerHost.bounds = self.bounds; 48 | [self.layer addSublayer:self.layerHost]; 49 | update = NO; 50 | } 51 | 52 | return self; 53 | } 54 | 55 | -(void)dealloc 56 | { 57 | self.layerHost = nil; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /KeyboardSupport/RASpringBoardKeyboardActivation.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RARunningAppsProvider.h" 3 | 4 | @interface RASpringBoardKeyboardActivation : NSObject 5 | +(instancetype) sharedInstance; 6 | 7 | @property (nonatomic, readonly, retain) NSString *currentIdentifier; 8 | 9 | -(void) showKeyboardForAppWithIdentifier:(NSString*)identifier; 10 | -(void) hideKeyboard; 11 | 12 | -(UIWindow*) keyboardWindow; 13 | @end 14 | -------------------------------------------------------------------------------- /KeyboardSupport/RASpringBoardKeyboardActivation.xm: -------------------------------------------------------------------------------- 1 | #import "RASpringBoardKeyboardActivation.h" 2 | #import "headers.h" 3 | #import 4 | #import "RAMessaging.h" 5 | #import "RAMessagingClient.h" 6 | #import "RAKeyboardWindow.h" 7 | #import "RARemoteKeyboardView.h" 8 | 9 | extern BOOL overrideDisableForStatusBar; 10 | RAKeyboardWindow *keyboardWindow; 11 | 12 | @implementation RASpringBoardKeyboardActivation 13 | +(id) sharedInstance 14 | { 15 | SHARED_INSTANCE2(RASpringBoardKeyboardActivation, 16 | [RARunningAppsProvider.sharedInstance addTarget:self] 17 | ); 18 | } 19 | 20 | -(void) showKeyboardForAppWithIdentifier:(NSString*)identifier 21 | { 22 | if (keyboardWindow) 23 | { 24 | [self hideKeyboard]; 25 | //NSLog(@"[ReachApp] springboard cancelling - keyboardWindow exists"); 26 | //return; 27 | } 28 | 29 | NSLog(@"[ReachApp] showing kb window %@", identifier); 30 | keyboardWindow = [[RAKeyboardWindow alloc] init]; 31 | overrideDisableForStatusBar = YES; 32 | [keyboardWindow setupForKeyboardAndShow:identifier]; 33 | overrideDisableForStatusBar = NO; 34 | _currentIdentifier = identifier; 35 | } 36 | 37 | -(void) hideKeyboard 38 | { 39 | NSLog(@"[ReachApp] remove kb window (%@)", _currentIdentifier); 40 | keyboardWindow.hidden = YES; 41 | [keyboardWindow removeKeyboard]; 42 | keyboardWindow = nil; 43 | _currentIdentifier = nil; 44 | } 45 | 46 | -(void) appDidDie:(SBApplication*)app 47 | { 48 | if ([_currentIdentifier isEqual:app.bundleIdentifier]) 49 | [self hideKeyboard]; 50 | } 51 | 52 | -(UIWindow*) keyboardWindow 53 | { 54 | return keyboardWindow; 55 | } 56 | @end 57 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DEBUG = 1 2 | ARCHS = armv7 armv7s arm64 3 | CFLAGS = -I./ -Iwidgets/ -Iwidgets/Core/ -Iwidgets/Reachability/ -ISwipeOver/ -IReachability/ -IGestureSupport/ -IKeyboardSupport/ -IMissionControl/ -IWindowedMultitasking/ -INotificationCenterApp/ -IBackgrounding/ -IIntroTutorial/ -IMessaging/ -ITheming/ 4 | CFLAGS += -fobjc-arc 5 | LDFLAGS += -Wl,-segalign,4000 6 | THEOS_PACKAGE_DIR_NAME = debs 7 | TARGET = :8.0 8 | 9 | include $(THEOS)/makefiles/common.mk 10 | 11 | TWEAK_NAME = ReachApp 12 | ReachApp_FILES = Tweak.xm $(wildcard *.xm) $(wildcard *.mm) $(wildcard *.m) \ 13 | $(wildcard Reachability/*.xm) $(wildcard Reachability/*.mm) $(wildcard Reachability/*.m) \ 14 | $(wildcard widgets/*.xm) $(wildcard widgets/*.mm) $(wildcard widgets/*.m) \ 15 | $(wildcard widgets/Core/*.xm) $(wildcard widgets/Core/*.mm) $(wildcard widgets/Core/*.m) \ 16 | $(wildcard widgets/Reachability/*.xm) $(wildcard widgets/Reachability/*.mm) $(wildcard widgets/Reachability/*.m) \ 17 | $(wildcard KeyboardSupport/*.xm) $(wildcard KeyboardSupport/*.mm) $(wildcard KeyboardSupport/*.m) \ 18 | $(wildcard GestureSupport/*.xm) $(wildcard GestureSupport/*.mm) $(wildcard GestureSupport/*.m) \ 19 | $(wildcard WindowedMultitasking/*.xm) $(wildcard WindowedMultitasking/*.mm) $(wildcard WindowedMultitasking/*.m) \ 20 | $(wildcard NotificationCenterApp/*.xm) $(wildcard NotificationCenterApp/*.mm) $(wildcard NotificationCenterApp/*.m) \ 21 | $(wildcard IntroTutorial/*.xm) $(wildcard IntroTutorial/*.mm) $(wildcard IntroTutorial/*.m) \ 22 | $(wildcard Messaging/*.xm) $(wildcard Messaging/*.mm) $(wildcard Messaging/*.m) \ 23 | $(wildcard DRM/*.xm) $(wildcard DRM/*.mm) $(wildcard DRM/*.m) \ 24 | $(wildcard Theming/*.xm) $(wildcard Theming/*.mm) $(wildcard Theming/*.m) \ 25 | $(wildcard Debugging/*.xm) $(wildcard Debugging/*.mm) $(wildcard Debugging/*.m) 26 | 27 | ReachApp_FRAMEWORKS = UIKit QuartzCore CoreGraphics CoreImage 28 | ReachApp_PRIVATE_FRAMEWORKS = GraphicsServices BackBoardServices AppSupport IOKit 29 | ReachApp_LIBRARIES = applist 30 | 31 | include $(THEOS_MAKE_PATH)/tweak.mk 32 | 33 | after-install:: 34 | # install.exec "killall -9 SpringBoard" 35 | # install.exec "killall -9 Preferences" 36 | install.exec "killall -9 backboardd" 37 | 38 | 39 | SUBPROJECTS += Backgrounding 40 | SUBPROJECTS += MissionControl 41 | SUBPROJECTS += SwipeOver 42 | 43 | SUBPROJECTS += reachappfakephonemode 44 | 45 | SUBPROJECTS += reachappassertiondhooks 46 | SUBPROJECTS += reachappbackboarddhooks 47 | 48 | SUBPROJECTS += reachappsettings 49 | SUBPROJECTS += reachappflipswitch 50 | SUBPROJECTS += reachappfsdaemon 51 | 52 | 53 | include $(THEOS_MAKE_PATH)/aggregate.mk 54 | -------------------------------------------------------------------------------- /Messaging/RAMessaging.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | enum { 4 | RAMessageTypeUpdateAppData = 0, 5 | 6 | RAMessageTypeShowKeyboard, 7 | RAMessageTypeHideKeyboard, 8 | RAMessageTypeUpdateKeyboardContextId, 9 | RAMessageTypeRetrieveKeyboardContextId, 10 | } RAMessageType; 11 | 12 | struct RAMessageAppData { 13 | BOOL shouldForceSize; 14 | // Can't use CGSize because it uses CGFloats which aren't able to be transferred between 32/64bit processes (because its float in one and something else (double? i can't remember) in the other). 15 | // Also why we can't use CGFloat here 16 | float wantedClientOriginX; 17 | float wantedClientOriginY; 18 | float wantedClientWidth; 19 | float wantedClientHeight; 20 | 21 | BOOL statusBarVisibility; 22 | BOOL shouldForceStatusBar; 23 | BOOL canHideStatusBarIfWanted; 24 | 25 | UIInterfaceOrientation forcedOrientation; 26 | BOOL shouldForceOrientation; 27 | 28 | BOOL shouldUseExternalKeyboard; 29 | BOOL isBeingHosted; 30 | // Only applies after the app has been restarted. 31 | BOOL forcePhoneMode; 32 | }; 33 | 34 | static NSString *RAMessagingUpdateAppInfoMessageName = @"updateAppInfo"; 35 | static NSString *RAMessagingShowKeyboardMessageName = @"showKeyboard"; 36 | static NSString *RAMessagingHideKeyboardMessageName = @"hideKeyboard"; 37 | static NSString *RAMessagingUpdateKeyboardContextIdMessageName = @"updateKBContextId"; 38 | static NSString *RAMessagingRetrieveKeyboardContextIdMessageName = @"getKBContextId"; 39 | static NSString *RAMessagingUpdateKeyboardSizeMessageName = @"updateKBSize"; 40 | static NSString *RAMessagingOpenURLKMessageName = @"openURL"; 41 | static NSString *RAMessagingSnapFrontMostWindowLeftMessageName = @"snapLeft"; 42 | static NSString *RAMessagingSnapFrontMostWindowRightMessageName = @"snapRight"; 43 | static NSString *RAMessagingGoToDesktopOnTheLeftMessageName = @"switchToDesktopLeft"; 44 | static NSString *RAMessagingGoToDesktopOnTheRightMessageName = @"switchToDesktopRight"; 45 | static NSString *RAMessagingAddNewDesktopMessageName = @"addNewDesktop"; 46 | static NSString *RAMessagingMaximizeAppMessageName = @"maximizeApp"; 47 | static NSString *RAMessagingCloseAppMessageName = @"closeApp"; 48 | static NSString *RAMessagingGetFrontMostAppInfoMessageName = @"frontMostApp"; 49 | static NSString *RAMessagingChangeFrontMostAppMessageName = @"yes_another_message"; 50 | static NSString *RAMessagingDetachCurrentAppMessageName = @"the_messages_never_end"; 51 | 52 | typedef void (^RAMessageCompletionCallback)(BOOL success); 53 | -------------------------------------------------------------------------------- /Messaging/RAMessagingClient.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import 3 | #import "RAMessaging.h" 4 | 5 | @interface RAMessagingClient : NSObject { 6 | CPDistributedMessagingCenter *serverCenter; 7 | } 8 | +(instancetype) sharedInstance; 9 | 10 | @property (nonatomic, readonly) RAMessageAppData currentData; 11 | @property (nonatomic) BOOL hasRecievedData; 12 | @property (nonatomic, retain) NSString *knownFrontmostApp; 13 | 14 | -(void) requestUpdateFromServer; 15 | 16 | -(void) notifyServerWithKeyboardContextId:(unsigned int)cid; 17 | -(void) notifyServerOfKeyboardSizeUpdate:(CGSize)size; 18 | -(void) notifyServerToShowKeyboard; 19 | -(void) notifyServerToHideKeyboard; 20 | -(BOOL) notifyServerToOpenURL:(NSURL*)url openInWindow:(BOOL)openWindow; 21 | -(void) notifySpringBoardOfFrontAppChangeToSelf; 22 | 23 | // Methods to ease the currentData usage 24 | -(BOOL) shouldResize; 25 | -(CGSize) resizeSize; 26 | -(BOOL) shouldHideStatusBar; 27 | -(BOOL) shouldShowStatusBar; 28 | -(UIInterfaceOrientation) forcedOrientation; 29 | -(BOOL) shouldForceOrientation; 30 | -(BOOL) shouldUseExternalKeyboard; 31 | -(BOOL) isBeingHosted; 32 | @end -------------------------------------------------------------------------------- /Messaging/RAMessagingServer.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import 3 | #import "RAMessaging.h" 4 | 5 | @interface RAMessagingServer : NSObject { 6 | CPDistributedMessagingCenter *messagingCenter; 7 | NSMutableDictionary *dataForApps; 8 | NSMutableDictionary *contextIds; 9 | NSMutableDictionary *waitingCompletions; 10 | } 11 | +(instancetype) sharedInstance; 12 | 13 | -(void) loadServer; 14 | 15 | -(RAMessageAppData) getDataForIdentifier:(NSString*)identifier; 16 | -(void) setData:(RAMessageAppData)data forIdentifier:(NSString*)identifier; 17 | -(void) sendStoredDataToApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 18 | 19 | -(void) resizeApp:(NSString*)identifier toSize:(CGSize)size completion:(RAMessageCompletionCallback)callback; 20 | -(void) moveApp:(NSString*)identifier toOrigin:(CGPoint)origin completion:(RAMessageCompletionCallback)callback; 21 | -(void) endResizingApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 22 | 23 | -(void) rotateApp:(NSString*)identifier toOrientation:(UIInterfaceOrientation)orientation completion:(RAMessageCompletionCallback)callback; 24 | -(void) unRotateApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 25 | 26 | -(void) forceStatusBarVisibility:(BOOL)visibility forApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 27 | -(void) unforceStatusBarVisibilityForApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 28 | 29 | -(void) setHosted:(BOOL)value forIdentifier:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 30 | 31 | -(void) forcePhoneMode:(BOOL)value forIdentifier:(NSString*)identifier andRelaunchApp:(BOOL)relaunch; 32 | 33 | -(unsigned int) getStoredKeyboardContextIdForApp:(NSString*)identifier; 34 | 35 | -(void) receiveShowKeyboardForAppWithIdentifier:(NSString*)identifier; 36 | -(void) receiveHideKeyboard; 37 | -(void) setShouldUseExternalKeyboard:(BOOL)value forApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 38 | @end 39 | -------------------------------------------------------------------------------- /Messaging/overview.txt: -------------------------------------------------------------------------------- 1 | The messaging system may seem complex and confusing at first. It sort of is. Below is an outline of how it works. 2 | 3 | 4 | 5 | 1. Some component in SpringBoard sends some form of an update to RAMessagingServer 6 | RAMessagingServer -> send CFNotification to app to retrieve updated info[1] 7 | | | 8 | | | 9 | | | 10 | | |-------------------> app receives CFNotification 11 | | - app send CPDistributedMessagingCenter message to sendMessageAndReceiveReplyName: 12 | | |-------> SpringBoard sends data, callback is called with a success 13 | |-----> timeout (4s) 14 | - callback, failed 15 | - notify user 16 | 17 | 18 | 19 | 20 | 21 | [1] - tries to send immediately, unless the app isn't running -------------------------------------------------------------------------------- /MissionControl/ActivatorListener.xm: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAMissionControlManager.h" 3 | #import "RASettings.h" 4 | 5 | @interface RAActivatorListener : NSObject 6 | @end 7 | 8 | static RAActivatorListener *sharedInstance; 9 | 10 | @implementation RAActivatorListener 11 | - (void)activator:(LAActivator *)activator receiveEvent:(LAEvent *)event 12 | { 13 | if ([[%c(SBLockScreenManager) sharedInstance] isUILocked]) 14 | return; 15 | else if ([[%c(RASettings) sharedInstance] missionControlEnabled]) 16 | { 17 | [RAMissionControlManager.sharedInstance toggleMissionControl:YES]; 18 | [[[%c(SBUIController) sharedInstance] _appSwitcherController] forceDismissAnimated:NO]; 19 | } 20 | [event setHandled:YES]; 21 | } 22 | @end 23 | 24 | %ctor 25 | { 26 | if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.springboard"]) 27 | { 28 | sharedInstance = [[RAActivatorListener alloc] init]; 29 | [[%c(LAActivator) sharedInstance] registerListener:sharedInstance forName:@"com.efrederickson.reachapp.missioncontrol.activatorlistener"]; 30 | } 31 | } -------------------------------------------------------------------------------- /MissionControl/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | 3 | CFLAGS = -I../ -I../Theming/ -I../GestureSupport/ -I../WindowedMultitasking/ 4 | CFLAGS += -fobjc-arc 5 | LDFLAGS += -Wl,-segalign,4000 6 | 7 | include $(THEOS)/makefiles/common.mk 8 | 9 | TWEAK_NAME = ReachAppMissionControl 10 | ReachAppMissionControl_FILES = $(wildcard *.xm) $(wildcard *.mm) $(wildcard *.m) 11 | ReachAppMissionControl_FRAMEWORKS = UIKit CoreGraphics 12 | 13 | include $(THEOS_MAKE_PATH)/tweak.mk 14 | 15 | after-install:: 16 | install.exec "killall -9 SpringBoard" 17 | -------------------------------------------------------------------------------- /MissionControl/RAMissionControlManager.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAMissionControlWindow.h" 3 | #import "RAGestureManager.h" 4 | 5 | @interface RAMissionControlManager : NSObject { 6 | RAMissionControlWindow *window; 7 | } 8 | +(instancetype) sharedInstance; 9 | 10 | @property (nonatomic, readonly) BOOL isShowingMissionControl; 11 | @property (nonatomic) BOOL inhibitDismissalGesture; 12 | 13 | -(void) createWindow; 14 | -(void) showMissionControl:(BOOL)animated; 15 | -(void) hideMissionControl:(BOOL)animated; 16 | -(void) toggleMissionControl:(BOOL)animated; 17 | 18 | -(RAMissionControlWindow*) missionControlWindow; 19 | @end -------------------------------------------------------------------------------- /MissionControl/RAMissionControlPreviewView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAMissionControlPreviewView : UIImageView { 4 | SBIcon *icon; 5 | SBIconView *iconView; 6 | } 7 | @property (nonatomic, retain) SBApplication *application; 8 | 9 | -(void) generatePreview; 10 | -(void) generatePreviewAsync; 11 | -(void) generateDesktopPreviewAsync:(id)desktop completion:(dispatch_block_t)completionBlock; 12 | @end -------------------------------------------------------------------------------- /MissionControl/RAMissionControlWindow.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RARunningAppsProvider.h" 3 | 4 | @class RAMissionControlManager; 5 | 6 | @interface RAMissionControlWindow : UIAutoRotatingWindow 7 | @property (nonatomic, weak) RAMissionControlManager *manager; 8 | 9 | -(void) reloadDesktopSection; 10 | -(void) reloadWindowedAppsSection; 11 | -(void) reloadWindowedAppsSection:(NSArray*)runningApplications; 12 | -(void) reloadOtherAppsSection; 13 | @end -------------------------------------------------------------------------------- /MissionControl/ReachAppMissionControl.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.springboard" ); }; } 2 | -------------------------------------------------------------------------------- /Multiplexer.h: -------------------------------------------------------------------------------- 1 | @class SBApplication; 2 | 3 | @interface MultiplexerExtension : NSObject 4 | @property (nonatomic, retain) NSString *name; 5 | @property (nonatomic, retain) NSString *multiplexerVersion; 6 | @end 7 | 8 | @interface Multiplexer : NSObject { 9 | NSMutableArray *activeExtensions; 10 | } 11 | +(instancetype) sharedInstance; 12 | 13 | -(NSString*) currentVersion; 14 | -(BOOL) isOnSupportedOS; 15 | 16 | -(void) registerExtension:(NSString*)name forMultiplexerVersion:(NSString*)version; 17 | 18 | +(id) createSBAppToAppWorkspaceTransactionForExitingApp:(SBApplication*)app; 19 | +(BOOL) shouldShowControlCenterGrabberOnFirstSwipe; 20 | @end 21 | -------------------------------------------------------------------------------- /NotificationCenterApp/RANCViewController.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @class RAHostedAppView; 4 | 5 | @interface SBNCColumnViewController : UIViewController 6 | @end 7 | 8 | @interface RANCViewController : SBNCColumnViewController 9 | +(instancetype) sharedViewController; 10 | 11 | -(RAHostedAppView*) hostedApp; 12 | -(void) forceReloadAppLikelyBecauseTheSettingChanged; 13 | @end -------------------------------------------------------------------------------- /PDFImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // This is free and unencumbered software released into the public domain. 3 | // 4 | // Anyone is free to copy, modify, publish, use, compile, sell, or 5 | // distribute this software, either in source code form or as a compiled 6 | // binary, for any purpose, commercial or non-commercial, and by any 7 | // means. 8 | // 9 | // In jurisdictions that recognize copyright laws, the author or authors 10 | // of this software dedicate any and all copyright interest in the 11 | // software to the public domain. We make this dedication for the benefit 12 | // of the public at large and to the detriment of our heirs and 13 | // successors. We intend this dedication to be an overt act of 14 | // relinquishment in perpetuity of all present and future rights to this 15 | // software under copyright law. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | // 25 | // For more information, please refer to 26 | // 27 | 28 | // Available from GitHub 29 | // https://github.com/tparry/PDFImage.framework 30 | 31 | #import 32 | 33 | #import "PDFImageOptions.h" 34 | 35 | // PDFImage is thread-safe, 36 | // however note that opening the same bundled file on 37 | // two different threads within a short time of each other (microseconds) 38 | // may result in a new instance and not the version in NSCache, the same applies to imageWithOptions: 39 | @interface RAPDFImage : NSObject 40 | 41 | @property (nonatomic, readonly) CGSize size; // original page size 42 | 43 | + (instancetype)imageNamed:(NSString *)name; // from the main bundle, the .pdf extension can be omitted, 44 | // this and +imageNamed:inBundle: are the only methods that will NSCache PDFImages, as bundles are read-only 45 | 46 | + (instancetype)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle; 47 | 48 | + (instancetype)imageWithContentsOfFile:(NSString *)path; 49 | + (instancetype)imageWithData:(NSData *)data; 50 | 51 | - (instancetype)initWithContentsOfFile:(NSString *)path; 52 | - (instancetype)initWithData:(NSData *)data; 53 | 54 | - (instancetype)initWithDocument:(CGPDFDocumentRef)document; 55 | 56 | - (UIImage *)imageWithOptions:(RAPDFImageOptions *)options; // will NSCache the image if the same options are used again 57 | - (void)drawInRect:(CGRect)rect; 58 | 59 | @end -------------------------------------------------------------------------------- /PDFImageOptions.h: -------------------------------------------------------------------------------- 1 | // 2 | // This is free and unencumbered software released into the public domain. 3 | // 4 | // Anyone is free to copy, modify, publish, use, compile, sell, or 5 | // distribute this software, either in source code form or as a compiled 6 | // binary, for any purpose, commercial or non-commercial, and by any 7 | // means. 8 | // 9 | // In jurisdictions that recognize copyright laws, the author or authors 10 | // of this software dedicate any and all copyright interest in the 11 | // software to the public domain. We make this dedication for the benefit 12 | // of the public at large and to the detriment of our heirs and 13 | // successors. We intend this dedication to be an overt act of 14 | // relinquishment in perpetuity of all present and future rights to this 15 | // software under copyright law. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | // 25 | // For more information, please refer to 26 | // 27 | 28 | #import 29 | 30 | @interface RAPDFImageOptions : NSObject 31 | 32 | @property (nonatomic, assign) CGFloat scale; // screen scale, defaults to 0, the current screen scale 33 | @property (nonatomic, copy) UIColor *tintColor; // solid color of the image, defaults to nil, original color 34 | @property (nonatomic, assign) CGSize size; // size of the image 35 | @property (nonatomic, assign) UIViewContentMode contentMode; // defaults to UIViewContentModeScaleToFill 36 | 37 | // Convience method for simply spitting out a sized version 38 | + (instancetype)optionsWithSize:(CGSize)size; 39 | 40 | - (CGRect)contentBoundsForContentSize:(CGSize)contentSize; 41 | 42 | // Proportionally scaled up or down by a whole number to fit the contentSize in the self.size 43 | - (CGSize)wholeProportionalFitForContentSize:(CGSize)contentSize; 44 | 45 | @end -------------------------------------------------------------------------------- /RAAppKiller.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RARunningAppsProvider.h" 3 | 4 | @interface RAAppKiller : NSObject 5 | +(void) killAppWithIdentifier:(NSString*)identifier; 6 | +(void) killAppWithIdentifier:(NSString*)identifier completion:(void(^)())handler; 7 | +(void) killAppWithSBApplication:(SBApplication*)app; 8 | +(void) killAppWithSBApplication:(SBApplication*)app completion:(void(^)())handler; 9 | @end 10 | 11 | -------------------------------------------------------------------------------- /RAAppSelectorView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @class RAAppSelectorView; 4 | 5 | @protocol RAAppSelectorViewDelegate 6 | -(void) appSelector:(RAAppSelectorView*)view appWasSelected:(NSString*)bundleIdentifier; 7 | @end 8 | 9 | @interface RAAppSelectorView : UIScrollView 10 | @property (nonatomic, weak) NSObject *target; 11 | 12 | -(void) relayoutApps; 13 | @end -------------------------------------------------------------------------------- /RAAppSliderProvider.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @class RAHostedAppView; 4 | 5 | @interface RAAppSliderProvider : NSObject 6 | @property (nonatomic, retain) NSArray *availableIdentifiers; 7 | @property (nonatomic) NSInteger currentIndex; 8 | 9 | -(BOOL) canGoLeft; 10 | -(BOOL) canGoRight; 11 | 12 | -(RAHostedAppView*) viewToTheLeft; 13 | -(RAHostedAppView*) viewToTheRight; 14 | -(RAHostedAppView*) viewAtCurrentIndex; 15 | 16 | -(void) goToTheLeft; 17 | -(void) goToTheRight; 18 | @end 19 | -------------------------------------------------------------------------------- /RAAppSliderProvider.mm: -------------------------------------------------------------------------------- 1 | #import "RAAppSliderProvider.h" 2 | #import "RAHostedAppView.h" 3 | 4 | @interface RAAppSliderProvider () { 5 | NSMutableDictionary *cachedViews; 6 | } 7 | @end 8 | 9 | @implementation RAAppSliderProvider 10 | @synthesize currentIndex, availableIdentifiers; 11 | 12 | -(id) init 13 | { 14 | if (self = [super init]) 15 | { 16 | cachedViews = [NSMutableDictionary dictionary]; 17 | } 18 | return self; 19 | } 20 | 21 | -(BOOL) canGoLeft 22 | { 23 | return currentIndex - 1 >= 0 && availableIdentifiers.count > 0; 24 | } 25 | 26 | -(BOOL) canGoRight 27 | { 28 | return availableIdentifiers.count > currentIndex + 1; 29 | } 30 | 31 | -(RAHostedAppView*) viewToTheLeft 32 | { 33 | if (self.canGoLeft) 34 | { 35 | NSString *ident = [availableIdentifiers objectAtIndex:currentIndex - 1]; 36 | 37 | if (!ident) return nil; 38 | if ([cachedViews objectForKey:ident]) return cachedViews[ident]; 39 | 40 | RAHostedAppView *view = [[RAHostedAppView alloc] initWithBundleIdentifier:ident]; 41 | [view preloadApp]; 42 | cachedViews[ident] = view; 43 | return view; 44 | } 45 | return nil; 46 | } 47 | 48 | -(RAHostedAppView*) viewToTheRight 49 | { 50 | if (self.canGoRight) 51 | { 52 | NSString *ident = [availableIdentifiers objectAtIndex:currentIndex + 1]; 53 | 54 | if (!ident) return nil; 55 | if ([cachedViews objectForKey:ident]) return cachedViews[ident]; 56 | 57 | RAHostedAppView *view = [[RAHostedAppView alloc] initWithBundleIdentifier:ident]; 58 | [view preloadApp]; 59 | cachedViews[ident] = view; 60 | return view; 61 | } 62 | return nil; 63 | } 64 | 65 | -(RAHostedAppView*) viewAtCurrentIndex 66 | { 67 | NSString *ident = [availableIdentifiers objectAtIndex:currentIndex]; 68 | 69 | if (!ident) return nil; 70 | if ([cachedViews objectForKey:ident]) return cachedViews[ident]; 71 | 72 | RAHostedAppView *view = [[RAHostedAppView alloc] initWithBundleIdentifier:ident]; 73 | [view preloadApp]; 74 | cachedViews[ident] = view; 75 | return view; 76 | } 77 | 78 | -(void) goToTheLeft 79 | { 80 | if (self.canGoLeft) 81 | currentIndex--; 82 | } 83 | 84 | -(void) goToTheRight 85 | { 86 | if (self.canGoRight) 87 | currentIndex++; 88 | } 89 | @end 90 | -------------------------------------------------------------------------------- /RAAppSliderProviderView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAHostedAppView.h" 3 | #import "RAGestureManager.h" 4 | 5 | @class RAAppSliderProvider; 6 | 7 | @interface RAAppSliderProviderView : UIView { 8 | RAHostedAppView *currentView; 9 | } 10 | @property (nonatomic, retain) RAAppSliderProvider *swipeProvider; 11 | @property (nonatomic) BOOL isSwipeable; 12 | 13 | -(CGRect) clientFrame; 14 | -(NSString*) currentBundleIdentifier; 15 | 16 | -(void) goToTheLeft; 17 | -(void) goToTheRight; 18 | 19 | -(void) load; 20 | -(void) unload; 21 | -(void) updateCurrentView; 22 | @end -------------------------------------------------------------------------------- /RAAppSwitcherModelWrapper.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAAppSwitcherModelWrapper : NSObject 4 | +(void) addToFront:(SBApplication*)app; 5 | +(void) addIdentifierToFront:(NSString*)ident; 6 | +(NSArray*) appSwitcherAppIdentiferList; 7 | 8 | +(void) removeItemWithIdentifier:(NSString*)ident; 9 | @end -------------------------------------------------------------------------------- /RAAppSwitcherModelWrapper.xm: -------------------------------------------------------------------------------- 1 | #import "RAAppSwitcherModelWrapper.h" 2 | 3 | @implementation RAAppSwitcherModelWrapper 4 | +(void) addToFront:(SBApplication*)app 5 | { 6 | SBAppSwitcherModel *model = [%c(SBAppSwitcherModel) sharedInstance]; 7 | if ([model respondsToSelector:@selector(addToFront:)]) // iOS 7 + 8 8 | { 9 | SBDisplayLayout *layout = [%c(SBDisplayLayout) fullScreenDisplayLayoutForApplication:app]; 10 | [model addToFront:layout]; 11 | } 12 | else // iOS 9 13 | { 14 | SBDisplayItem *layout = [%c(SBDisplayItem) displayItemWithType:@"App" displayIdentifier:app.bundleIdentifier]; 15 | [model addToFront:layout role:2]; 16 | } 17 | 18 | } 19 | 20 | +(void) addIdentifierToFront:(NSString*)ident 21 | { 22 | [RAAppSwitcherModelWrapper addToFront:[[%c(SBApplicationController) sharedInstance] RA_applicationWithBundleIdentifier:ident]]; 23 | } 24 | 25 | +(NSArray*) appSwitcherAppIdentiferList 26 | { 27 | SBAppSwitcherModel *model = [%c(SBAppSwitcherModel) sharedInstance]; 28 | 29 | if ([model respondsToSelector:@selector(snapshotOfFlattenedArrayOfAppIdentifiersWhichIsOnlyTemporary)]) 30 | return [model snapshotOfFlattenedArrayOfAppIdentifiersWhichIsOnlyTemporary]; 31 | 32 | // iOS 9 most likely. 33 | 34 | NSMutableArray *ret = [NSMutableArray array]; 35 | 36 | id list = [model mainSwitcherDisplayItems]; // NSArray 37 | for (SBDisplayItem *item in list) 38 | { 39 | [ret addObject:item.displayIdentifier]; 40 | } 41 | 42 | return ret; 43 | } 44 | 45 | +(void) removeItemWithIdentifier:(NSString*)ident 46 | { 47 | SBDisplayItem *item = [%c(SBDisplayItem) displayItemWithType:@"App" displayIdentifier:ident]; 48 | id appSwitcherModel = [%c(SBAppSwitcherModel) sharedInstance]; 49 | if ([appSwitcherModel respondsToSelector:@selector(removeDisplayItem:)]) 50 | [[%c(SBAppSwitcherModel) sharedInstance] removeDisplayItem:item]; 51 | else 52 | [[%c(SBAppSwitcherModel) sharedInstance] remove:item]; 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /RACompatibilitySystem.h: -------------------------------------------------------------------------------- 1 | @interface RACompatibilitySystem : NSObject { 2 | 3 | } 4 | //+(instancetype) sharedInstance; 5 | 6 | +(void) showWarning:(NSString*)info; 7 | +(void) showError:(NSString*)info; 8 | @end -------------------------------------------------------------------------------- /RACompatibilitySystem.mm: -------------------------------------------------------------------------------- 1 | #import "RACompatibilitySystem.h" 2 | #include 3 | #include 4 | #import 5 | #import "headers.h" 6 | 7 | @implementation RACompatibilitySystem 8 | +(NSString*) aggregateSystemInfo 9 | { 10 | NSMutableString *ret = [[NSMutableString alloc] init]; 11 | 12 | struct utsname systemInfo; 13 | uname(&systemInfo); 14 | NSString *sysInfo = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; 15 | 16 | [ret appendString:[NSString stringWithFormat:@"%@, %@ %@\n", sysInfo, UIDevice.currentDevice.systemName, UIDevice.currentDevice.systemVersion]]; 17 | 18 | return ret; 19 | } 20 | 21 | +(void) showWarning:(NSString*)info 22 | { 23 | NSString *message = [NSString stringWithFormat:@"System info: %@\n\nWARNING: POTENTIAL INCOMPATIBILITY DETECTED\n%@", [self aggregateSystemInfo], info]; 24 | 25 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Multiplexer Compatibility" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 26 | [alert show]; 27 | } 28 | 29 | +(void) showError:(NSString*)info 30 | { 31 | NSString *message = [NSString stringWithFormat:@"System info: %@\n\n***ERROR***: POTENTIAL INCOMPATIBILITY DETECTED\n%@", [self aggregateSystemInfo], info]; 32 | 33 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Multiplexer Compatibility" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 34 | [alert show]; 35 | } 36 | @end -------------------------------------------------------------------------------- /RAControlCenterInhibitor.h: -------------------------------------------------------------------------------- 1 | @interface RAControlCenterInhibitor : NSObject 2 | +(void) setInhibited:(BOOL)value; 3 | +(BOOL) isInhibited; 4 | @end -------------------------------------------------------------------------------- /RAControlCenterInhibitor.xm: -------------------------------------------------------------------------------- 1 | #import "RAControlCenterInhibitor.h" 2 | #import 3 | 4 | BOOL overrideCC = NO; 5 | 6 | @implementation RAControlCenterInhibitor : NSObject 7 | +(void) setInhibited:(BOOL)value 8 | { 9 | overrideCC = value; 10 | } 11 | 12 | +(BOOL) isInhibited 13 | { 14 | return overrideCC; 15 | } 16 | @end 17 | 18 | %hook SBUIController 19 | - (void)_showControlCenterGestureBeganWithLocation:(CGPoint)arg1 20 | { 21 | if (!overrideCC) 22 | %orig; 23 | } 24 | 25 | - (void)handleShowControlCenterSystemGesture:(__unsafe_unretained id)arg1 26 | { 27 | if (!overrideCC) 28 | %orig; 29 | } 30 | %end 31 | -------------------------------------------------------------------------------- /RAFakePhoneMode.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAFakePhoneMode : NSObject 4 | +(CGSize) fakedSize; 5 | +(BOOL) shouldFakeForThisProcess; 6 | +(void) updateAppSizing; 7 | 8 | +(BOOL) shouldFakeForAppWithIdentifier:(NSString*)identifier; 9 | +(CGSize) fakeSizeForAppWithIdentifier:(NSString*)identifier; 10 | @end -------------------------------------------------------------------------------- /RAHostManager.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAHostManager : NSObject 4 | +(UIView*) systemHostViewForApplication:(SBApplication*)app; 5 | +(UIView*) enabledHostViewForApplication:(SBApplication*)app; 6 | +(NSObject*) hostManagerForApp:(SBApplication*)app; 7 | @end -------------------------------------------------------------------------------- /RAHostManager.xm: -------------------------------------------------------------------------------- 1 | #import "RAHostManager.h" 2 | #import "RACompatibilitySystem.h" 3 | 4 | @implementation RAHostManager 5 | +(UIView*) systemHostViewForApplication:(SBApplication*)app 6 | { 7 | if (!app) 8 | return nil; 9 | if ([app respondsToSelector:@selector(mainScene)]) // iOS 8 10 | return MSHookIvar(app.mainScene.contextHostManager, "_hostView"); 11 | else if ([app respondsToSelector:@selector(mainScreenContextHostManager)]) 12 | return MSHookIvar([app mainScreenContextHostManager], "_hostView"); 13 | 14 | [RACompatibilitySystem showWarning:@"Unable to find valid method for accessing system context host views"]; 15 | return nil; 16 | } 17 | 18 | +(UIView*) enabledHostViewForApplication:(SBApplication*)app 19 | { 20 | if (!app) 21 | return nil; 22 | 23 | if ([app respondsToSelector:@selector(mainScene)]) 24 | { 25 | FBScene *scene = [app mainScene]; 26 | FBWindowContextHostManager *contextHostManager = [scene contextHostManager]; 27 | 28 | FBSMutableSceneSettings *settings = [[scene mutableSettings] mutableCopy]; 29 | if (!settings) 30 | return nil; 31 | 32 | SET_BACKGROUNDED(settings, NO); 33 | [scene _applyMutableSettings:settings withTransitionContext:nil completion:nil]; 34 | 35 | [contextHostManager enableHostingForRequester:@"reachapp" orderFront:YES]; 36 | return [contextHostManager hostViewForRequester:@"reachapp" enableAndOrderFront:YES]; 37 | } 38 | 39 | [RACompatibilitySystem showWarning:@"Unable to find valid method for accessing context host views"]; 40 | return nil; 41 | } 42 | 43 | +(NSObject*) hostManagerForApp:(SBApplication*)app 44 | { 45 | if (!app) 46 | return nil; 47 | 48 | if ([app respondsToSelector:@selector(mainScene)]) 49 | { 50 | FBScene *scene = [app mainScene]; 51 | return (NSObject*)[scene contextHostManager]; 52 | } 53 | 54 | [RACompatibilitySystem showWarning:@"Unable to find valid method for accessing context host view managers"]; 55 | return nil; 56 | } 57 | @end -------------------------------------------------------------------------------- /RAHostedAppView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RARunningAppsProvider.h" 3 | 4 | @class RAAppSliderProvider; 5 | 6 | @interface RAHostedAppView : UIView { 7 | SBApplication *app; 8 | FBWindowContextHostWrapperView *view; 9 | } 10 | 11 | +(void) iPad_iOS83_fixHosting; 12 | 13 | -(id) initWithBundleIdentifier:(NSString*)bundleIdentifier; 14 | 15 | @property (nonatomic) BOOL showSplashscreenInsteadOfSpinner; 16 | @property (nonatomic) BOOL renderWallpaper; 17 | 18 | @property (nonatomic, retain) NSString *bundleIdentifier; 19 | @property (nonatomic) BOOL autosizesApp; 20 | 21 | @property (nonatomic) BOOL allowHidingStatusBar; 22 | @property (nonatomic) BOOL hideStatusBar; 23 | 24 | @property (nonatomic) BOOL shouldUseExternalKeyboard; 25 | 26 | @property (nonatomic) BOOL isCurrentlyHosting; 27 | 28 | -(SBApplication*) app; 29 | -(NSString*) displayName; 30 | 31 | @property (nonatomic, readonly) UIInterfaceOrientation orientation; 32 | -(void) rotateToOrientation:(UIInterfaceOrientation)o; 33 | 34 | -(void) preloadApp; 35 | -(void) loadApp; 36 | -(void) unloadApp; 37 | -(void) unloadApp:(BOOL)forceImmediate; 38 | 39 | @end -------------------------------------------------------------------------------- /RAHostedWidgetView.h: -------------------------------------------------------------------------------- 1 | #import "RAHostedAppView.h" 2 | 3 | // defunct. 4 | // TODO: implement. 5 | // Why hasn't it already been implemented? No need to so far. 6 | 7 | @interface RAHostedWidgetView : RAHostedAppView 8 | 9 | @end -------------------------------------------------------------------------------- /RAHostedWidgetView.xm: -------------------------------------------------------------------------------- 1 | #import "RAHostedWidgetView.h" 2 | #import "RAWidgetBase.h" 3 | #import "RAWidgetHostManager.h" 4 | 5 | @interface RAHostedWidgetView () { 6 | RAWidgetBase *widget; 7 | } 8 | @end 9 | 10 | @implementation RAHostedWidgetView 11 | -(SBApplication*) app { return nil; } 12 | -(NSString*) displayName { return [self loadWidget].displayName; } 13 | 14 | //-(void) rotateToOrientation:(UIInterfaceOrientation)o; 15 | 16 | -(RAWidgetBase*) loadWidget 17 | { 18 | widget = [RAWidgetHostManager.sharedInstance widgetForIdentifier:self.bundleIdentifier]; 19 | return widget; 20 | } 21 | 22 | -(void) preloadApp 23 | { 24 | [self loadWidget]; 25 | } 26 | 27 | -(void) loadApp 28 | { 29 | widget.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); 30 | [self addSubview:widget]; 31 | [widget didAppear]; 32 | } 33 | 34 | -(void) unloadApp 35 | { 36 | [widget didDisappear]; 37 | [widget removeFromSuperview]; 38 | } 39 | @end -------------------------------------------------------------------------------- /RAInsetLabel.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAInsetLabel : UILabel 4 | @property (nonatomic) UIEdgeInsets textInset; 5 | @end 6 | -------------------------------------------------------------------------------- /RAInsetLabel.mm: -------------------------------------------------------------------------------- 1 | #import "RAInsetLabel.h" 2 | 3 | @implementation RAInsetLabel 4 | - (void)drawTextInRect:(CGRect)rect 5 | { 6 | [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.textInset)]; 7 | } 8 | @end -------------------------------------------------------------------------------- /RALocalizer.h: -------------------------------------------------------------------------------- 1 | @interface RALocalizer : NSObject { 2 | NSDictionary *translation; 3 | } 4 | +(id) sharedInstance; 5 | 6 | -(NSString*) localizedStringForKey:(NSString*)key; 7 | @end -------------------------------------------------------------------------------- /RALocalizer.mm: -------------------------------------------------------------------------------- 1 | #import "RALocalizer.h" 2 | #import "headers.h" 3 | 4 | @implementation RALocalizer 5 | +(id) sharedInstance 6 | { 7 | SHARED_INSTANCE2(RALocalizer, [sharedInstance loadTranslation]); 8 | } 9 | 10 | -(BOOL) attemptLoadForLanguageCode:(NSString*)code 11 | { 12 | NSString *expandedPath = [NSString stringWithFormat:@"%@/Localizations/%@.strings",RA_BASE_PATH,code]; 13 | NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:expandedPath]; 14 | if (plist) 15 | { 16 | translation = plist; 17 | return YES; 18 | } 19 | return NO; 20 | } 21 | 22 | -(void) loadTranslation 23 | { 24 | NSArray *langs = [NSLocale preferredLanguages]; 25 | 26 | for (NSString *lang in langs) 27 | { 28 | if ([self attemptLoadForLanguageCode:lang]) 29 | break; 30 | } 31 | if (!translation) 32 | [self attemptLoadForLanguageCode:@"en"]; 33 | } 34 | 35 | -(NSString*) localizedStringForKey:(NSString*)key 36 | { 37 | return [translation objectForKey:key] ? translation[key] : key; 38 | } 39 | @end -------------------------------------------------------------------------------- /RAOrientationLocker.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAOrientationLocker : NSObject 4 | +(void) lockOrientation; 5 | +(void) unlockOrientation; 6 | @end -------------------------------------------------------------------------------- /RAOrientationLocker.xm: -------------------------------------------------------------------------------- 1 | #import "RAOrientationLocker.h" 2 | 3 | @implementation RAOrientationLocker 4 | +(void) lockOrientation 5 | { 6 | if ([%c(SBUIController) instancesRespondToSelector:@selector(_lockOrientationForSwitcher)]) 7 | [[%c(SBUIController) sharedInstance] _lockOrientationForSwitcher]; // iOS 8 8 | else // iOS 9 9 | [[%c(SBMainSwitcherGestureCoordinator) sharedInstance] _lockOrientation]; 10 | } 11 | 12 | +(void) unlockOrientation 13 | { 14 | if ([%c(SBUIController) instancesRespondToSelector:@selector(releaseSwitcherOrientationLock)]) 15 | [[%c(SBUIController) sharedInstance] releaseSwitcherOrientationLock]; // iOS 8 16 | else // iOS 9 17 | [[%c(SBMainSwitcherGestureCoordinator) sharedInstance] _releaseOrientationLock]; 18 | } 19 | @end -------------------------------------------------------------------------------- /RAResourceImageProvider.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAResourceImageProvider : NSObject 4 | +(UIImage*) imageForFilename:(NSString*)filename; 5 | +(UIImage*) imageForFilename:(NSString*)filename size:(CGSize)size tintedTo:(UIColor*)tint; 6 | +(UIImage*) imageForFilename:(NSString*)filename constrainedToSize:(CGSize)size; 7 | @end -------------------------------------------------------------------------------- /RARunningAppsProvider.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @protocol RARunningAppsProviderDelegate 4 | @optional 5 | -(void) appDidStart:(__unsafe_unretained SBApplication*)app; 6 | -(void) appDidDie:(__unsafe_unretained SBApplication*)app; 7 | @end 8 | 9 | @interface RARunningAppsProvider : NSObject { 10 | NSMutableArray *apps; 11 | NSMutableArray *targets; 12 | NSLock *lock; 13 | } 14 | +(instancetype) sharedInstance; 15 | 16 | -(void) addRunningApp:(__unsafe_unretained SBApplication*)app; 17 | -(void) removeRunningApp:(__unsafe_unretained SBApplication*)app; 18 | 19 | -(void) addTarget:(__weak NSObject*)target; 20 | -(void) removeTarget:(__weak NSObject*)target; 21 | 22 | -(NSArray*) runningApplications; 23 | @end -------------------------------------------------------------------------------- /RARunningAppsProvider.xm: -------------------------------------------------------------------------------- 1 | #import "RARunningAppsProvider.h" 2 | 3 | @implementation RARunningAppsProvider 4 | +(instancetype) sharedInstance 5 | { 6 | SHARED_INSTANCE2(RARunningAppsProvider, 7 | sharedInstance->apps = [NSMutableArray array]; 8 | sharedInstance->targets = [NSMutableArray array]; 9 | sharedInstance->lock = [[NSLock alloc] init]; 10 | ); 11 | } 12 | 13 | -(void) addRunningApp:(__unsafe_unretained SBApplication*)app 14 | { 15 | [lock lock]; 16 | 17 | [apps addObject:app]; 18 | for (NSObject* target in targets) 19 | if ([target respondsToSelector:@selector(appDidStart:)]) 20 | dispatch_async(dispatch_get_main_queue(), ^{ 21 | [target appDidStart:app]; 22 | }); 23 | 24 | [lock unlock]; 25 | } 26 | 27 | -(void) removeRunningApp:(__unsafe_unretained SBApplication*)app 28 | { 29 | [lock lock]; 30 | 31 | [apps removeObject:app]; 32 | 33 | for (NSObject* target in targets) 34 | if ([target respondsToSelector:@selector(appDidDie:)]) 35 | dispatch_async(dispatch_get_main_queue(), ^{ 36 | [target appDidDie:app]; 37 | }); 38 | 39 | [lock unlock]; 40 | } 41 | 42 | -(void) addTarget:(__weak NSObject*)target 43 | { 44 | [lock lock]; 45 | 46 | if ([targets containsObject:target] == NO) 47 | [targets addObject:target]; 48 | 49 | [lock unlock]; 50 | } 51 | 52 | -(void) removeTarget:(__weak NSObject*)target 53 | { 54 | [lock lock]; 55 | 56 | [targets removeObject:target]; 57 | 58 | [lock unlock]; 59 | } 60 | 61 | -(NSArray*) runningApplications { return apps; } 62 | -(NSMutableArray*) mutableRunningApplications { return apps; } 63 | @end 64 | 65 | %hook SBApplication 66 | - (void)updateProcessState:(unsafe_id)arg1 67 | { 68 | %orig; 69 | 70 | if (self.isRunning && [RARunningAppsProvider.sharedInstance.mutableRunningApplications containsObject:self] == NO) 71 | [RARunningAppsProvider.sharedInstance addRunningApp:self]; 72 | else if (!self.isRunning && [RARunningAppsProvider.sharedInstance.mutableRunningApplications containsObject:self]) 73 | [RARunningAppsProvider.sharedInstance removeRunningApp:self]; 74 | } 75 | %end -------------------------------------------------------------------------------- /RASBWorkspaceFetcher.h: -------------------------------------------------------------------------------- 1 | @class SBWorkspace; 2 | 3 | @interface RASBWorkspaceFetcher : NSObject 4 | +(Class) SBWorkspaceClass; 5 | +(SBWorkspace*) getCurrentSBWorkspaceImplementationInstanceForThisOS; 6 | @end -------------------------------------------------------------------------------- /RASBWorkspaceFetcher.xm: -------------------------------------------------------------------------------- 1 | #import "RASBWorkspaceFetcher.h" 2 | #import 3 | 4 | // IMPORTANT: DO NOT IMPORT HEADERS.H 5 | // REASON: HEADERS.H IMPORTS THIS FILE 6 | 7 | @interface __SBWorkspace__class_impl_dummy : NSObject 8 | +(id) sharedInstance; 9 | @end 10 | 11 | Class SBWorkspace_class_implementation_class = nil; 12 | 13 | @implementation RASBWorkspaceFetcher 14 | +(Class) SBWorkspaceClass 15 | { 16 | return SBWorkspace_class_implementation_class; 17 | } 18 | 19 | +(SBWorkspace*) getCurrentSBWorkspaceImplementationInstanceForThisOS 20 | { 21 | if ([SBWorkspace_class_implementation_class respondsToSelector:@selector(sharedInstance)]) 22 | return [SBWorkspace_class_implementation_class sharedInstance]; 23 | NSLog(@"[ReachApp] \"SBWorkspace\" class '%s' does not have '+sharedInstance' method", class_getName(SBWorkspace_class_implementation_class)); 24 | return nil; 25 | } 26 | @end 27 | 28 | %ctor 29 | { 30 | // SBMainWorkspace: iOS 9 31 | // SBWorkspace: iOS 8 32 | SBWorkspace_class_implementation_class = objc_getClass("SBMainWorkspace") ?: objc_getClass("SBWorkspace"); 33 | } -------------------------------------------------------------------------------- /RASettings.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | enum RAGrabArea { 4 | RAGrabAreaBottomLeftThird = 1, 5 | RAGrabAreaBottomMiddleThird = 2, 6 | RAGrabAreaBottomRightThird = 3, 7 | 8 | RAGrabAreaSideAnywhere = 6, 9 | RAGrabAreaSideTopThird = 7, 10 | RAGrabAreaSideMiddleThird = 8, 11 | RAGrabAreaSideBottomThird = 9, 12 | }; 13 | 14 | @interface RASettings : NSObject { 15 | NSDictionary *_settings; 16 | } 17 | +(instancetype)sharedInstance; 18 | 19 | +(BOOL) isParagonInstalled; 20 | +(BOOL) isActivatorInstalled; 21 | +(BOOL) isLibStatusBarInstalled; 22 | 23 | -(void) reloadSettings; 24 | -(void) resetSettings; 25 | 26 | -(BOOL) enabled; 27 | 28 | -(BOOL) reachabilityEnabled; 29 | -(BOOL) disableAutoDismiss; 30 | -(BOOL) enableRotation; 31 | -(BOOL) showNCInstead; 32 | -(BOOL) homeButtonClosesReachability; 33 | -(BOOL) showBottomGrabber; 34 | -(BOOL) showWidgetSelector; 35 | -(BOOL) scalingRotationMode; 36 | -(BOOL) autoSizeWidgetSelector; 37 | -(BOOL) showAllAppsInWidgetSelector; 38 | -(BOOL) showRecentAppsInWidgetSelector; 39 | -(BOOL) pagingEnabled; 40 | -(NSMutableArray*) favoriteApps; 41 | -(BOOL) unifyStatusBar; 42 | -(BOOL) flipTopAndBottom; 43 | -(BOOL) showFavorites; 44 | 45 | -(BOOL) NCAppEnabled; 46 | -(NSString*) NCApp; 47 | -(BOOL) ncAppHideOnLS; 48 | 49 | -(BOOL) alwaysEnableGestures; 50 | -(BOOL) snapWindows; 51 | -(BOOL) snapRotation; 52 | -(BOOL) launchIntoWindows; 53 | -(BOOL) windowedMultitaskingCompleteAnimations; 54 | -(BOOL) openLinksInWindows; 55 | -(BOOL) showSnapHelper; 56 | 57 | -(NSInteger) globalBackgroundMode; 58 | -(BOOL) shouldShowStatusBarIcons; 59 | -(BOOL) shouldShowStatusBarNativeIcons; 60 | -(BOOL) backgrounderEnabled; 61 | -(BOOL) shouldShowIconIndicatorsGlobally; 62 | -(BOOL) showNativeStateIconIndicators; 63 | -(NSDictionary*) rawCompiledBackgrounderSettingsForIdentifier:(NSString*)identifier; 64 | 65 | -(BOOL) missionControlEnabled; 66 | -(BOOL) replaceAppSwitcherWithMC; 67 | -(BOOL) missionControlKillApps; 68 | -(NSInteger) missionControlDesktopStyle; 69 | -(BOOL) missionControlPagingEnabled; 70 | 71 | -(BOOL) isFirstRun; 72 | -(void) setFirstRun:(BOOL)value; 73 | 74 | -(BOOL) swipeOverEnabled; 75 | -(BOOL) alwaysShowSOGrabber; 76 | 77 | -(BOOL) exitAppAfterUsingActivatorAction; 78 | 79 | -(BOOL) quickAccessUseGenericTabLabel; 80 | 81 | #if DEBUG 82 | -(BOOL) debug_showIPCMessages; 83 | #endif 84 | 85 | -(BOOL) windowedMultitaskingEnabled; 86 | -(NSInteger) windowRotationLockMode; 87 | -(RAGrabArea) windowedMultitaskingGrabArea; 88 | -(RAGrabArea) swipeOverGrabArea; 89 | -(BOOL) onlyShowWindowBarIconsOnOverlay; 90 | 91 | -(NSString*) currentThemeIdentifier; 92 | @end -------------------------------------------------------------------------------- /RASnapshotProvider.h: -------------------------------------------------------------------------------- 1 | #import "RADesktopWindow.h" 2 | 3 | @interface RASnapshotProvider : NSObject { 4 | NSCache *imageCache; 5 | } 6 | +(id) sharedInstance; 7 | 8 | -(UIImage*) snapshotForDesktop:(RADesktopWindow*)desktop; 9 | -(void) forceReloadSnapshotOfDesktop:(RADesktopWindow*)desktop; 10 | 11 | -(UIImage*) storedSnapshotOfMissionControl; 12 | -(void) storeSnapshotOfMissionControl:(UIWindow*)window; 13 | 14 | -(UIImage*) snapshotForIdentifier:(NSString*)identifier; 15 | -(void) forceReloadOfSnapshotForIdentifier:(NSString*)identifier; 16 | 17 | -(UIImage*) wallpaperImage; 18 | 19 | -(void) forceReloadEverything; 20 | @end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multiplexer 2 | Six multitasking additions to iOS 3 | 4 | http://moreinfo.thebigboss.org/moreinfo/depiction.php?file=multiplexerDp 5 | 6 | ### Features 7 | - Secondary app in Reachability (Reach App) 8 | - iOS 9-like "slide over" (Swipe Over) 9 | - Mission Control with multiple desktops (Mission Control) 10 | - Windowed multitasking (Empoleon) 11 | - An app in a Notication Center tab (Quick Access) 12 | - Backgrounding features (Aura) 13 | 14 | ### Wiki 15 | See /wiki for some code tutorials. 16 | 17 | ### iOS 9 Update Status 18 | - Empoleon: working 19 | - fs daemon: working 20 | - SwipeOver: fixed 21 | - Reachability: fixed 22 | - GestureSupport: fixed 23 | - Backgrounding: fixed 24 | - KeyboardSupport: hackily fixed but it works now 25 | - MissionControl: initialization broken, otherwise fixed 26 | - NCApp: fixed 27 | - assertiond hooks: unknown 28 | - backboardd hooks: unknown 29 | - fake phone mode: unknown 30 | 31 | see the update_status file for more info on the iOS 9 changes. 32 | 33 | ### API 34 | There is a full public API (as opposed to the private/interval api and headers) that allows anyone to create addons, widgets, and tweaks (Tweakception!) for Multiplexer. 35 | The public api can be found in public_api. This api is less likely to change or be removed as opposed to the other headers and stuff. 36 | For the end user's ease of use, please register your extensions with -[Multiplexer registerExtension:forMultiplexerVersion:]. I hope to also move the core functions into extensions, provide api requirements, etc at some point. 37 | 38 | Currently it is only compatible with iOS 8, however some measures have been taken to ease the process of making it compatible with other iOS editions (whether future or past). 39 | There are some "options" or features that are in here but are disabled or otherwise removed because either they don't work or there's no point having them. 40 | -------------------------------------------------------------------------------- /ReachApp.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.UIKit" ); }; } -------------------------------------------------------------------------------- /ReachAppIntegrator.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | #define CHECK_FOR_REACHAPP \ 6 | if ([NSFileManager.defaultManager fileExistsAtPath:@"/Library/MobileSubstrate/DynamicLibraries/ReachApp.dylib"]) \ 7 | dlopen("/Library/MobileSubstrate/DynamicLibraries/ReachApp.dylib", RTLD_NOW | RTLD_GLOBAL); 8 | 9 | #define IF_REACHAPP if (objc_getClass("RAWidget") != nil) -------------------------------------------------------------------------------- /Reachability/RAReachabilityManager.h: -------------------------------------------------------------------------------- 1 | #import "RAWidget.h" 2 | 3 | @class RAAppSliderProviderView; 4 | 5 | @interface RAReachabilityManager : NSObject 6 | +(id) sharedInstance; 7 | 8 | -(void) launchTopAppWithIdentifier:(NSString*)identifier; 9 | -(void) launchWidget:(RAWidget*)widget; 10 | -(void) showAppWithSliderProvider:(__weak RAAppSliderProviderView*)view; 11 | 12 | -(void) showWidgetSelector; 13 | @end -------------------------------------------------------------------------------- /Reachability/RAReachabilityManager.mm: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAReachabilityManager.h" 3 | #import "headers.h" 4 | #import "RAAppSliderProviderView.h" 5 | #import "RAMessagingServer.h" 6 | 7 | @implementation RAReachabilityManager 8 | +(id) sharedInstance 9 | { 10 | SHARED_INSTANCE(RAReachabilityManager); 11 | } 12 | 13 | -(void) launchTopAppWithIdentifier:(NSString*)identifier 14 | { 15 | //[[objc_getClass("SBWorkspace") sharedInstance] RA_closeCurrentView]; 16 | [GET_SBWORKSPACE RA_launchTopAppWithIdentifier:identifier]; 17 | } 18 | 19 | -(void) launchWidget:(RAWidget*)widget 20 | { 21 | //[[objc_getClass("SBWorkspace") sharedInstance] RA_closeCurrentView]; 22 | [GET_SBWORKSPACE RA_setView:[widget view] preferredHeight:[widget preferredHeight]]; 23 | } 24 | 25 | -(void) showWidgetSelector 26 | { 27 | //[[objc_getClass("SBWorkspace") sharedInstance] RA_closeCurrentView]; 28 | [GET_SBWORKSPACE RA_showWidgetSelector]; 29 | } 30 | 31 | -(void) showAppWithSliderProvider:(__weak RAAppSliderProviderView*)view 32 | { 33 | //[[objc_getClass("SBWorkspace") sharedInstance] RA_closeCurrentView]; 34 | [view updateCurrentView]; 35 | [view load]; 36 | [GET_SBWORKSPACE RA_setView:view preferredHeight:view.frame.size.height]; 37 | } 38 | @end -------------------------------------------------------------------------------- /Reachability/UIKit.xm: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAMessagingClient.h" 3 | 4 | BOOL allowClosingReachabilityNatively = NO; 5 | 6 | %hook UIApplication 7 | - (void)_deactivateReachability 8 | { 9 | if (allowClosingReachabilityNatively == NO) 10 | { 11 | NSLog(@"[ReachApp] attempting to close reachability but not allowed to."); 12 | return; 13 | } 14 | 15 | if ([RAMessagingClient.sharedInstance isBeingHosted]) 16 | { 17 | NSLog(@"[ReachApp] stopping reachability from closing because hosted"); 18 | return; 19 | } 20 | %orig; 21 | } 22 | %end 23 | 24 | /* 25 | %hook UIWindow 26 | - (void)makeKeyAndVisible 27 | { 28 | overrideViewControllerDismissal = YES; 29 | %orig; 30 | overrideViewControllerDismissal = NO; 31 | } 32 | %end 33 | 34 | %hook UIViewController 35 | - (void)_presentViewController:(unsafe_id)viewController withAnimationController:(unsafe_id)animationController completion:(unsafe_id)completion 36 | { 37 | overrideViewControllerDismissal = YES; 38 | %orig; 39 | overrideViewControllerDismissal = NO; 40 | } 41 | 42 | - (void)dismissViewControllerWithTransition:(unsafe_id)transition completion:(unsafe_id)completion 43 | { 44 | overrideViewControllerDismissal = YES; 45 | %orig; 46 | overrideViewControllerDismissal = NO; 47 | } 48 | %end 49 | 50 | %hook UINavigationController 51 | - (void)pushViewController:(unsafe_id)viewController transition:(unsafe_id)transition forceImmediate:(BOOL)immediate 52 | { 53 | overrideViewControllerDismissal = YES; 54 | %orig; 55 | overrideViewControllerDismissal = NO; 56 | } 57 | 58 | - (id)_popViewControllerWithTransition:(unsafe_id)transition allowPoppingLast:(BOOL)last 59 | { 60 | overrideViewControllerDismissal = YES; 61 | id r = %orig; 62 | overrideViewControllerDismissal = NO; 63 | return r; 64 | } 65 | 66 | - (void)_popViewControllerAndUpdateInterfaceOrientationAnimated:(BOOL)animated 67 | { 68 | overrideViewControllerDismissal = YES; 69 | %orig; 70 | overrideViewControllerDismissal = NO; 71 | } 72 | %end 73 | 74 | %hook UIInputWindowController 75 | - (void)moveFromPlacement:(unsafe_id)arg1 toPlacement:(unsafe_id)arg2 starting:(unsafe_id)arg3 completion:(unsafe_id)arg4 76 | { 77 | overrideViewControllerDismissal = YES; 78 | %orig; 79 | overrideViewControllerDismissal = NO; 80 | } 81 | %end 82 | */ -------------------------------------------------------------------------------- /SKBounceAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKBounceAnimation.h 3 | // SKBounceAnimation 4 | // 5 | // Created by Soroush Khanlou on 6/15/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef CGFloat SKBounceAnimationStiffness; 13 | 14 | extern SKBounceAnimationStiffness SKBounceAnimationStiffnessLight; 15 | extern SKBounceAnimationStiffness SKBounceAnimationStiffnessMedium; 16 | extern SKBounceAnimationStiffness SKBounceAnimationStiffnessHeavy; 17 | 18 | @interface SKBounceAnimation : CAKeyframeAnimation 19 | 20 | @property (nonatomic, retain) id fromValue; 21 | @property (nonatomic, retain) id byValue; 22 | @property (nonatomic, retain) id toValue; 23 | @property (nonatomic, assign) NSUInteger numberOfBounces; 24 | @property (nonatomic, assign) BOOL shouldOvershoot; //default YES 25 | @property (nonatomic, assign) BOOL shake; //if shaking, set fromValue to the furthest value, and toValue to the current value 26 | @property (nonatomic, assign) SKBounceAnimationStiffness stiffness; 27 | 28 | + (SKBounceAnimation*) animationWithKeyPath:(NSString*)keyPath; 29 | 30 | 31 | @end -------------------------------------------------------------------------------- /SwipeOver/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | 3 | CFLAGS = -I../ -I../Theming/ -I../GestureSupport/ -I../WindowedMultitasking/ -I../Messaging/ -I../KeyboardSupport -I../MissionControl 4 | CFLAGS += -fobjc-arc 5 | LDFLAGS += -Wl,-segalign,4000 6 | include $(THEOS)/makefiles/common.mk 7 | 8 | TWEAK_NAME = ReachAppSwipeOver 9 | ReachAppSwipeOver_FILES = $(wildcard *.xm) $(wildcard *.mm) $(wildcard *.m) 10 | ReachAppSwipeOver_FRAMEWORKS = UIKit CoreGraphics 11 | 12 | include $(THEOS_MAKE_PATH)/tweak.mk 13 | 14 | after-install:: 15 | install.exec "killall -9 SpringBoard" 16 | -------------------------------------------------------------------------------- /SwipeOver/RASwipeOverManager.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RASwipeOverManager : NSObject { 4 | NSString *currentAppIdentifier; 5 | BOOL isUsingSwipeOver; 6 | } 7 | +(id) sharedInstance; 8 | 9 | -(void) startUsingSwipeOver; 10 | -(void) stopUsingSwipeOver; 11 | -(BOOL) isUsingSwipeOver; 12 | 13 | -(void) createEdgeView; 14 | 15 | -(void) showApp:(NSString*)identifier; // if identifier is nil it will use the app switcher data 16 | -(void) closeCurrentView; // App or selector 17 | -(void) showAppSelector; // No widget chooser, not enough horizontal space. TODO: make it work anyway 18 | 19 | -(BOOL) isEdgeViewShowing; 20 | -(void) convertSwipeOverViewToSideBySide; 21 | 22 | -(void) sizeViewForTranslation:(CGPoint)translation state:(UIGestureRecognizerState)state; 23 | @end 24 | 25 | #define RASWIPEOVER_VIEW_TAG 996 26 | -------------------------------------------------------------------------------- /SwipeOver/RASwipeOverOverlay.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAAppSelectorView.h" 3 | 4 | @interface RASwipeOverOverlay : UIAutoRotatingWindow { 5 | BOOL isHidingUnderlyingApp; 6 | 7 | UIView *darkenerView; 8 | } 9 | @property (nonatomic, retain) UIView *grabberView; 10 | 11 | -(BOOL) isHidingUnderlyingApp; 12 | -(void) showEnoughToDarkenUnderlyingApp; 13 | -(void) removeOverlayFromUnderlyingApp; 14 | -(void) removeOverlayFromUnderlyingAppImmediately; 15 | 16 | -(BOOL) isShowingAppSelector; 17 | -(void) showAppSelector; 18 | 19 | -(UIView*) currentView; 20 | @end -------------------------------------------------------------------------------- /SwipeOver/ReachAppSwipeOver.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.springboard" ); }; } 2 | -------------------------------------------------------------------------------- /Theming/RATheme.mm: -------------------------------------------------------------------------------- 1 | #import "RATheme.h" 2 | 3 | @implementation RATheme 4 | 5 | @end -------------------------------------------------------------------------------- /Theming/RAThemeLoader.h: -------------------------------------------------------------------------------- 1 | #import "RATheme.h" 2 | 3 | @interface RAThemeLoader : NSObject 4 | +(RATheme*)loadFromFile:(NSString*)baseName; 5 | 6 | +(RATheme*) themeFromDictionary:(NSDictionary*)dict; 7 | @end -------------------------------------------------------------------------------- /Theming/RAThemeManager.h: -------------------------------------------------------------------------------- 1 | #import "RATheme.h" 2 | 3 | @interface RAThemeManager : NSObject { 4 | NSMutableDictionary *allThemes; 5 | RATheme *currentTheme; 6 | } 7 | 8 | +(instancetype) sharedInstance; 9 | 10 | -(RATheme*) currentTheme; 11 | -(NSArray*) allThemes; 12 | 13 | -(void) invalidateCurrentThemeAndReload:(NSString*)currentIdentifier; 14 | @end -------------------------------------------------------------------------------- /Theming/RAThemeManager.mm: -------------------------------------------------------------------------------- 1 | #import "RAThemeManager.h" 2 | #import "RAThemeLoader.h" 3 | #import "RASettings.h" 4 | #import "headers.h" 5 | 6 | @implementation RAThemeManager 7 | +(instancetype) sharedInstance 8 | { 9 | SHARED_INSTANCE2(RAThemeManager, [sharedInstance invalidateCurrentThemeAndReload:nil]); // will be reloaded by RASettings 10 | } 11 | 12 | -(RATheme*) currentTheme { return currentTheme; } 13 | -(NSArray*) allThemes { return allThemes.allValues; } 14 | 15 | -(void) invalidateCurrentThemeAndReload:(NSString*)currentIdentifier 16 | { 17 | #if DEBUG 18 | NSLog(@"[ReachApp] loading themes..."); 19 | NSDate *startTime = [NSDate date]; 20 | #endif 21 | 22 | currentTheme = nil; 23 | [allThemes removeAllObjects]; 24 | allThemes = [NSMutableDictionary dictionary]; 25 | 26 | NSString *folderName = [NSString stringWithFormat:@"%@/Themes/", RA_BASE_PATH]; 27 | NSArray *themeFileNames = [NSFileManager.defaultManager subpathsAtPath:folderName]; 28 | 29 | for (NSString *themeName in themeFileNames) 30 | { 31 | if ([themeName hasSuffix:@"plist"] == NO) 32 | continue; 33 | 34 | RATheme *theme = [RAThemeLoader loadFromFile:themeName]; 35 | if (theme && theme.themeIdentifier) 36 | { 37 | //NSLog(@"[ReachApp] adding %@", theme.themeIdentifier); 38 | allThemes[theme.themeIdentifier] = theme; 39 | 40 | if ([theme.themeIdentifier isEqual:currentIdentifier]) 41 | currentTheme = theme; 42 | } 43 | } 44 | if (!currentTheme) 45 | { 46 | currentTheme = [allThemes objectForKey:@"com.eljahandandrew.multiplexer.themes.default"]; 47 | if (!currentTheme && allThemes.allKeys.count > 0) 48 | { 49 | currentTheme = allThemes[allThemes.allKeys[0]]; 50 | } 51 | } 52 | 53 | #if DEBUG 54 | NSDate *endTime = [NSDate date]; 55 | NSLog(@"[ReachApp] loaded %ld themes in %f seconds.", (long)allThemes.count, [endTime timeIntervalSinceDate:startTime]); 56 | #endif 57 | } 58 | @end -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 arm64 2 | 3 | include theos/makefiles/common.mk 4 | 5 | TWEAK_NAME = MultiplexerTutorial 6 | MultiplexerTutorial_FILES = Tweak.xm 7 | MultiplexerTutorial_FRAMEWORKS = UIKit 8 | 9 | include $(THEOS_MAKE_PATH)/tweak.mk 10 | 11 | after-install:: 12 | install.exec "killall -9 SpringBoard" 13 | -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/MultiplexerTutorial.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.andrewabosh.Multiplexer", "com.apple.springboard" ); }; } 2 | -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/Tweak.xm: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | %hook UIApplication 4 | -(BOOL) openURL:(NSURL*)url 5 | { 6 | CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFSTR("com.elijahandandrew.multiplexer.tutorial.open_settings"), nil, nil, YES); 7 | return YES; 8 | } 9 | %end 10 | 11 | void open_settings(CFNotificationCenterRef a, void *b, CFStringRef c, const void *d, CFDictionaryRef e) 12 | { 13 | [UIApplication.sharedApplication openURL:[NSURL URLWithString:@"prefs:root=Multiplexer"]]; 14 | } 15 | 16 | %ctor 17 | { 18 | if ([NSBundle.mainBundle.bundleIdentifier isEqual:@"com.apple.springboard"]) 19 | CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, open_settings, CFSTR("com.elijahandandrew.multiplexer.tutorial.open_settings"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); 20 | else 21 | %init; 22 | } -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29@2x.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29@2x~ipad.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29@3x.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon29x29~ipad.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40@2x.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40@2x~ipad.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40@3x.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon40x40~ipad.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon76x76@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon76x76@2x~ipad.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon76x76~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/AppIcon76x76~ipad.png -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Assets.car: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Assets.car -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Launch Screen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Launch Screen.storyboardc/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Launch Screen.storyboardc/Info.plist -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Launch Screen.storyboardc/UIViewController-01J-lp-oVM.nib -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Multiplexer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/Multiplexer -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/archived-expanded-entitlements.xcent: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | application-identifier 6 | NYV24DF4EN.com.andrewabosh.Multiplexer 7 | keychain-access-groups 8 | 9 | NYV24DF4EN.com.andrewabosh.Multiplexer 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au1.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au2.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au3.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au4.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au4.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au5.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au5.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au6.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/au6.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em1.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em2.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em3.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em4.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em4.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em5.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em5.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em6.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/em6.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/embedded.mobileprovision: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/embedded.mobileprovision -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc1.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc2.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc3.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc4.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc4.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc5.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc5.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc6.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc6.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc7.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/mc7.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/qa1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/qa1.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/qa2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/qa2.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra1.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra2.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra3.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra4.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/ra4.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so1.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so2.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so3.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so3.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so4.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/TutorialApp/multiplexertutorial/layout/Applications/Multiplexer.app/so4.mp4 -------------------------------------------------------------------------------- /TutorialApp/multiplexertutorial/layout/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: com.elijahandandrew.MultiplexerTutorial 2 | Name: Multiplexer Tutorial 3 | Version: 1.0 4 | Section: Applications 5 | Depends: mobilesubstrate 6 | Architecture: iphoneos-arm 7 | Description: Tutorial for the tweak Multiplexer. 8 | Author: Elijah and Andrew 9 | Sponsor: Elijah and Andrew 10 | Maintainer: Elijah and Andrew 11 | -------------------------------------------------------------------------------- /Tweak.xm: -------------------------------------------------------------------------------- 1 | #define MULTIPLEXER_CORE 1 2 | #import "headers.h" 3 | #include 4 | 5 | /* 6 | This project thanks: 7 | ForceReach: https://github.com/PoomSmart/ForceReach/ 8 | Reference: https://github.com/fewjative/Reference 9 | MessageBox: https://github.com/b3ll/MessageBox 10 | This pastie (by @Freerunnering?): http://pastie.org/pastes/8684110 11 | Previous research done by b3ll and freerunnering (with _UIRemoteView, BKSProcessAssertion, etc) 12 | Various tips and help (early ReachApp (when it was just the reachability part): @sharedRoutine 13 | Various concepts / help / ideas: Ethan Arbuckle (@its_not_herpes) 14 | 15 | Many concepts and ideas have been used from them. 16 | Unlike shinvou's claims, however, there was no copyright violation. Nor did I use any of his code. Or Auxo 3's for that matter. See here for context: https://www.reddit.com/r/jailbreak/comments/3esp30/question_how_come_we_all_desperately_waited_for/cti3eck 17 | Any code based off of or using parts of the above projects is documented. 18 | 19 | */ 20 | 21 | // IS_SPRINGBOARD macro optimized from always comparing NSBundle - because it won't change in-process 22 | BOOL $__IS_SPRINGBOARD = NO; 23 | %ctor 24 | { 25 | $__IS_SPRINGBOARD = [NSBundle.mainBundle.bundleIdentifier isEqual:@"com.apple.springboard"]; 26 | } 27 | 28 | void SET_BACKGROUNDED(id settings, BOOL value) 29 | { 30 | #if __has_feature(objc_arc) 31 | // stupid ARC... 32 | ptrdiff_t bgOffset = ivar_getOffset(class_getInstanceVariable([settings class], "_backgrounded")); 33 | char *bgPtr = ((char *)(__bridge void *)settings) + bgOffset; 34 | memcpy(bgPtr, &value, sizeof(value)); 35 | #else 36 | // ARC is off, easy way 37 | if (value) 38 | object_setInstanceVariable(settings, "_backgrounded", (void*)YES); // strangely it doesn't like using the val, i have to do this. 39 | else 40 | object_setInstanceVariable(settings, "_backgrounded", (void*)NO); 41 | #endif 42 | } 43 | 44 | /* 45 | #if DEBUG 46 | //extern "C" void _CFEnableZombies(void); 47 | %ctor 48 | { 49 | IF_SPRINGBOARD { 50 | _CFEnableZombies(); 51 | } 52 | } 53 | #endif 54 | */ 55 | -------------------------------------------------------------------------------- /UIColor+HexString.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+HexString.h 3 | // 4 | // Created by Micah Hainline 5 | // http://stackoverflow.com/users/590840/micah-hainline 6 | // 7 | 8 | #import 9 | 10 | @interface UIColor (HexString) 11 | 12 | + (UIColor *) RA_colorWithHexString:(NSString*)hexString; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /UIColor+HexString.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+HexString.m 3 | // 4 | // Created by Micah Hainline 5 | // http://stackoverflow.com/users/590840/micah-hainline 6 | // 7 | 8 | #import "UIColor+HexString.h" 9 | 10 | 11 | @implementation UIColor (HexString) 12 | 13 | + (CGFloat) RA_colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length { 14 | NSString *substring = [string substringWithRange: NSMakeRange(start, length)]; 15 | NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring]; 16 | unsigned hexComponent; 17 | [[NSScanner scannerWithString:fullHex] scanHexInt:&hexComponent]; 18 | return hexComponent / 255.0; 19 | } 20 | 21 | + (UIColor *) RA_colorWithHexString: (NSString *) hexString { 22 | if (hexString.length == 0) 23 | return nil; 24 | NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString]; 25 | CGFloat alpha, red, blue, green; 26 | switch ([colorString length]) { 27 | case 3: // #RGB 28 | alpha = 1.0f; 29 | red = [self RA_colorComponentFrom: colorString start: 0 length: 1]; 30 | green = [self RA_colorComponentFrom: colorString start: 1 length: 1]; 31 | blue = [self RA_colorComponentFrom: colorString start: 2 length: 1]; 32 | break; 33 | case 4: // #ARGB 34 | alpha = [self RA_colorComponentFrom: colorString start: 0 length: 1]; 35 | red = [self RA_colorComponentFrom: colorString start: 1 length: 1]; 36 | green = [self RA_colorComponentFrom: colorString start: 2 length: 1]; 37 | blue = [self RA_colorComponentFrom: colorString start: 3 length: 1]; 38 | break; 39 | case 6: // #RRGGBB 40 | alpha = 1.0f; 41 | red = [self RA_colorComponentFrom: colorString start: 0 length: 2]; 42 | green = [self RA_colorComponentFrom: colorString start: 2 length: 2]; 43 | blue = [self RA_colorComponentFrom: colorString start: 4 length: 2]; 44 | break; 45 | case 8: // #AARRGGBB 46 | alpha = [self RA_colorComponentFrom: colorString start: 0 length: 2]; 47 | red = [self RA_colorComponentFrom: colorString start: 2 length: 2]; 48 | green = [self RA_colorComponentFrom: colorString start: 4 length: 2]; 49 | blue = [self RA_colorComponentFrom: colorString start: 6 length: 2]; 50 | break; 51 | default: 52 | return nil; 53 | } 54 | return [UIColor colorWithRed: red green: green blue: blue alpha: alpha]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /WindowedMultitasking/ActivatorToggleEditModeListener.xm: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RADesktopManager.h" 3 | #import "RADesktopWindow.h" 4 | #import "RAHostedAppView.h" 5 | #import "RAWindowBar.h" 6 | 7 | @interface RAActivatorToggleEditModeListener : NSObject 8 | @end 9 | 10 | static RAActivatorToggleEditModeListener *sharedInstance; 11 | 12 | @implementation RAActivatorToggleEditModeListener 13 | - (void)activator:(LAActivator *)activator receiveEvent:(LAEvent *)event 14 | { 15 | RADesktopWindow *desktop = RADesktopManager.sharedInstance.currentDesktop; 16 | 17 | for (RAWindowBar *view in desktop.subviews) 18 | { 19 | if ([view isKindOfClass:[RAWindowBar class]]) 20 | { 21 | if (view.isOverlayShowing) 22 | [view hideOverlay]; 23 | else 24 | [view showOverlay]; 25 | } 26 | } 27 | } 28 | @end 29 | 30 | %ctor 31 | { 32 | if([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.springboard"]) 33 | { 34 | sharedInstance = [[RAActivatorToggleEditModeListener alloc] init]; 35 | [[%c(LAActivator) sharedInstance] registerListener:sharedInstance forName:@"com.efrederickson.reachapp.windowedmultitasking.toggleEditMode"]; 36 | } 37 | } -------------------------------------------------------------------------------- /WindowedMultitasking/RADesktopManager.h: -------------------------------------------------------------------------------- 1 | #import "RADesktopWindow.h" 2 | 3 | @interface RADesktopManager : NSObject { 4 | NSMutableArray *windows; 5 | RADesktopWindow *currentDesktop; 6 | NSUInteger currentDesktopIndex; 7 | } 8 | +(instancetype) sharedInstance; 9 | 10 | @property (nonatomic, weak) RAWindowBar *lastUsedWindow; 11 | 12 | -(void) addDesktop:(BOOL)switchTo; 13 | -(void) removeDesktopAtIndex:(NSUInteger)index; 14 | -(void) removeAppWithIdentifier:(NSString*)bundleIdentifier animated:(BOOL)animated; 15 | -(void) removeAppWithIdentifier:(NSString*)bundleIdentifier animated:(BOOL)animated forceImmediateUnload:(BOOL)force; 16 | 17 | -(BOOL) isAppOpened:(NSString*)identifier; 18 | -(RAWindowBar*) windowForIdentifier:(NSString*)identifier; 19 | 20 | -(NSUInteger) currentDesktopIndex; 21 | -(NSUInteger) numberOfDesktops; 22 | -(void) switchToDesktop:(NSUInteger)index; 23 | -(void) switchToDesktop:(NSUInteger)index actuallyShow:(BOOL)show; 24 | -(RADesktopWindow*) currentDesktop; 25 | -(NSArray*) availableDesktops; 26 | -(RADesktopWindow*) desktopAtIndex:(NSUInteger)index; 27 | 28 | -(void) updateWindowSizeForApplication:(NSString*)identifier; 29 | -(void) updateRotationOnClients:(UIInterfaceOrientation)orientation; 30 | 31 | -(void) hideDesktop; 32 | -(void) reshowDesktop; 33 | 34 | -(void) findNewForemostApp; 35 | @end -------------------------------------------------------------------------------- /WindowedMultitasking/RADesktopWindow.h: -------------------------------------------------------------------------------- 1 | #import "RAHostedAppView.h" 2 | 3 | @class RAWindowBar; 4 | 5 | @interface RADesktopWindow : UIWindow { 6 | UIInterfaceOrientation lastKnownOrientation; 7 | NSMutableArray *appViews; 8 | 9 | BOOL dontClearForcedPhoneState; 10 | } 11 | 12 | -(RAWindowBar*) addAppWithView:(RAHostedAppView*)view animated:(BOOL)animated; 13 | -(RAWindowBar*) createAppWindowForSBApplication:(SBApplication*)app animated:(BOOL)animated; 14 | -(RAWindowBar*) createAppWindowWithIdentifier:(NSString*)identifier animated:(BOOL)animated; 15 | 16 | -(void) addExistingWindow:(RAWindowBar*)window; 17 | -(void) removeAppWithIdentifier:(NSString*)identifier animated:(BOOL)animated; 18 | -(void) removeAppWithIdentifier:(NSString*)identifier animated:(BOOL)animated forceImmediateUnload:(BOOL)force; 19 | 20 | -(NSArray*) hostedWindows; 21 | -(BOOL) isAppOpened:(NSString*)identifier; 22 | -(RAWindowBar*) windowForIdentifier:(NSString*)identifier; 23 | 24 | -(UIInterfaceOrientation) currentOrientation; 25 | -(CGFloat) baseRotationForOrientation; 26 | -(UIInterfaceOrientation) appOrientationRelativeToThisOrientation:(CGFloat)currentRotation; 27 | -(void) updateRotationOnClients:(UIInterfaceOrientation)orientation; 28 | 29 | -(void) updateWindowSizeForApplication:(NSString*)identifier; 30 | 31 | -(void) unloadApps; 32 | -(void) loadApps; 33 | -(void) closeAllApps; 34 | 35 | -(void) saveInfo; 36 | -(void) loadInfo; 37 | -(void) loadInfo:(NSInteger)index; 38 | @end -------------------------------------------------------------------------------- /WindowedMultitasking/RAWindowBar.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAHostedAppView.h" 3 | 4 | @class RADesktopWindow; 5 | 6 | @interface RAWindowBar : UIView { 7 | RAHostedAppView *attachedView; 8 | } 9 | 10 | @property (nonatomic, weak) RADesktopWindow *desktop; 11 | 12 | -(void) close; 13 | -(void) maximize; 14 | -(void) minimize; 15 | -(void) sizingLockButtonTap:(id)arg1; 16 | -(BOOL) isLocked; 17 | 18 | -(void) showOverlay; 19 | -(void) hideOverlay; 20 | -(BOOL) isOverlayShowing; 21 | 22 | -(RAHostedAppView*) attachedView; 23 | -(void) attachView:(RAHostedAppView*)view; 24 | 25 | -(void) updateClientRotation; 26 | -(void) updateClientRotation:(UIInterfaceOrientation)orientation; 27 | 28 | -(void) scaleTo:(CGFloat)scale animated:(BOOL)animate; 29 | -(void) scaleTo:(CGFloat)scale animated:(BOOL)animate derotate:(BOOL)derotate; 30 | 31 | -(void) saveWindowInfo; 32 | 33 | -(void) disableLongPress; 34 | -(void) enableLongPress; 35 | 36 | -(void) resignForemostApp; 37 | -(void) becomeForemostApp; 38 | @end -------------------------------------------------------------------------------- /WindowedMultitasking/RAWindowOverlayView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAWindowBar.h" 3 | 4 | @interface RAWindowOverlayView : UIView 5 | @property (nonatomic, weak) RAWindowBar *appWindow; 6 | -(void) show; 7 | -(void) dismiss; 8 | @end -------------------------------------------------------------------------------- /WindowedMultitasking/RAWindowSnapDataProvider.h: -------------------------------------------------------------------------------- 1 | #import "RAWindowBar.h" 2 | #import "RADesktopWindow.h" 3 | 4 | enum RAWindowSnapLocation { 5 | RAWindowSnapLocationInvalid = 0, 6 | 7 | RAWindowSnapLocationLeftTop, 8 | RAWindowSnapLocationLeftMiddle, 9 | RAWindowSnapLocationLeftBottom, 10 | 11 | RAWindowSnapLocationRightTop, 12 | RAWindowSnapLocationRightMiddle, 13 | RAWindowSnapLocationRightBottom, 14 | 15 | RAWindowSnapLocationBottom, 16 | RAWindowSnapLocationTop, 17 | RAWindowSnapLocationBottomCenter, 18 | 19 | RAWindowSnapLocationBottomLeft = RAWindowSnapLocationLeftBottom, 20 | RAWindowSnapLocationBottomRight = RAWindowSnapLocationRightBottom, 21 | 22 | RAWindowSnapLocationRight = RAWindowSnapLocationRightMiddle, 23 | RAWindowSnapLocationLeft = RAWindowSnapLocationLeftMiddle, 24 | RAWindowSnapLocationNone = RAWindowSnapLocationInvalid, 25 | }; 26 | 27 | @interface RAWindowSnapDataProvider : NSObject 28 | +(BOOL) shouldSnapWindow:(RAWindowBar*)bar; 29 | +(RAWindowSnapLocation) snapLocationForWindow:(RAWindowBar*)windowBar; 30 | +(CGPoint) snapCenterForWindow:(RAWindowBar*)window toLocation:(RAWindowSnapLocation)location; 31 | +(void) snapWindow:(RAWindowBar*)window toLocation:(RAWindowSnapLocation)location animated:(BOOL)animated; 32 | +(void) snapWindow:(RAWindowBar*)window toLocation:(RAWindowSnapLocation)location animated:(BOOL)animated completion:(dispatch_block_t)completionBlock; 33 | @end 34 | 35 | RAWindowSnapLocation RAWindowSnapLocationGetLeftOfScreen(); 36 | RAWindowSnapLocation RAWindowSnapLocationGetRightOfScreen(); 37 | -------------------------------------------------------------------------------- /WindowedMultitasking/RAWindowSorter.h: -------------------------------------------------------------------------------- 1 | #import "RADesktopWindow.h" 2 | 3 | @interface RAWindowSorter : NSObject 4 | +(void) sortWindowsOnDesktop:(RADesktopWindow*)desktop resizeIfNecessary:(BOOL)resize; 5 | @end -------------------------------------------------------------------------------- /WindowedMultitasking/RAWindowStatePreservationSystemManager.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RADesktopWindow.h" 3 | #import "RAWindowBar.h" 4 | 5 | struct RAPreservedWindowInformation { 6 | CGPoint center; 7 | CGAffineTransform transform; 8 | }; 9 | 10 | struct RAPreservedDesktopInformation { 11 | NSUInteger index; 12 | NSArray *openApps; //NSArray 13 | }; 14 | 15 | @interface RAWindowStatePreservationSystemManager : NSObject { 16 | NSMutableDictionary *dict; 17 | } 18 | +(id) sharedInstance; 19 | 20 | -(void) loadInfo; 21 | -(void) saveInfo; 22 | 23 | // Desktop 24 | -(void) saveDesktopInformation:(RADesktopWindow*)desktop; 25 | -(BOOL) hasDesktopInformationAtIndex:(NSInteger)index; 26 | -(RAPreservedDesktopInformation) desktopInformationForIndex:(NSInteger)index; 27 | 28 | // Window 29 | -(void) saveWindowInformation:(RAWindowBar*)window; 30 | -(BOOL) hasWindowInformationForIdentifier:(NSString*)appIdentifier; 31 | -(RAPreservedWindowInformation) windowInformationForAppIdentifier:(NSString*)identifier; 32 | -(void) removeWindowInformationForIdentifier:(NSString*)appIdentifier; 33 | @end -------------------------------------------------------------------------------- /WindowedMultitasking/WindowSorterActivator.xm: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RADesktopManager.h" 3 | #import "RADesktopWindow.h" 4 | #import "RAHostedAppView.h" 5 | #import "RAWindowBar.h" 6 | #import "RAWindowSorter.h" 7 | 8 | @interface RAActivatorSortWindowsListener : NSObject 9 | @end 10 | 11 | static RAActivatorSortWindowsListener *sharedInstance$RAActivatorSortWindowsListener; 12 | 13 | @implementation RAActivatorSortWindowsListener 14 | - (void)activator:(LAActivator *)activator receiveEvent:(LAEvent *)event 15 | { 16 | RADesktopWindow *desktop = RADesktopManager.sharedInstance.currentDesktop; 17 | 18 | [RAWindowSorter sortWindowsOnDesktop:desktop resizeIfNecessary:YES]; 19 | } 20 | @end 21 | 22 | %ctor 23 | { 24 | if([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.springboard"]) 25 | { 26 | sharedInstance$RAActivatorSortWindowsListener = [[RAActivatorSortWindowsListener alloc] init]; 27 | [[%c(LAActivator) sharedInstance] registerListener:sharedInstance$RAActivatorSortWindowsListener forName:@"com.efrederickson.reachapp.windowedmultitasking.sortWindows"]; 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /dispatch_after_cancel.h: -------------------------------------------------------------------------------- 1 | // thank you based stackoverflow 2 | // https://stackoverflow.com/questions/12475450/prevent-dispatch-after-background-task-from-being-executed 3 | 4 | struct dispatch_async_handle { 5 | char didFire; // control block did fire 6 | char shouldCall; // control block should call payload 7 | char shouldFree; // control block is owner of this handle 8 | char didFree; // fix trying to free a freed dispatch_async_handle 9 | }; 10 | 11 | 12 | #ifdef __cplusplus 13 | extern "C" 14 | #endif 15 | struct dispatch_async_handle *dispatch_after_cancellable(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t payload); 16 | 17 | 18 | #ifdef __cplusplus 19 | extern "C" 20 | #endif 21 | 22 | void dispatch_after_cancel(struct dispatch_async_handle *handle); -------------------------------------------------------------------------------- /dispatch_after_cancel.m: -------------------------------------------------------------------------------- 1 | #include "dispatch_after_cancel.h" 2 | 3 | struct dispatch_async_handle *dispatch_after_cancellable(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t payload) 4 | { 5 | struct dispatch_async_handle *handle = malloc(sizeof(struct dispatch_async_handle)); 6 | 7 | handle->didFire = 0; 8 | handle->shouldCall = 1; // initially, payload should be called 9 | handle->shouldFree = 0; // and handles belong to owner 10 | 11 | dispatch_after(when, queue, ^{ 12 | 13 | //NSLog(@"[ReachApp][%p] (control block) call=%d, free=%d, didfree=%d", handle, handle->shouldCall, handle->shouldFree, handle->didFree); 14 | 15 | handle->didFire = 1; 16 | if (handle->shouldCall) payload(); 17 | if (handle->shouldFree && handle->didFree == 0) free(handle); 18 | }); 19 | 20 | return handle; // to owner 21 | } 22 | 23 | void dispatch_after_cancel(struct dispatch_async_handle *handle) 24 | { 25 | if (handle->didFire && handle->shouldFree == 0) { 26 | //printf("[%p] (owner) too late, freeing myself\n", handle); 27 | handle->didFree = 1; 28 | free(handle); 29 | } 30 | else { 31 | //printf("[%p] (owner) set call=0, free=1\n", handle); 32 | handle->shouldCall = 0; 33 | handle->shouldFree = 1; // control block is owner now 34 | } 35 | } -------------------------------------------------------------------------------- /layout/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: org.thebigboss.multiplexer 2 | Name: Multiplexer 3 | Depends: mobilesubstrate, applist, preferenceloader, com.elijahandandrew.MultiplexerTutorial, com.rpetrich.rocketbootstrap 4 | Conflicts: cc.tweak.statushud 5 | Replaces: com.efrederickson.reachapp 6 | Version: 0.1 7 | Architecture: iphoneos-arm 8 | Description: All sorts of multitasking. 9 | Depiction: http://elijahandandrew.com/repo/depictions/Multiplexer/index.html 10 | Maintainer: Elijah and Andrew 11 | Author: Elijah and Andrew 12 | Section: Tweaks 13 | -------------------------------------------------------------------------------- /layout/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | chgrp wheel /Library/LaunchDaemons/com.efrederickson.reachapp.fsdaemon.plist 4 | chown root /Library/LaunchDaemons/com.efrederickson.reachapp.fsdaemon.plist 5 | launchctl load -w /Library/LaunchDaemons/com.efrederickson.reachapp.fsdaemon.plist 6 | 7 | #echo "The best multitasker you've never used... Until now." 8 | echo "Thanks for using Multiplexer!" 9 | -------------------------------------------------------------------------------- /layout/DEBIAN/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | launchctl unload -w /Library/LaunchDaemons/com.efrederickson.reachapp.fsdaemon.plist 4 | 5 | -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | compatible-modes 6 | 7 | springboard 8 | application 9 | lockscreen 10 | 11 | description 12 | Toggle Aura mode for the current app 13 | title 14 | Toggle Aura Mode 15 | 16 | -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/icon-small.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/icon-small@2x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.backgrounder.togglemode/icon-small@3x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | compatible-modes 6 | 7 | springboard 8 | application 9 | lockscreen 10 | 11 | description 12 | Activate Multiplexer's Mission Control 13 | title 14 | Activate Mission Control 15 | 16 | -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/icon-small.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/icon-small@2x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.missioncontrol.activatorlistener/icon-small@3x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | compatible-modes 6 | 7 | springboard 8 | application 9 | lockscreen 10 | 11 | description 12 | Sorts open windows on the current desktop 13 | title 14 | Sort Windows 15 | 16 | -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/icon-small.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/icon-small@2x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.sortWindows/icon-small@3x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | compatible-modes 6 | 7 | springboard 8 | application 9 | lockscreen 10 | 11 | description 12 | Toggle edit mode on all open windows 13 | title 14 | Toggle Edit Mode 15 | 16 | -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/icon-small.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/icon-small@2x.png -------------------------------------------------------------------------------- /layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Activator/Listeners/com.efrederickson.reachapp.windowedmultitasking.toggleEditMode/icon-small@3x.png -------------------------------------------------------------------------------- /layout/Library/LaunchDaemons/com.efrederickson.reachapp.fsdaemon.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.efrederickson.reachapp.fsdaemon 7 | Program 8 | /usr/bin/ReachAppFSDaemon 9 | RunAtLoad 10 | 11 | StandardErrorPath 12 | /dev/null 13 | WatchPaths 14 | 15 | /User/Library/.reachapp.uiappexitsonsuspend.wantstochangerootapp 16 | 17 | user 18 | root 19 | group 20 | wheel 21 | 22 | -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Localizations/en.strings: -------------------------------------------------------------------------------- 1 | "BIOLOCKDOWN_AUTH_DESCRIPTION" = "Multiplexer requires authentication"; 2 | "BIOLOCKDOWN_AUTH_FAILED" = "BioLockdown authentication failed for %@. Tap to try again."; 3 | "MULTIPLEXER" = "Multiplexer"; 4 | "BACKGROUNDER_POPUP_SWITCHER_TEXT" = "Which backgrounding mode would you like to enable for %@ (currently %@)?"; 5 | "CANCEL" = "Cancel"; 6 | "FORCE_FOREGROUND" = "Force Foreground"; 7 | "NATIVE" = "Native"; 8 | "SUSPEND_IMMEDIATELY" = "Suspend Immediately"; 9 | "DISABLE" = "Disable"; 10 | "THANK_YOU_TEXT" = "Thank you for installing Multiplexer! Tap here to view the tutorial."; 11 | "DESKTOPS" = "Desktops"; 12 | "ON_THIS_DESKTOP" = "On This Desktop"; 13 | "RUNNING_ELSEWHERE" = "Running Elsewhere"; 14 | "NO_APPS" = "No Apps"; 15 | "APP" = "App"; 16 | "UNLOCK_FOR_NCAPP" = "Unlock to use\nQuick Access"; 17 | "ALL_APPS" = "All Apps"; 18 | "WIDGETS" = "Widgets"; 19 | "FAVORITES" = "Favorites"; 20 | "RECENTS" = "Recent"; 21 | "ACTIVE_APP_WARNING" = "%@\n is currently open"; 22 | "ASPHALEIA2_AUTH_FAILED" = "Asphaleia 2\n authentication failed for\n %@.\nTap to try again."; 23 | "UNLIMITED_BACKGROUNDING_TIME" = "Unlimited Backgrounding Time"; 24 | "KILL_ALL" = "Kill All"; -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Close.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Close.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Grabber.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Grabber.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Lock.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Lock.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Minus.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Minus.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Plus.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Plus.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/SwipeOverDetachImage.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/SwipeOverDetachImage.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Trash.png -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Trash@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Trash@2x.png -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Trash@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Trash@3x.png -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Resources/Unlocked.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/layout/Library/Multiplexer/Resources/Unlocked.pdf -------------------------------------------------------------------------------- /layout/Library/Multiplexer/Themes/Default.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | identifier 6 | com.eljahandandrew.multiplexer.themes.default 7 | displayName 8 | Default 9 | 10 | backgroundingIndicatorTextColor 11 | FFFFFF 12 | backgroundingIndicatorBackgroundColor 13 | 3C6CFF 14 | 15 | missionControlBlurStyle 16 | 1 17 | missionControlScrollViewBackgroundColor 18 | FFFFFF 19 | missionControlScrollViewOpacity 20 | 0.3 21 | missionControlIconPreviewShadowRadius 22 | 12 23 | windowedMultitaskingWindowBarBackgroundColor 24 | E5E4E5 25 | windowedMultitaskingCloseIconTint 26 | 80000000 27 | windowedMultitaskingCloseIconBackgroundColor 28 | FF7070 29 | windowedMultitaskingMaxIconTint 30 | 80000000 31 | windowedMultitaskingMaxIconBackgroundColor 32 | 73E8A6 33 | windowedMultitaskingMinIconTint 34 | 80000000 35 | windowedMultitaskingMinIconBackgroundColor 36 | 5ABFFF 37 | windowedMultitaskingRotationIconTint 38 | 80000000 39 | windowedMultitaskingRotationIconBackgroundColor 40 | B974F5 41 | windowedMultitaskingBarTitleColor 42 | 737273 43 | windowedMultitaskingOverlayColor 44 | 99000000 45 | windowedMultitaskingBlurStyle 46 | 2 47 | 48 | swipeOverDetachBarColor 49 | E5E4E5 50 | 51 | windowedMultitaskingCloseButtonAlignment 52 | 0 53 | windowedMultitaskingMaxButtonAlignment 54 | 0 55 | windowedMultitaskingMinButtonAlignment 56 | 0 57 | windowedMultitaskingRotationAlignment 58 | 1 59 | windowedMultitaskingCloseButtonPriority 60 | 0 61 | windowedMultitaskingMaxButtonPriority 62 | 1 63 | windowedMultitaskingMinButtonPriority 64 | 2 65 | windowedMultitaskingRotationPriority 66 | 0 67 | windowedMultaskingBarTitleTextAlignment 68 | 1 69 | 70 | windowedMultitaskingBarButtonCornerType 71 | 1 72 | 73 | -------------------------------------------------------------------------------- /public_api/Multiplexer.h: -------------------------------------------------------------------------------- 1 | @interface MultiplexerExtension : NSObject 2 | @property (nonatomic, retain) NSString *name; 3 | @property (nonatomic, retain) NSString *multiplexerVersion; 4 | @end 5 | 6 | @interface Multiplexer : NSObject { 7 | NSMutableArray *activeExtensions; 8 | } 9 | +(instancetype) sharedInstance; 10 | 11 | -(NSString*) currentVersion; 12 | -(BOOL) isOnSupportedOS; 13 | 14 | -(void) registerExtension:(NSString*)name forMultiplexerVersion:(NSString*)version; 15 | @end 16 | -------------------------------------------------------------------------------- /public_api/RAAppKiller.h: -------------------------------------------------------------------------------- 1 | @class SBApplication; 2 | 3 | @interface RAAppKiller : NSObject 4 | +(void) killAppWithIdentifier:(NSString*)identifier; 5 | +(void) killAppWithIdentifier:(NSString*)identifier completion:(void(^)())handler; 6 | +(void) killAppWithSBApplication:(SBApplication*)app; 7 | +(void) killAppWithSBApplication:(SBApplication*)app completion:(void(^)())handler; 8 | @end 9 | 10 | -------------------------------------------------------------------------------- /public_api/RAAppSelectorView.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class RAAppSelectorView; 4 | 5 | @protocol RAAppSelectorViewDelegate 6 | -(void) appSelector:(RAAppSelectorView*)view appWasSelected:(NSString*)bundleIdentifier; 7 | @end 8 | 9 | @interface RAAppSelectorView : UIScrollView 10 | @property (nonatomic, weak) NSObject *target; 11 | 12 | -(void) relayoutApps; 13 | @end -------------------------------------------------------------------------------- /public_api/RAAppSliderProvider.h: -------------------------------------------------------------------------------- 1 | @class RAHostedAppView; 2 | 3 | @interface RAAppSliderProvider : NSObject 4 | @property (nonatomic, retain) NSArray *availableIdentifiers; 5 | @property (nonatomic) NSInteger currentIndex; 6 | 7 | -(BOOL) canGoLeft; 8 | -(BOOL) canGoRight; 9 | 10 | -(RAHostedAppView*) viewToTheLeft; 11 | -(RAHostedAppView*) viewToTheRight; 12 | -(RAHostedAppView*) viewAtCurrentIndex; 13 | 14 | -(void) goToTheLeft; 15 | -(void) goToTheRight; 16 | @end 17 | -------------------------------------------------------------------------------- /public_api/RAAppSliderProviderView.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAHostedAppView.h" 3 | 4 | @class RAAppSliderProvider; 5 | 6 | @interface RAAppSliderProviderView : UIView 7 | @property (nonatomic, retain) RAAppSliderProvider *swipeProvider; 8 | @property (nonatomic) BOOL isSwipeable; 9 | 10 | -(CGRect) clientFrame; 11 | -(NSString*) currentBundleIdentifier; 12 | 13 | -(void) goToTheLeft; 14 | -(void) goToTheRight; 15 | 16 | -(void) load; 17 | -(void) unload; 18 | -(void) updateCurrentView; 19 | @end -------------------------------------------------------------------------------- /public_api/RABackgrounder.h: -------------------------------------------------------------------------------- 1 | @class SBApplication; 2 | 3 | enum RABackgroundMode { 4 | RABackgroundModeNative = 1, 5 | RABackgroundModeForceNativeForOldApps = 2, 6 | RABackgroundModeForcedForeground = 3, 7 | RABackgroundModeForceNone = 4, 8 | RABackgroundModeSuspendImmediately = 5, 9 | RABackgroundModeUnlimitedBackgroundingTime = 6, 10 | }; 11 | 12 | // Localized. 13 | NSString *FriendlyNameForBackgroundMode(RABackgroundMode mode); 14 | 15 | @interface RABackgrounder : NSObject 16 | +(id) sharedInstance; 17 | 18 | -(BOOL) shouldAutoLaunchApplication:(NSString*)identifier; 19 | -(BOOL) shouldAutoRelaunchApplication:(NSString*)identifier; 20 | 21 | -(NSInteger) backgroundModeForIdentifier:(NSString*)identifier; 22 | 23 | -(BOOL) shouldShowIndicatorForIdentifier:(NSString*)identifier; 24 | -(BOOL) shouldShowStatusBarIconForIdentifier:(NSString*)identifier; 25 | @end -------------------------------------------------------------------------------- /public_api/RAControlCenterInhibitor.h: -------------------------------------------------------------------------------- 1 | // This doesn't even need a description. 2 | 3 | @interface RAControlCenterInhibitor : NSObject 4 | +(void) setInhibited:(BOOL)value; 5 | +(BOOL) isInhibited; 6 | @end -------------------------------------------------------------------------------- /public_api/RADesktopManager.h: -------------------------------------------------------------------------------- 1 | #import "RADesktopWindow.h" 2 | 3 | @interface RADesktopManager : NSObject 4 | +(instancetype) sharedInstance; 5 | 6 | -(void) addDesktop:(BOOL)switchTo; 7 | -(void) removeDesktopAtIndex:(NSUInteger)index; 8 | -(void) removeAppWithIdentifier:(NSString*)bundleIdentifier animated:(BOOL)animated; 9 | -(void) removeAppWithIdentifier:(NSString*)bundleIdentifier animated:(BOOL)animated forceImmediateUnload:(BOOL)force; 10 | 11 | -(BOOL) isAppOpened:(NSString*)identifier; 12 | -(RAWindowBar*) windowForIdentifier:(NSString*)identifier; 13 | 14 | -(NSUInteger) currentDesktopIndex; 15 | -(RADesktopWindow*) currentDesktop; 16 | 17 | -(NSArray*) availableDesktops; 18 | -(NSUInteger) numberOfDesktops; 19 | -(RADesktopWindow*) desktopAtIndex:(NSUInteger)index; 20 | 21 | -(void) switchToDesktop:(NSUInteger)index; 22 | -(void) switchToDesktop:(NSUInteger)index actuallyShow:(BOOL)show; 23 | 24 | -(void) hideDesktop; 25 | -(void) reshowDesktop; 26 | @end -------------------------------------------------------------------------------- /public_api/RADesktopWindow.h: -------------------------------------------------------------------------------- 1 | #import "RAHostedAppView.h" 2 | 3 | @class RAWindowBar; 4 | 5 | @interface RADesktopWindow : UIWindow 6 | -(RAWindowBar*) addAppWithView:(RAHostedAppView*)view animated:(BOOL)animated; 7 | -(RAWindowBar*) createAppWindowForSBApplication:(SBApplication*)app animated:(BOOL)animated; 8 | -(RAWindowBar*) createAppWindowWithIdentifier:(NSString*)identifier animated:(BOOL)animated; 9 | 10 | -(void) removeAppWithIdentifier:(NSString*)identifier animated:(BOOL)animated; 11 | -(void) removeAppWithIdentifier:(NSString*)identifier animated:(BOOL)animated forceImmediateUnload:(BOOL)force; 12 | 13 | -(NSArray*) hostedWindows; 14 | -(BOOL) isAppOpened:(NSString*)identifier; 15 | -(RAWindowBar*) windowForIdentifier:(NSString*)identifier; 16 | 17 | -(void) unloadApps; 18 | -(void) loadApps; 19 | -(void) closeAllApps; 20 | @end -------------------------------------------------------------------------------- /public_api/RAFakePhoneMode.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | // iPad only. 4 | 5 | @interface RAFakePhoneMode : NSObject 6 | 7 | // Hook this to change the faked size when using Phone Mode. 8 | +(CGSize) fakedSize; 9 | 10 | // Whether this process is currently forcing "phone mode" or not. 11 | +(BOOL) shouldFakeForThisProcess; 12 | 13 | // Use in SpringBoard. Checks whether or not a certain application should be forcing phone mode. Also available by checking RAMessagingServer. 14 | +(BOOL) shouldFakeForAppWithIdentifier:(NSString*)identifier; 15 | 16 | // Use in SpringBoard. if you hook +[RAFakePhoneMode fakedSize], hook this too. 17 | +(CGSize) fakeSizeForAppWithIdentifier:(NSString*)identifier; 18 | @end -------------------------------------------------------------------------------- /public_api/RAGestureManager.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class RAGestureCallback; 4 | 5 | typedef enum { 6 | RAGestureCallbackResultSuccessAndContinue, 7 | RAGestureCallbackResultFailure, 8 | RAGestureCallbackResultSuccessAndStop, 9 | 10 | RAGestureCallbackResultSuccess = RAGestureCallbackResultSuccessAndContinue, 11 | } RAGestureCallbackResult; 12 | 13 | @protocol RAGestureCallbackProtocol 14 | -(BOOL) RAGestureCallback_canHandle:(CGPoint)point velocity:(CGPoint)velocity; 15 | -(RAGestureCallbackResult) RAGestureCallback_handle:(UIGestureRecognizerState)state withPoint:(CGPoint)location velocity:(CGPoint)velocity forEdge:(UIRectEdge)edge; 16 | @end 17 | 18 | typedef BOOL(^RAGestureConditionBlock)(CGPoint location, CGPoint velocity); 19 | typedef RAGestureCallbackResult(^RAGestureCallbackBlock)(UIGestureRecognizerState state, CGPoint location, CGPoint velocity); 20 | 21 | const NSUInteger RAGesturePriorityLow = 0; 22 | const NSUInteger RAGesturePriorityHigh = 10; 23 | const NSUInteger RAGesturePriorityDefault = RAGesturePriorityLow; 24 | 25 | @interface RAGestureManager : NSObject 26 | +(id) sharedInstance; 27 | 28 | -(void) addGestureRecognizer:(RAGestureCallbackBlock)callbackBlock withCondition:(RAGestureConditionBlock)conditionBlock forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier priority:(NSUInteger)priority; 29 | -(void) addGestureRecognizer:(RAGestureCallbackBlock)callbackBlock withCondition:(RAGestureConditionBlock)conditionBlock forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier; 30 | -(void) addGestureRecognizerWithTarget:(NSObject*)target forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier; 31 | -(void) addGestureRecognizerWithTarget:(NSObject*)target forEdge:(UIRectEdge)screenEdge identifier:(NSString*)identifier priority:(NSUInteger)priority; 32 | -(void) addGesture:(RAGestureCallback*)callback; 33 | -(void) removeGestureWithIdentifier:(NSString*)identifier; 34 | 35 | -(void) ignoreSwipesBeginningInRect:(CGRect)area forIdentifier:(NSString*)identifier; 36 | -(void) stopIgnoringSwipesForIdentifier:(NSString*)identifier; 37 | -(void) ignoreSwipesBeginningOnSide:(UIRectEdge)side aboveYAxis:(NSUInteger)axis forIdentifier:(NSString*)identifier; 38 | -(void) ignoreSwipesBeginningOnSide:(UIRectEdge)side belowYAxis:(NSUInteger)axis forIdentifier:(NSString*)identifier; 39 | @end -------------------------------------------------------------------------------- /public_api/RAHostedAppView.h: -------------------------------------------------------------------------------- 1 | @interface RAHostedAppView : UIView 2 | 3 | -(id) initWithBundleIdentifier:(NSString*)bundleIdentifier; 4 | 5 | @property (nonatomic) BOOL showSplashscreenInsteadOfSpinner; 6 | 7 | @property (nonatomic, retain) NSString *bundleIdentifier; 8 | @property (nonatomic) BOOL autosizesApp; 9 | 10 | @property (nonatomic) BOOL allowHidingStatusBar; 11 | @property (nonatomic) BOOL hideStatusBar; 12 | 13 | @property (nonatomic) BOOL shouldUseExternalKeyboard; 14 | 15 | @property (nonatomic) BOOL isCurrentlyHosting; 16 | 17 | -(SBApplication*) app; 18 | -(NSString*) displayName; 19 | 20 | @property (nonatomic, readonly) UIInterfaceOrientation orientation; 21 | -(void) rotateToOrientation:(UIInterfaceOrientation)o; 22 | 23 | -(void) preloadApp; 24 | -(void) loadApp; 25 | -(void) unloadApp; 26 | -(void) unloadApp:(BOOL)forceImmediate; 27 | 28 | @end -------------------------------------------------------------------------------- /public_api/RAInsetLabel.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAInsetLabel : UILabel 4 | @property (nonatomic) UIEdgeInsets textInset; 5 | @end 6 | -------------------------------------------------------------------------------- /public_api/RAMessaging.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | struct RAMessageAppData { 4 | BOOL shouldForceSize; 5 | // Can't use CGSize because it uses CGFloats which aren't able to be transferred between 32/64bit processes 6 | // Also why it can't use CGFloat 7 | float wantedClientOriginX; 8 | float wantedClientOriginY; 9 | float wantedClientWidth; 10 | float wantedClientHeight; 11 | BOOL statusBarVisibility; 12 | BOOL shouldForceStatusBar; 13 | BOOL canHideStatusBarIfWanted; 14 | UIInterfaceOrientation forcedOrientation; 15 | BOOL shouldForceOrientation; 16 | BOOL shouldUseExternalKeyboard; 17 | BOOL isBeingHosted; 18 | BOOL forcePhoneMode; // Requires client restart to apply 19 | }; 20 | 21 | typedef void (^RAMessageCompletionCallback)(BOOL success); 22 | -------------------------------------------------------------------------------- /public_api/RAMessagingClient.h: -------------------------------------------------------------------------------- 1 | #import "RAMessaging.h" 2 | 3 | @interface RAMessagingClient : NSObject 4 | +(instancetype) sharedInstance; 5 | 6 | @property (nonatomic, readonly) RAMessageAppData currentData; 7 | @property (nonatomic) BOOL hasRecievedData; 8 | 9 | -(void) requestUpdateFromServer; 10 | 11 | -(BOOL) notifyServerToOpenURL:(NSURL*)url openInWindow:(BOOL)openWindow; 12 | 13 | -(BOOL) shouldResize; 14 | -(CGSize) resizeSize; 15 | -(BOOL) shouldHideStatusBar; 16 | -(BOOL) shouldShowStatusBar; 17 | -(UIInterfaceOrientation) forcedOrientation; 18 | -(BOOL) shouldForceOrientation; 19 | -(BOOL) shouldUseExternalKeyboard; 20 | -(BOOL) isBeingHosted; 21 | @end -------------------------------------------------------------------------------- /public_api/RAMessagingServer.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAMessaging.h" 3 | 4 | @interface RAMessagingServer : NSObject 5 | +(instancetype) sharedInstance; 6 | 7 | -(RAMessageAppData) getDataForIdentifier:(NSString*)identifier; 8 | -(void) setData:(RAMessageAppData)data forIdentifier:(NSString*)identifier; 9 | -(void) sendStoredDataToApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 10 | -(void) resizeApp:(NSString*)identifier toSize:(CGSize)size completion:(RAMessageCompletionCallback)callback; 11 | -(void) moveApp:(NSString*)identifier toOrigin:(CGPoint)origin completion:(RAMessageCompletionCallback)callback; 12 | -(void) endResizingApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 13 | -(void) rotateApp:(NSString*)identifier toOrientation:(UIInterfaceOrientation)orientation completion:(RAMessageCompletionCallback)callback; 14 | -(void) unRotateApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 15 | -(void) forceStatusBarVisibility:(BOOL)visibility forApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 16 | -(void) unforceStatusBarVisibilityForApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 17 | -(void) setHosted:(BOOL)value forIdentifier:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 18 | -(void) forcePhoneMode:(BOOL)value forIdentifier:(NSString*)identifier andRelaunchApp:(BOOL)relaunch; 19 | 20 | -(unsigned int) getStoredKeyboardContextIdForApp:(NSString*)identifier; 21 | 22 | -(void) setShouldUseExternalKeyboard:(BOOL)value forApp:(NSString*)identifier completion:(RAMessageCompletionCallback)callback; 23 | @end 24 | -------------------------------------------------------------------------------- /public_api/RAMissionControlManager.h: -------------------------------------------------------------------------------- 1 | @interface RAMissionControlManager : NSObject 2 | +(instancetype) sharedInstance; 3 | 4 | @property (nonatomic, readonly) BOOL isShowingMissionControl; 5 | 6 | -(void) showMissionControl:(BOOL)animated; 7 | -(void) hideMissionControl:(BOOL)animated; 8 | -(void) toggleMissionControl:(BOOL)animated; 9 | @end -------------------------------------------------------------------------------- /public_api/RAReachabilityManager.h: -------------------------------------------------------------------------------- 1 | #import "widgets/RAWidget.h" 2 | 3 | @class RAAppSliderProviderView; 4 | 5 | @interface RAReachabilityManager : NSObject 6 | +(id) sharedInstance; 7 | 8 | -(void) launchTopAppWithIdentifier:(NSString*)identifier; 9 | -(void) launchWidget:(RAWidget*)widget; 10 | -(void) showAppWithSliderProvider:(RAAppSliderProviderView*)view; 11 | 12 | -(void) showWidgetSelector; 13 | @end -------------------------------------------------------------------------------- /public_api/RAResourceImageProvider.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RAResourceImageProvider : NSObject 4 | +(UIImage*) imageForFilename:(NSString*)filename; 5 | +(UIImage*) imageForFilename:(NSString*)filename size:(CGSize)size tintedTo:(UIColor*)tint; 6 | +(UIImage*) imageForFilename:(NSString*)filename constrainedToSize:(CGSize)size; 7 | @end -------------------------------------------------------------------------------- /public_api/RARunningAppsProvider.h: -------------------------------------------------------------------------------- 1 | @class SBApplication; 2 | 3 | @protocol RARunningAppsProviderDelegate 4 | @optional 5 | -(void) appDidStart:(SBApplication*)app; 6 | -(void) appDidDie:(SBApplication*)app; 7 | @end 8 | 9 | @interface RARunningAppsProvider : NSObject 10 | +(instancetype) sharedInstance; 11 | 12 | -(void) addTarget:(NSObject*)target; 13 | -(void) removeTarget:(NSObject*)target; 14 | 15 | -(NSArray*) runningApplications; 16 | @end -------------------------------------------------------------------------------- /public_api/RASettings.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | // This exposes the entirety of the settings 4 | // You can check any setting from nearly any process with this. 5 | 6 | enum RAGrabArea { 7 | RAGrabAreaBottomLeftThird = 1, 8 | RAGrabAreaBottomMiddleThird = 2, 9 | RAGrabAreaBottomRightThird = 3, 10 | 11 | RAGrabAreaSideAnywhere = 6, 12 | RAGrabAreaSideTopThird = 7, 13 | RAGrabAreaSideMiddleThird = 8, 14 | RAGrabAreaSideBottomThird = 9, 15 | }; 16 | 17 | @interface RASettings : NSObject 18 | +(instancetype)sharedInstance; 19 | 20 | +(BOOL) isParagonInstalled; 21 | +(BOOL) isActivatorInstalled; 22 | +(BOOL) isLibStatusBarInstalled; 23 | 24 | -(void) reloadSettings; 25 | 26 | -(BOOL) enabled; 27 | 28 | -(BOOL) reachabilityEnabled; 29 | -(BOOL) disableAutoDismiss; 30 | -(BOOL) enableRotation; 31 | -(BOOL) showNCInstead; 32 | -(BOOL) homeButtonClosesReachability; 33 | -(BOOL) showBottomGrabber; 34 | -(BOOL) showWidgetSelector; 35 | -(BOOL) scalingRotationMode; 36 | -(BOOL) autoSizeWidgetSelector; 37 | -(BOOL) showAllAppsInWidgetSelector; 38 | -(BOOL) showRecentAppsInWidgetSelector; 39 | -(BOOL) pagingEnabled; 40 | -(NSMutableArray*) favoriteApps; 41 | -(BOOL) unifyStatusBar; 42 | -(BOOL) flipTopAndBottom; 43 | -(BOOL) showFavorites; 44 | -(BOOL) NCAppEnabled; 45 | -(NSString*) NCApp; 46 | -(BOOL) ncAppHideOnLS; 47 | -(BOOL) alwaysEnableGestures; 48 | -(BOOL) snapWindows; 49 | -(BOOL) snapRotation; 50 | -(BOOL) launchIntoWindows; 51 | -(BOOL) windowedMultitaskingCompleteAnimations; 52 | -(BOOL) openLinksInWindows; 53 | -(BOOL) showSnapHelper; 54 | -(NSInteger) globalBackgroundMode; 55 | -(BOOL) shouldShowStatusBarIcons; 56 | -(BOOL) shouldShowStatusBarNativeIcons; 57 | -(BOOL) backgrounderEnabled; 58 | -(BOOL) shouldShowIconIndicatorsGlobally; 59 | -(BOOL) showNativeStateIconIndicators; 60 | -(NSDictionary*) rawCompiledBackgrounderSettingsForIdentifier:(NSString*)identifier; 61 | -(BOOL) missionControlEnabled; 62 | -(BOOL) replaceAppSwitcherWithMC; 63 | -(BOOL) missionControlKillApps; 64 | -(NSInteger) missionControlDesktopStyle; 65 | -(BOOL) missionControlPagingEnabled; 66 | -(BOOL) isFirstRun; 67 | -(void) setFirstRun:(BOOL)value; 68 | -(BOOL) swipeOverEnabled; 69 | -(BOOL) alwaysShowSOGrabber; 70 | -(BOOL) exitAppAfterUsingActivatorAction; 71 | -(BOOL) quickAccessUseGenericTabLabel; 72 | -(BOOL) windowedMultitaskingEnabled; 73 | -(NSInteger) windowRotationLockMode; 74 | -(RAGrabArea) windowedMultitaskingGrabArea; 75 | -(RAGrabArea) swipeOverGrabArea; 76 | -(BOOL) onlyShowWindowBarIconsOnOverlay; 77 | -(NSString*) currentThemeIdentifier; 78 | @end -------------------------------------------------------------------------------- /public_api/RASwipeOverManager.h: -------------------------------------------------------------------------------- 1 | @interface RASwipeOverManager : NSObject 2 | +(id) sharedInstance; 3 | 4 | -(void) startUsingSwipeOver; 5 | -(void) stopUsingSwipeOver; 6 | -(BOOL) isUsingSwipeOver; 7 | 8 | -(void) showApp:(NSString*)identifier; // if identifier is nil it will use the app switcher data 9 | -(void) closeCurrentView; // App or selector 10 | -(void) showAppSelector; 11 | 12 | -(BOOL) isEdgeViewShowing; 13 | -(void) convertSwipeOverViewToSideBySide; 14 | 15 | @end -------------------------------------------------------------------------------- /public_api/RAThemeManager.h: -------------------------------------------------------------------------------- 1 | #import "RATheme.h" 2 | 3 | @interface RAThemeManager : NSObject 4 | +(instancetype) sharedInstance; 5 | 6 | -(RATheme*) currentTheme; 7 | -(NSArray*) allThemes; 8 | @end -------------------------------------------------------------------------------- /public_api/RAWindowBar.h: -------------------------------------------------------------------------------- 1 | #import "RAHostedAppView.h" 2 | 3 | @class RADesktopWindow; 4 | 5 | @interface RAWindowBar : UIView 6 | @property (nonatomic, weak) RADesktopWindow *desktop; 7 | 8 | -(void) close; 9 | -(void) maximize; 10 | -(void) minimize; 11 | -(BOOL) isLocked; 12 | 13 | -(void) showOverlay; 14 | -(void) hideOverlay; 15 | -(BOOL) isOverlayShowing; 16 | 17 | -(RAHostedAppView*) attachedView; 18 | -(void) attachView:(RAHostedAppView*)view; 19 | 20 | -(void) scaleTo:(CGFloat)scale animated:(BOOL)animate; 21 | @end -------------------------------------------------------------------------------- /public_api/ReachAppIntegrator.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | // original ReachApp widget api integrator for existing Reachability tweaks 6 | 7 | #define CHECK_FOR_REACHAPP \ 8 | if ([NSFileManager.defaultManager fileExistsAtPath:@"/Library/MobileSubstrate/DynamicLibraries/ReachApp.dylib"]) \ 9 | dlopen("/Library/MobileSubstrate/DynamicLibraries/ReachApp.dylib", RTLD_NOW | RTLD_GLOBAL); 10 | 11 | #define IF_REACHAPP if (objc_getClass("RAWidget") != nil) -------------------------------------------------------------------------------- /public_api/widgets/RADefaultWidgetSection.h: -------------------------------------------------------------------------------- 1 | #import "RAWidgetSection.h" 2 | #import "RAWidget.h" 3 | 4 | @interface RADefaultWidgetSection : RAWidgetSection 5 | +(id) sharedDefaultWidgetSection; 6 | @end -------------------------------------------------------------------------------- /public_api/widgets/RAWidget.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RAWidget : NSObject 4 | 5 | -(NSString*) identifier; 6 | 7 | // actual view for showing in Reachability 8 | -(UIView*) view; 9 | 10 | // Similar to an app icon with the image/title 11 | -(UIView*) iconForSize:(CGSize)size; 12 | 13 | -(CGFloat) preferredHeight; 14 | @end -------------------------------------------------------------------------------- /public_api/widgets/RAWidgetSection.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAWidget.h" 3 | 4 | @interface RAWidgetSection : NSObject 5 | -(BOOL) enabled; 6 | 7 | -(NSInteger) sortOrder; 8 | -(BOOL) showTitle; 9 | -(NSString*) displayName; 10 | -(NSString*) identifier; 11 | -(CGFloat) titleOffset; 12 | 13 | // The view should cache, if possible, to speed up loading times. 14 | // It should NOT show the title view. 15 | -(UIView*) viewForFrame:(CGRect)frame preferredIconSize:(CGSize)size iconsThatFitPerLine:(NSInteger)iconsPerLine spacing:(CGFloat)spacing; 16 | 17 | -(void) addWidget:(RAWidget*)widget; 18 | @end -------------------------------------------------------------------------------- /public_api/widgets/RAWidgetSectionManager.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAWidgetSection.h" 3 | 4 | @interface RAWidgetSectionManager : NSObject 5 | +(instancetype) sharedInstance; 6 | 7 | -(void) registerSection:(RAWidgetSection*)section; 8 | 9 | -(NSArray*) sections; 10 | -(NSArray*) enabledSections; 11 | 12 | -(UIView*) createViewForEnabledSectionsWithBaseFrame:(CGRect)frame preferredIconSize:(CGSize)size iconsThatFitPerLine:(NSInteger)iconsPerLine spacing:(CGFloat)spacing; 13 | @end -------------------------------------------------------------------------------- /reachappassertiondhooks/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | CFLAGS = -fno-objc-arc 3 | LDFLAGS += -Wl,-segalign,4000 4 | 5 | include $(THEOS)/makefiles/common.mk 6 | 7 | TWEAK_NAME = ReachAppAssertiondHooks 8 | ReachAppAssertiondHooks_FILES = Tweak.xm 9 | 10 | include $(THEOS_MAKE_PATH)/tweak.mk 11 | 12 | after-install:: 13 | install.exec "killall -9 SpringBoard" 14 | -------------------------------------------------------------------------------- /reachappassertiondhooks/ReachAppAssertiondHooks.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Executables = ( "assertiond" ); }; } 2 | -------------------------------------------------------------------------------- /reachappassertiondhooks/Tweak.xm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | extern const char *__progname; 6 | 7 | static int (*orig_BSAuditTokenTaskHasEntitlement)(id connection, NSString *entitlement); 8 | static int hax_BSAuditTokenTaskHasEntitlement(__unsafe_unretained id connection, __unsafe_unretained NSString *entitlement) 9 | { 10 | if ([entitlement isEqualToString:@"com.apple.multitasking.unlimitedassertions"]) 11 | { 12 | // We could check if the connection's pid matches SpringBoard's pid, but at this point I don't think it really matters 13 | // I mean, what could be the worst thing a process can do by making BKSProcessAssertions? slaughtering battery? suspending/keeping apps running? 14 | return true; 15 | } 16 | 17 | return orig_BSAuditTokenTaskHasEntitlement(connection, entitlement); 18 | } 19 | 20 | %ctor 21 | { 22 | // We can never be too sure 23 | if (strcmp(__progname, "assertiond") == 0) 24 | { 25 | dlopen("/System/Library/PrivateFrameworks/XPCObjects.framework/XPCObjects", RTLD_LAZY); 26 | void *xpcFunction = MSFindSymbol(NULL, "_BSAuditTokenTaskHasEntitlement"); 27 | MSHookFunction(xpcFunction, (void *)hax_BSAuditTokenTaskHasEntitlement, (void **)&orig_BSAuditTokenTaskHasEntitlement); 28 | } 29 | } -------------------------------------------------------------------------------- /reachappbackboarddhooks/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | CFLAGS = -I../Messaging/ 3 | #CFLAGS += -fno-objc-arc 4 | LDFLAGS += -Wl,-segalign,4000 5 | 6 | include $(THEOS)/makefiles/common.mk 7 | 8 | TWEAK_NAME = ReachAppBackboarddHooks 9 | ReachAppBackboarddHooks_FILES = Tweak.xm 10 | ReachAppBackboarddHooks_LIBRARIES = IOKit 11 | 12 | include $(THEOS_MAKE_PATH)/tweak.mk 13 | 14 | after-install:: 15 | install.exec "killall -9 SpringBoard" 16 | -------------------------------------------------------------------------------- /reachappbackboarddhooks/ReachAppBackboarddHooks.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Executables = ( "backboardd" ); }; } 2 | -------------------------------------------------------------------------------- /reachappfakephonemode/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | 3 | CFLAGS = -I../ -I../Theming 4 | LDFLAGS += -Wl,-segalign,4000 5 | 6 | include $(THEOS)/makefiles/common.mk 7 | 8 | TWEAK_NAME = ReachAppFakePhoneMode 9 | ReachAppFakePhoneMode_FILES = Tweak.xm 10 | ReachAppFakePhoneMode_FRAMEWORKS = UIKit CoreGraphics 11 | 12 | include $(THEOS_MAKE_PATH)/tweak.mk 13 | 14 | after-install:: 15 | install.exec "killall -9 SpringBoard" 16 | -------------------------------------------------------------------------------- /reachappfakephonemode/ReachAppFakePhoneMode.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.i.dont.exist.xxxxxx" ); }; } 2 | -------------------------------------------------------------------------------- /reachappfakephonemode/Tweak.xm: -------------------------------------------------------------------------------- 1 | #import "RAFakePhoneMode.h" 2 | 3 | #define FAKE \ 4 | \//if (IS_SPRINGBOARD || ignorePhoneMode) \ 5 | \// return %orig; \ 6 | \ 7 | if ([%c(RAFakePhoneMode) shouldFakeForThisProcess]) \ 8 | { \ 9 | CGRect frame = (CGRect) { CGPointZero, [%c(RAFakePhoneMode) fakedSize] }; \ 10 | return frame; \ 11 | } 12 | 13 | %hook UIDevice 14 | -(UIUserInterfaceIdiom) userInterfaceIdiom 15 | { 16 | UIUserInterfaceIdiom origIdiom = %orig; 17 | 18 | //if (IS_SPRINGBOARD || ignorePhoneMode) 19 | // return origIdiom; 20 | 21 | if (origIdiom != UIUserInterfaceIdiomPhone && [%c(RAFakePhoneMode) shouldFakeForThisProcess]) 22 | return UIUserInterfaceIdiomPhone; 23 | 24 | return origIdiom; 25 | } 26 | %end 27 | 28 | %hook UIScreen 29 | - (CGRect)_unjailedReferenceBounds 30 | { 31 | FAKE; 32 | return %orig; 33 | } 34 | 35 | - (CGRect)_referenceBounds 36 | { 37 | FAKE; 38 | return %orig; 39 | } 40 | 41 | - (CGRect)_interfaceOrientedBounds 42 | { 43 | FAKE; 44 | return %orig; 45 | } 46 | 47 | - (CGRect)bounds 48 | { 49 | FAKE; 50 | return %orig; 51 | } 52 | 53 | - (CGRect)nativeBounds 54 | { 55 | FAKE; 56 | return %orig; 57 | } 58 | 59 | - (CGRect)applicationFrame 60 | { 61 | FAKE; 62 | return %orig; 63 | } 64 | 65 | - (CGRect)_boundsForInterfaceOrientation:(int)arg1 66 | { 67 | FAKE; 68 | return %orig; 69 | } 70 | 71 | - (CGRect)_applicationFrameForInterfaceOrientation:(int)arg1 usingStatusbarHeight:(CGFloat)arg2 ignoreStatusBar:(BOOL)arg3 72 | { 73 | FAKE; 74 | return %orig; 75 | } 76 | 77 | - (CGRect)_applicationFrameForInterfaceOrientation:(int)arg1 usingStatusbarHeight:(CGFloat)arg2 78 | { 79 | FAKE; 80 | return %orig; 81 | } 82 | 83 | - (CGRect)_applicationFrameForInterfaceOrientation:(int)arg1 84 | { 85 | FAKE; 86 | return %orig; 87 | } 88 | %end 89 | -------------------------------------------------------------------------------- /reachappflipswitch/FSSwitchState.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef enum { 4 | FSSwitchStateOff = 0, 5 | FSSwitchStateOn = 1, 6 | FSSwitchStateIndeterminate = -1 7 | } FSSwitchState; 8 | 9 | extern NSString *NSStringFromFSSwitchState(FSSwitchState state); 10 | extern FSSwitchState FSSwitchStateFromNSString(NSString *stateString); 11 | -------------------------------------------------------------------------------- /reachappflipswitch/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | include $(THEOS)/makefiles/common.mk 3 | 4 | BUNDLE_NAME = ReachAppFlipswitch 5 | ReachAppFlipswitch_FILES = Switch.x 6 | ReachAppFlipswitch_FRAMEWORKS = UIKit 7 | ReachAppFlipswitch_LIBRARIES = flipswitch 8 | ReachAppFlipswitch_INSTALL_PATH = /Library/Switches 9 | 10 | include $(THEOS_MAKE_PATH)/bundle.mk -------------------------------------------------------------------------------- /reachappflipswitch/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ReachAppFlipswitch 9 | CFBundleIdentifier 10 | com.efrederickson.reachapp.flipswitch 11 | CFBundleDisplayName 12 | Multiplexer 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | DTPlatformName 24 | iphoneos 25 | MinimumOSVersion 26 | 3.0 27 | NSPrincipalClass 28 | ReachAppFlipswitchSwitch 29 | alternate-action-url 30 | prefs: 31 | 32 | -------------------------------------------------------------------------------- /reachappflipswitch/Resources/glyph.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappflipswitch/Resources/glyph.pdf -------------------------------------------------------------------------------- /reachappflipswitch/Switch.x: -------------------------------------------------------------------------------- 1 | #import "FSSwitchDataSource.h" 2 | #import "FSSwitchPanel.h" 3 | #import 4 | 5 | @interface ReachAppFlipswitchSwitch : NSObject 6 | @end 7 | 8 | @implementation ReachAppFlipswitchSwitch 9 | 10 | - (FSSwitchState)stateForSwitchIdentifier:(NSString *)switchIdentifier 11 | { 12 | Boolean keyExistsAndHasValidFormat; 13 | BOOL enabled = CFPreferencesGetAppBooleanValue(CFSTR("enabled"), CFSTR("com.efrederickson.reachapp.settings"), &keyExistsAndHasValidFormat); 14 | 15 | return enabled ? FSSwitchStateOn : FSSwitchStateOff; 16 | } 17 | 18 | - (void)applyState:(FSSwitchState)newState forSwitchIdentifier:(NSString *)switchIdentifier 19 | { 20 | if (newState == FSSwitchStateIndeterminate) 21 | return; 22 | 23 | CFPreferencesSetAppValue(CFSTR("enabled"), (CFPropertyListRef)(newState == FSSwitchStateOn ? @YES : @NO), CFSTR("com.efrederickson.reachapp.settings")); 24 | notify_post("com.efrederickson.reachapp.settings/reloadSettings"); 25 | } 26 | 27 | @end -------------------------------------------------------------------------------- /reachappfsdaemon/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | CFLAGS = -I../ -I../Theming 3 | LDFLAGS += -Wl,-segalign,4000 4 | 5 | include $(THEOS)/makefiles/common.mk 6 | 7 | TOOL_NAME = ReachAppFSDaemon 8 | ReachAppFSDaemon_FILES = main.mm 9 | ReachAppFSDaemon_PRIVATE_FRAMEWORKS = Foundation MobileCoreServices 10 | 11 | include $(THEOS_MAKE_PATH)/tool.mk 12 | -------------------------------------------------------------------------------- /reachappfsdaemon/main.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #import 6 | #import "headers.h" 7 | #import 8 | 9 | int main(int argc, char **argv, char **envp) { 10 | NSAutoreleasePool *pool = [NSAutoreleasePool new]; 11 | 12 | NSString *filePath = @"/var/mobile/Library/.reachapp.uiappexitsonsuspend.wantstochangerootapp"; 13 | if ([NSFileManager.defaultManager fileExistsAtPath:filePath] == NO) 14 | { 15 | NSLog(@"[ReachApp] FS Daemon: plist does not exist"); 16 | return 0; 17 | } 18 | 19 | NSDictionary *contents = [NSDictionary dictionaryWithContentsOfFile:filePath]; 20 | 21 | LSApplicationProxy *appInfo = [objc_getClass("LSApplicationProxy") applicationProxyForIdentifier:contents[@"bundleIdentifier"]]; 22 | NSString *path = [NSString stringWithFormat:@"%@/Info.plist",appInfo.bundleURL.absoluteString]; 23 | NSMutableDictionary *infoPlist = [NSMutableDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:path]]; 24 | infoPlist[@"UIApplicationExitsOnSuspend"] = contents[@"UIApplicationExitsOnSuspend"]; 25 | BOOL success = [infoPlist writeToURL:[NSURL URLWithString:path] atomically:YES]; 26 | 27 | if (!success) 28 | NSLog(@"[ReachApp] FS Daemon: error writing to plist: %@", path); 29 | else 30 | [NSFileManager.defaultManager removeItemAtPath:filePath error:nil]; 31 | 32 | [pool release]; 33 | return 0; 34 | } -------------------------------------------------------------------------------- /reachappsettings/BackgroundPerAppDetailsController.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import 3 | 4 | @interface RABGPerAppDetailsController : SKTintedListController 5 | { 6 | NSString* _appName; 7 | NSString* _identifier; 8 | } 9 | -(id)initWithAppName:(NSString*)appName identifier:(NSString*)identifier; 10 | @end -------------------------------------------------------------------------------- /reachappsettings/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 armv7s arm64 2 | TARGET = iPhone:clang:latest:latest 3 | CFLAGS = -fobjc-arc -I../ -I../Backgrounding/ -I../Theming/ -I../NotificationCenterApp 4 | LDFLAGS = -F$(THEOS)/frameworks 5 | LDFLAGS += -Wl,-segalign,4000 6 | 7 | include $(THEOS)/makefiles/common.mk 8 | 9 | BUNDLE_NAME = ReachAppSettings 10 | ReachAppSettings_FILES = ReachAppSettings.mm $(shell find $(THEOS)/include/SettingsKit -name '*.m') $(wildcard *.xm) RAHeaderView.mm ../PDFImageOptions.m ../PDFImage.m ../RALocalizer.mm ../RASettings.mm $(wildcard ../Theming/*.mm) 11 | ReachAppSettings_INSTALL_PATH = /Library/PreferenceBundles 12 | ReachAppSettings_FRAMEWORKS = UIKit MessageUI Social QuartzCore CoreGraphics 13 | ReachAppSettings_LIBRARIES = applist substrate 14 | ReachAppSettings_PRIVATE_FRAMEWORKS = Preferences 15 | 16 | include $(THEOS_MAKE_PATH)/bundle.mk 17 | 18 | internal-stage:: 19 | $(ECHO_NOTHING)rsync -a -v --ignore-existing $(THEOS)/include/SettingsKit/Resources/*.png $(THEOS_STAGING_DIR)/Library/PreferenceBundles/ReachAppSettings.bundle/$(ECHO_END) 20 | $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) 21 | $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/ReachAppSettings.plist$(ECHO_END) 22 | -------------------------------------------------------------------------------- /reachappsettings/RAHeaderView.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAHeaderView : UIView { 4 | UILabel *label; 5 | UIImageView *imageView; 6 | } 7 | @property (nonatomic) CGBlendMode blendMode; 8 | @property (nonatomic) BOOL shouldBlend; 9 | -(void) setColors:(NSArray*)colors; 10 | -(void) setTitle:(NSString*)title; 11 | -(void) setImage:(UIImage*)image; 12 | @end -------------------------------------------------------------------------------- /reachappsettings/Resources/Andi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Andi.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Andi@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Andi@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Andi@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Andi@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/BackgrounderHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/BackgrounderHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/Binders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Binders.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Binders@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Binders@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Binders@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Binders@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Chon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Chon.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Chon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Chon@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Chon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Chon@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/David.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/David.png -------------------------------------------------------------------------------- /reachappsettings/Resources/David@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/David@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/David@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/David@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/EmpoleonHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/EmpoleonHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/EthanArbuckle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/EthanArbuckle.png -------------------------------------------------------------------------------- /reachappsettings/Resources/EthanArbuckle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/EthanArbuckle@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/EthanArbuckle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/EthanArbuckle@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ReachAppSettings 9 | CFBundleIdentifier 10 | com.efrederickson.reachapp.settings 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 | ReachAppSettingsListController 27 | 28 | 29 | -------------------------------------------------------------------------------- /reachappsettings/Resources/Jack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Jack.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Jack@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Jack@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Jack@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Jack@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/MainHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/MainHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/MissionControlHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/MissionControlHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/Moshe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Moshe.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Moshe@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Moshe@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Moshe@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Moshe@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Multiplexer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Multiplexer.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Multiplexer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Multiplexer@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Multiplexer@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Multiplexer@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/NCAppHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/NCAppHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/ReachAppHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ReachAppHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/Reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Reset.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Reset@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Reset@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Reset@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Reset@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/SharedRoutine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/SharedRoutine.png -------------------------------------------------------------------------------- /reachappsettings/Resources/SharedRoutine@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/SharedRoutine@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/SharedRoutine@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/SharedRoutine@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/SwipeOverHeader.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/SwipeOverHeader.pdf -------------------------------------------------------------------------------- /reachappsettings/Resources/Wilson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Wilson.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Wilson@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Wilson@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Wilson@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Wilson@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Ziphon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Ziphon.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Ziphon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Ziphon@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/Ziphon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/Ziphon@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/andrew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/andrew.png -------------------------------------------------------------------------------- /reachappsettings/Resources/andrew@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/andrew@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/andrew@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/andrew@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/aura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/aura.png -------------------------------------------------------------------------------- /reachappsettings/Resources/aura@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/aura@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/aura@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/aura@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/beta382.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/beta382.png -------------------------------------------------------------------------------- /reachappsettings/Resources/beta382@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/beta382@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/beta382@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/beta382@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/elijah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/elijah.png -------------------------------------------------------------------------------- /reachappsettings/Resources/elijah@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/elijah@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/elijah@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/elijah@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/empoleon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/empoleon.png -------------------------------------------------------------------------------- /reachappsettings/Resources/empoleon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/empoleon@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/empoleon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/empoleon@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/github.png -------------------------------------------------------------------------------- /reachappsettings/Resources/github@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/github@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/github@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/github@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/missioncontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/missioncontrol.png -------------------------------------------------------------------------------- /reachappsettings/Resources/missioncontrol@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/missioncontrol@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/missioncontrol@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/missioncontrol@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/quickaccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/quickaccess.png -------------------------------------------------------------------------------- /reachappsettings/Resources/quickaccess@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/quickaccess@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/quickaccess@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/quickaccess@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_enabled.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_enabled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_enabled@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_enabled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_enabled@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_makers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_makers.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_makers@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_makers@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_makers@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_makers@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_support.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_support.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_support@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_support@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/ra_support@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/ra_support@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/reachapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/reachapp.png -------------------------------------------------------------------------------- /reachappsettings/Resources/reachapp@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/reachapp@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/reachapp@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/reachapp@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/swipeover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/swipeover.png -------------------------------------------------------------------------------- /reachappsettings/Resources/swipeover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/swipeover@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/swipeover@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/swipeover@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/theme.png -------------------------------------------------------------------------------- /reachappsettings/Resources/theme@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/theme@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/theme@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/theme@3x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/tutorial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/tutorial.png -------------------------------------------------------------------------------- /reachappsettings/Resources/tutorial@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/tutorial@2x.png -------------------------------------------------------------------------------- /reachappsettings/Resources/tutorial@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/reachappsettings/Resources/tutorial@3x.png -------------------------------------------------------------------------------- /reachappsettings/entry.plist: -------------------------------------------------------------------------------- 1 | { 2 | entry = { 3 | bundle = ReachAppSettings; 4 | cell = PSLinkCell; 5 | detail = ReachAppSettingsListController; 6 | icon = Multiplexer.png; 7 | isController = 1; 8 | label = Multiplexer; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /update_status: -------------------------------------------------------------------------------- 1 | update status: 2 | 3 | Windowed: working 4 | fs daemon: working 5 | SwipeOver: working (replace with native slide over(?)) 6 | Reachability: fixed 7 | GestureSupport: fixed 8 | Backgrounding: fixed 9 | KeyboardSupport: hackily fixed but it works now 10 | MissionControl: initialization broken, otherwise fixed 11 | NCApp: fixed on phone, not working right on ipad (misplaced view & no title) 12 | assertiond hooks: unknown 13 | backboardd hooks: unknown 14 | fake phone mode: working 15 | 16 | 17 | - adding items to SBAppSwitcherModel is broken 18 | - SwipeOver sliding off screen animation is broken (RASwipeOverManager.xm:L62) 19 | - icons and apps do not show up in RASnapshotProvider 20 | - GestureSupport: LandscapeLeft is, once again, broken 21 | 22 | notes: 23 | use _referenceBounds instead of bounds on UIScreen to get physical bounds. Makes landscape support easier? 24 | -------------------------------------------------------------------------------- /widgets/Core/RAReachabilityWidgetShim.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/widgets/Core/RAReachabilityWidgetShim.h -------------------------------------------------------------------------------- /widgets/Core/RAReachabilityWidgetShim.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/efrederickson/Multiplexer/eec24acc7c8883d0305f1d8f14af2ccaa08f1d95/widgets/Core/RAReachabilityWidgetShim.xm -------------------------------------------------------------------------------- /widgets/Core/RAWidgetBase.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | 3 | @interface RAWidgetBase : UIView 4 | -(NSString*) identifier; 5 | -(NSString*) displayName; 6 | 7 | -(void) didAppear; 8 | -(void) didDisappear; 9 | @end -------------------------------------------------------------------------------- /widgets/Core/RAWidgetBase.xm: -------------------------------------------------------------------------------- 1 | #import "RAWidgetBase.h" 2 | 3 | @implementation RAWidgetBase 4 | -(NSString*) identifier { return nil; } 5 | -(NSString*) displayName { return nil; } 6 | 7 | -(void) didAppear 8 | { 9 | 10 | } 11 | 12 | -(void) didDisappear 13 | { 14 | 15 | } 16 | @end -------------------------------------------------------------------------------- /widgets/Core/RAWidgetHostManager.h: -------------------------------------------------------------------------------- 1 | #import "headers.h" 2 | #import "RAWidgetBase.h" 3 | 4 | @interface RAWidgetHostManager : NSObject { 5 | NSMutableArray *widgets; 6 | } 7 | +(id) sharedInstance; 8 | 9 | -(void) addWidget:(RAWidgetBase*)widget; 10 | -(void) removeWidget:(RAWidgetBase*)widget; 11 | -(void) removeWidgetWithIdentifier:(NSString*)identifier; 12 | -(RAWidgetBase*) widgetForIdentifier:(NSString*)identifier; 13 | @end -------------------------------------------------------------------------------- /widgets/Core/RAWidgetHostManager.xm: -------------------------------------------------------------------------------- 1 | #import "RAWidgetHostManager.h" 2 | 3 | @implementation RAWidgetHostManager 4 | +(id) sharedInstance 5 | { 6 | SHARED_INSTANCE2(RAWidgetHostManager, sharedInstance->widgets = [NSMutableArray array]); 7 | } 8 | 9 | -(void) addWidget:(RAWidgetBase*)widget 10 | { 11 | if ([widgets containsObject:widget] == NO) 12 | [widgets addObject:widget]; 13 | } 14 | 15 | -(void) removeWidget:(RAWidgetBase*)widget 16 | { 17 | [self removeWidgetWithIdentifier:widget.identifier]; 18 | } 19 | 20 | -(void) removeWidgetWithIdentifier:(NSString*)identifier 21 | { 22 | for (RAWidgetBase *w in widgets) 23 | { 24 | if ([w.identifier isEqual:identifier]) 25 | { 26 | [widgets removeObject:w]; 27 | return; 28 | } 29 | } 30 | } 31 | 32 | -(RAWidgetBase*) widgetForIdentifier:(NSString*)identifier 33 | { 34 | for (RAWidgetBase *w in widgets) 35 | { 36 | if ([w.identifier isEqual:identifier]) 37 | { 38 | return w; 39 | } 40 | } 41 | return nil; 42 | } 43 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RAAllAppsWidget.h: -------------------------------------------------------------------------------- 1 | #import "RAWidgetSection.h" 2 | 3 | @interface RAAllAppsWidget : RAWidgetSection 4 | 5 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RADefaultWidgetSection.h: -------------------------------------------------------------------------------- 1 | #import "RAWidgetSection.h" 2 | #import "RAWidget.h" 3 | 4 | @interface RADefaultWidgetSection : RAWidgetSection 5 | +(id) sharedDefaultWidgetSection; 6 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RADefaultWidgetSection.mm: -------------------------------------------------------------------------------- 1 | #import "RADefaultWidgetSection.h" 2 | #import "RAWidget.h" 3 | #import "RAWidgetSectionManager.h" 4 | #import "headers.h" 5 | 6 | @implementation RADefaultWidgetSection 7 | +(id) sharedDefaultWidgetSection 8 | { 9 | SHARED_INSTANCE2(RADefaultWidgetSection, [[RAWidgetSectionManager sharedInstance] registerSection:sharedInstance]); 10 | } 11 | 12 | -(NSString*) displayName 13 | { 14 | return LOCALIZE(@"WIDGETS"); 15 | } 16 | 17 | -(NSString*) identifier 18 | { 19 | return @"com.efrederickson.reachapp.widgets.sections.default"; 20 | } 21 | @end 22 | 23 | static __attribute__((constructor)) void cant_believe_i_forgot_this_before() 24 | { 25 | static id _widget = [RADefaultWidgetSection sharedDefaultWidgetSection]; 26 | [RAWidgetSectionManager.sharedInstance registerSection:_widget]; 27 | } -------------------------------------------------------------------------------- /widgets/Reachability/RAFavoriteAppsWidget.h: -------------------------------------------------------------------------------- 1 | #import "RAWidgetSection.h" 2 | 3 | @interface RAFavoriteAppsWidget : RAWidgetSection 4 | 5 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RARecentAppsWidget.h: -------------------------------------------------------------------------------- 1 | #import "RAWidgetSection.h" 2 | 3 | @interface RARecentAppsWidget : RAWidgetSection 4 | 5 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RAWidget.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RAWidget : NSObject 4 | 5 | -(NSString*) identifier; 6 | 7 | // actual view for showing in Reachability 8 | -(UIView*) view; 9 | 10 | // Similar to an app icon with the image/title 11 | -(UIView*) iconForSize:(CGSize)size; 12 | 13 | -(CGFloat) preferredHeight; 14 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RAWidget.mm: -------------------------------------------------------------------------------- 1 | #import "RAWidget.h" 2 | 3 | @implementation RAWidget 4 | 5 | -(NSString*)identifier 6 | { 7 | @throw @"This is an abstract method and must be overriden"; 8 | } 9 | 10 | -(UIView*) view 11 | { 12 | @throw @"This is an abstract method and must be overriden"; 13 | } 14 | 15 | -(UIView*) iconForSize:(CGSize)size 16 | { 17 | @throw @"This is an abstract method and must be overriden"; 18 | } 19 | 20 | -(CGFloat) preferredHeight 21 | { 22 | return self.view.frame.size.height; 23 | } 24 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RAWidgetSection.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAWidget.h" 3 | 4 | @interface RAWidgetSection : NSObject { 5 | NSMutableArray *_widgets; 6 | } 7 | 8 | -(BOOL) enabled; 9 | 10 | -(NSInteger) sortOrder; 11 | -(BOOL) showTitle; 12 | -(NSString*) displayName; 13 | -(NSString*) identifier; 14 | -(CGFloat) titleOffset; 15 | 16 | // The view should cache, if possible, to speed up loading times. 17 | // It should NOT show the title view. 18 | -(UIView*) viewForFrame:(CGRect)frame preferredIconSize:(CGSize)size iconsThatFitPerLine:(NSInteger)iconsPerLine spacing:(CGFloat)spacing; 19 | 20 | -(void) addWidget:(RAWidget*)widget; 21 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RAWidgetSection.mm: -------------------------------------------------------------------------------- 1 | #import "RAWidgetSection.h" 2 | #import "RAReachabilityManager.h" 3 | 4 | @implementation RAWidgetSection 5 | 6 | -(id) init 7 | { 8 | if (self = [super init]) 9 | { 10 | _widgets = [NSMutableArray array]; 11 | } 12 | return self; 13 | } 14 | 15 | -(BOOL) enabled { return _widgets.count > 0; } 16 | -(BOOL) showTitle { return YES; } 17 | 18 | -(NSInteger) sortOrder { return 10; } 19 | 20 | -(NSString*) displayName 21 | { 22 | @throw @"This is an abstract method and should be overriden."; 23 | } 24 | 25 | -(NSString*) identifier 26 | { 27 | @throw @"This is an abstract method and should be overriden."; 28 | } 29 | 30 | -(void) addWidget:(RAWidget*)widget 31 | { 32 | [_widgets addObject:widget]; 33 | } 34 | 35 | -(UIView*) viewForFrame:(CGRect)frame preferredIconSize:(CGSize)size iconsThatFitPerLine:(NSInteger)iconsPerLine spacing:(CGFloat)spacing 36 | { 37 | UIView *view = [[UIView alloc] initWithFrame:frame]; 38 | view.userInteractionEnabled = YES; 39 | CGPoint origin = CGPointMake(10, 10); 40 | 41 | for (NSInteger index = 0; index < _widgets.count; index++) 42 | { 43 | RAWidget *widget = _widgets[index]; 44 | 45 | UIView *subView = [widget iconForSize:size]; 46 | subView.clipsToBounds = YES; 47 | subView.backgroundColor = [UIColor clearColor]; 48 | 49 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(widgetIconTap:)]; 50 | [subView addGestureRecognizer:tap]; 51 | subView.tag = index; 52 | subView.userInteractionEnabled = YES; 53 | 54 | CGRect frame = subView.frame; 55 | frame.origin = origin; 56 | subView.frame = frame; 57 | origin.x += frame.size.width + spacing; 58 | 59 | [view addSubview:subView]; 60 | } 61 | return view; 62 | } 63 | 64 | -(void) widgetIconTap:(UITapGestureRecognizer*)gesture 65 | { 66 | NSInteger widgetIndex = gesture.view.tag; 67 | [[RAReachabilityManager sharedInstance] launchWidget:_widgets[widgetIndex]]; 68 | } 69 | 70 | -(CGFloat) titleOffset 71 | { 72 | return 10; 73 | } 74 | @end -------------------------------------------------------------------------------- /widgets/Reachability/RAWidgetSectionManager.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "RAWidgetSection.h" 3 | 4 | @interface RAWidgetSectionManager : NSObject { 5 | NSMutableDictionary *_sections; 6 | } 7 | 8 | +(instancetype) sharedInstance; 9 | 10 | -(void) registerSection:(RAWidgetSection*)section; 11 | 12 | -(NSArray*) sections; 13 | -(NSArray*) enabledSections; 14 | 15 | -(UIView*) createViewForEnabledSectionsWithBaseFrame:(CGRect)frame preferredIconSize:(CGSize)size iconsThatFitPerLine:(NSInteger)iconsPerLine spacing:(CGFloat)spacing; 16 | @end --------------------------------------------------------------------------------