├── .DS_Store ├── .gitignore ├── Chapters.mm ├── Chapters.plist ├── Chapters.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── kritanta.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── xcschemes │ │ └── xcschememanagement.plist └── xcuserdata │ └── kritanta.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── Chapters ├── CHPLabelDelegate.h ├── CHPManager.h ├── CHPManager.m ├── CHPPageLabelView.h └── CHPPageLabelView.m ├── DragonMake ├── HomePlus.plist ├── LICENSE ├── Prefs.plist ├── README.md ├── build.ninja ├── icon@2x.png └── include ├── SpringBoardHome.h └── substrate.h /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kritanta-ios-tweaks/Chapters/37f70502cbd2f145d3c8648e54caf269c09bc0c2/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | Products/ 3 | .dragon/ 4 | packages/ 5 | .theos/ 6 | -------------------------------------------------------------------------------- /Chapters.mm: -------------------------------------------------------------------------------- 1 | // 2 | // Chapters.mm | Substrate hooks to get the tweak integrated cleanly. 3 | // Chapters 4 | // 5 | // Add some clean labels to your pages 6 | // 7 | // Created by _kritanta 8 | // 9 | //05 10 | 11 | @import UIKit; 12 | 13 | #include "include/SpringBoardHome.h" 14 | #include "Chapters/CHPManager.h" 15 | 16 | #import 17 | #include "substrate.h" 18 | 19 | @class SBRootFolderController; 20 | @class SBRootIconListView; 21 | @class SBHomeScreenPreviewView; 22 | @class _UIStatusBar; 23 | @class SBIconListView; 24 | 25 | static void (*orig_UISB_setForegroundColor) (_UIStatusBar *, SEL, UIColor *); 26 | static void hooked_UISB_setForegroundColor (_UIStatusBar *, SEL, UIColor *); 27 | 28 | static struct CGPoint (*orig_12_SBRILV_originForIconAtCoordinate) (SBRootIconListView *, SEL, SBIconCoordinate, struct SBIconListLayoutMetrics); 29 | static struct CGPoint hooked_12_SBRILV_originForIconAtCoordinate (SBRootIconListView *, SEL, SBIconCoordinate, struct SBIconListLayoutMetrics); 30 | 31 | static void (*orig_SBILV_layoutIconsNow) (SBIconListView *, SEL); 32 | static void hooked_SBILV_layoutIconsNow (SBIconListView *, SEL); 33 | 34 | static struct CGPoint (*orig_SBILV_originForIconAtCoordinate$metrics) (SBIconListView *, SEL, SBIconCoordinate, struct SBIconListLayoutMetrics); 35 | static struct CGPoint hooked_SBILV_originForIconAtCoordinate$metrics (SBIconListView *, SEL, SBIconCoordinate, struct SBIconListLayoutMetrics); 36 | 37 | static void (*orig_SBRFC_viewWillAppear) (SBRootFolderController *, SEL, BOOL); 38 | static void hooked_SBRFC_viewWillAppear (SBRootFolderController *, SEL, BOOL); 39 | 40 | static void *observer = NULL; 41 | 42 | /** 43 | * [_UIStatusBar setForegroundColor:] 44 | * 45 | * iOS already has logic to detect a nice foreground color. 46 | * I can look at directly using it later, but for now, it's nice to just 47 | * snipe the color when apple uses it. 48 | * 49 | * @param color Color for the status bar foreground text and glyphs 50 | * @return void 51 | */ 52 | static void hooked_UISB_setForegroundColor (_UIStatusBar *self, SEL cmd, UIColor *color) 53 | { 54 | [[CHPManager sharedInstance] setLabelColor:color]; 55 | orig_UISB_setForegroundColor(self, cmd, color); 56 | [[CHPManager sharedInstance] relayoutIfNeeded]; 57 | } 58 | 59 | /** 60 | * -[SBRootIconListView originForIconAtCoordinate:metrics:] 61 | * 62 | * Handy little method for manually manipulating icon origin 63 | * 64 | * .iconLocation is an int on iOS 12, so this one needs its own hook 65 | * 66 | * @param coordinate Icon Coordinate 67 | * @param metrics Layout Metrics 68 | * @return CGPoint origin for icon specified 69 | */ 70 | static struct CGPoint hooked_12_SBRILV_originForIconAtCoordinate (SBRootIconListView *self, SEL cmd, 71 | SBIconCoordinate coordinate, struct SBIconListLayoutMetrics metrics) 72 | { 73 | CGPoint o = orig_12_SBRILV_originForIconAtCoordinate(self, cmd, coordinate, metrics); 74 | 75 | o.y += (54 + [[prefs valueForKey:@"BottomMargin"] intValue]+ [[prefs valueForKey:@"TopMargin"] intValue]); 76 | 77 | return o; 78 | } 79 | 80 | /** 81 | * -[SBIconListView layoutIconsNow] 82 | * 83 | * Convenience function added by apple that calls: 84 | * [self setIconsNeedLayout]; 85 | * [self layoutIconsIfNeeded:0.0]; 86 | * 87 | * iOS doesn't use it much, but my layout editing tweaks do, and this lets us update with them dynamically. 88 | * 89 | * @return void 90 | */ 91 | static void hooked_SBILV_layoutIconsNow (SBIconListView *self, SEL cmd) 92 | { 93 | orig_SBILV_layoutIconsNow(self, cmd); 94 | 95 | if (kCFCoreFoundationVersionNumber < 1600 || [self.iconViewProvider class] == objc_getClass("SBHomeScreenPreviewView")) 96 | { 97 | return; 98 | } 99 | 100 | if ([self.iconLocation isEqualToString:@"SBIconLocationRoot"]) 101 | { 102 | if (@available(iOS 14, *)) 103 | self.additionalLayoutInsets = UIEdgeInsetsMake((54 + [[prefs valueForKey:@"BottomMargin"] intValue]+ [[prefs valueForKey:@"TopMargin"] intValue]),0,-(54 + [[prefs valueForKey:@"BottomMargin"] intValue]+ [[prefs valueForKey:@"TopMargin"] intValue]),0); 104 | [[CHPManager sharedInstance] reloadLabelsForRootFolderController:self.iconViewProvider.rootFolderController 105 | index:-1]; 106 | } 107 | } 108 | 109 | /** 110 | * -[SBIconListView originForIconAtCoordinate:metrics:] 111 | * 112 | * Handy little method for manually manipulating icon origin 113 | * 114 | * Should probably perform modifications to self.layout instead, but I need to figure out how to pull that 115 | * off without screwing up layout managers. 116 | * 117 | * @param coordinate Icon Coordinate 118 | * @param metrics Layout Metrics 119 | * @return CGPoint origin for icon specified 120 | */ 121 | static struct CGPoint hooked_SBILV_originForIconAtCoordinate$metrics (SBIconListView *self, SEL cmd, SBIconCoordinate arg1, struct SBIconListLayoutMetrics arg2) 122 | { 123 | CGPoint o = orig_SBILV_originForIconAtCoordinate$metrics(self, cmd, arg1, arg2); 124 | 125 | if ([self.iconViewProvider class] != objc_getClass("SBHomeScreenPreviewView") 126 | && [self.iconLocation isEqualToString:@"SBIconLocationRoot"] 127 | && kCFCoreFoundationVersionNumber > 1600 128 | && kCFCoreFoundationVersionNumber < 1700) 129 | { 130 | o.y += (54 + [[prefs valueForKey:@"BottomMargin"] intValue]+ [[prefs valueForKey:@"TopMargin"] intValue]); 131 | } 132 | 133 | return o; 134 | } 135 | 136 | /** 137 | * -[SBRootFolderController viewWillAppear:] 138 | * 139 | * Load in our labels whenever the root folder controller appears. 140 | * 141 | * @param yes 142 | */ 143 | static void hooked_SBRFC_viewWillAppear (SBRootFolderController *self, SEL cmd, BOOL yes) 144 | { 145 | orig_SBRFC_viewWillAppear(self, cmd, yes); 146 | 147 | @try 148 | { 149 | [[CHPManager sharedInstance] reloadLabelsForRootFolderController:self index:-1]; 150 | } 151 | @catch (NSException *ex) 152 | { 153 | return; 154 | } 155 | } 156 | 157 | static void preferencesChanged() 158 | { 159 | [[CHPManager sharedInstance] reloadLabelsForRootFolderController:[[[objc_getClass("SBIconController") sharedInstance] iconManager] rootFolderController] index:-1]; 160 | [[NSNotificationCenter defaultCenter] postNotificationName:@"HPLayoutIconViews" object:nil]; 161 | } 162 | 163 | static __attribute__((constructor)) void ChaptersInit (int argc, char **argv, char **envp) 164 | { 165 | NSLog(@"Chapters: Injected"); 166 | 167 | prefs = [[NSUserDefaults alloc] initWithSuiteName:@"me.kritanta.chapters"]; 168 | 169 | if ([prefs valueForKey:@"TopMargin"] == nil) 170 | [prefs setValue:0 forKey:@"TopMargin"]; 171 | if ([prefs valueForKey:@"BottomMargin"] == nil) 172 | [prefs setValue:0 forKey:@"BottomMargin"]; 173 | 174 | MSHookMessageEx(objc_getClass("SBRootFolderController"), 175 | @selector(viewWillAppear:), 176 | (IMP) &hooked_SBRFC_viewWillAppear, 177 | (IMP *) &orig_SBRFC_viewWillAppear); 178 | 179 | MSHookMessageEx(objc_getClass("SBRootIconListView"), 180 | @selector(originForIconAtCoordinate:metrics:), 181 | (IMP) &hooked_12_SBRILV_originForIconAtCoordinate, 182 | (IMP *) &orig_12_SBRILV_originForIconAtCoordinate); 183 | 184 | MSHookMessageEx(objc_getClass("SBIconListView"), 185 | @selector(layoutIconsNow), 186 | (IMP) &hooked_SBILV_layoutIconsNow, 187 | (IMP *) &orig_SBILV_layoutIconsNow); 188 | 189 | if (kCFCoreFoundationVersionNumber < 1700) 190 | MSHookMessageEx(objc_getClass("SBIconListView"), 191 | @selector(originForIconAtCoordinate:metrics:), 192 | (IMP) &hooked_SBILV_originForIconAtCoordinate$metrics, 193 | (IMP *) &orig_SBILV_originForIconAtCoordinate$metrics); 194 | 195 | MSHookMessageEx(objc_getClass("_UIStatusBar"), 196 | @selector(setForegroundColor:), 197 | (IMP) &hooked_UISB_setForegroundColor, 198 | (IMP *) &orig_UISB_setForegroundColor); 199 | 200 | CFNotificationCenterAddObserver( 201 | CFNotificationCenterGetDarwinNotifyCenter(), 202 | &observer, 203 | (CFNotificationCallback)preferencesChanged, 204 | (CFStringRef)@"me.krit.chapters/prefs", 205 | NULL, 206 | CFNotificationSuspensionBehaviorDeliverImmediately 207 | ); 208 | } 209 | -------------------------------------------------------------------------------- /Chapters.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Executables = ( "SpringBoard" ); }; } 2 | -------------------------------------------------------------------------------- /Chapters.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B36163EC7ED6600241098844 /* CHPManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B3616C85EC7E40E8014EB435 /* CHPManager.m */; }; 11 | B361655335221B47937F4CE7 /* CHPPageLabelView.m in Sources */ = {isa = PBXBuildFile; fileRef = B3616D13B1C5EFE0C707F4BA /* CHPPageLabelView.m */; }; 12 | B361671068BF9B58CC936496 /* Chapters.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3616369A63AE1CD196A4C39 /* Chapters.mm */; }; 13 | B3616EA25D2A930E2BBB4370 /* Chapters.xm.mm in Sources */ = {isa = PBXBuildFile; fileRef = B36162B9ABFEF0DF3827E38E /* Chapters.xm.mm */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXBuildRule section */ 17 | 5FBB363824651D87007A485A /* PBXBuildRule */ = { 18 | isa = PBXBuildRule; 19 | compilerSpec = com.apple.compilers.proxy.script; 20 | filePatterns = .xm; 21 | fileType = pattern.proxy; 22 | inputFiles = ( 23 | ); 24 | isEditable = 1; 25 | outputFiles = ( 26 | "$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).mm", 27 | ); 28 | script = "mkdir -p .dragon/logos\n$DRAGONBUILD/bin/logos.pl ${INPUT_FILE_PATH} > ${DERIVED_FILE_DIR}/${INPUT_FILE_BASE}.xm.mm\n"; 29 | }; 30 | /* End PBXBuildRule section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 5FBB362F24651C92007A485A /* Chapters.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Chapters.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | B36160011937A9C509DFB4F4 /* .ninja_log */ = {isa = PBXFileReference; lastKnownFileType = file.ninja_log; path = .ninja_log; sourceTree = ""; }; 35 | B3616154E6FD96D27D223E20 /* CHPPageLabelView.m.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = CHPPageLabelView.m.o; sourceTree = ""; }; 36 | B36161F9758ACE4A74486267 /* Chapters.xm.mm.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = Chapters.xm.mm.o; sourceTree = ""; }; 37 | B36162042FFDC1B890BA2426 /* build.ninja */ = {isa = PBXFileReference; lastKnownFileType = file.ninja; path = build.ninja; sourceTree = ""; }; 38 | B361622756164C8A195005BD /* control */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = control; sourceTree = ""; }; 39 | B361622A51ECB259AF128E5F /* last_package */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = last_package; sourceTree = ""; }; 40 | B36162B9ABFEF0DF3827E38E /* Chapters.xm.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Chapters.xm.mm; sourceTree = ""; }; 41 | B3616369A63AE1CD196A4C39 /* Chapters.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Chapters.mm; sourceTree = ""; }; 42 | B361638219441DC3E872F98F /* Chapters.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = Chapters.dylib; sourceTree = ""; }; 43 | B36163CE327BA137A09D4E68 /* Chapters.dylib.unsigned */ = {isa = PBXFileReference; lastKnownFileType = file.unsigned; path = Chapters.dylib.unsigned; sourceTree = ""; }; 44 | B361642D95123CF53B8CBA21 /* Chapters.arm64e */ = {isa = PBXFileReference; lastKnownFileType = file.arm64e; path = Chapters.arm64e; sourceTree = ""; }; 45 | B3616473FE27E9B602FD9117 /* substrate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = substrate.h; sourceTree = ""; }; 46 | B361647BE240844DC806E322 /* CHPPageLabelView.m.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = CHPPageLabelView.m.o; sourceTree = ""; }; 47 | B361660799698E8E68C206FF /* Chapters.arm64 */ = {isa = PBXFileReference; lastKnownFileType = file.arm64; path = Chapters.arm64; sourceTree = ""; }; 48 | B36166AB3C1CF2BE1B4753E2 /* CHPManager.m.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = CHPManager.m.o; sourceTree = ""; }; 49 | B361671BC6A22D60F5880D8B /* CHPLabelDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHPLabelDelegate.h; sourceTree = ""; }; 50 | B36167354EC8181EDAB7751B /* .ninja_deps */ = {isa = PBXFileReference; lastKnownFileType = file.ninja_deps; path = .ninja_deps; sourceTree = ""; }; 51 | B3616868262419BE78C765B0 /* SpringBoardHome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpringBoardHome.h; sourceTree = ""; }; 52 | B36168971A16E6272DF716C7 /* CHPManager.m.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = CHPManager.m.o; sourceTree = ""; }; 53 | B36168FE2DF97819EF7EDF5C /* CHPPageLabelView.m.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = CHPPageLabelView.m.o; sourceTree = ""; }; 54 | B3616985A88AF31B1E20D7B5 /* Chapters.dylib.unsym */ = {isa = PBXFileReference; lastKnownFileType = file.unsym; path = Chapters.dylib.unsym; sourceTree = ""; }; 55 | B36169A18565E292406AAFA0 /* CHPManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHPManager.h; sourceTree = ""; }; 56 | B36169BD03CDEEF82574968B /* CHPManager.m.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = CHPManager.m.o; sourceTree = ""; }; 57 | B36169C680A16B8BD2A0798A /* Chapters.xm.mm.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = Chapters.xm.mm.o; sourceTree = ""; }; 58 | B36169D9DCA9779AAF7B1732 /* DragonMake */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DragonMake; sourceTree = ""; }; 59 | B3616B734561A7F107C7AF96 /* control */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = control; sourceTree = ""; }; 60 | B3616BD7247D3A24B8768860 /* Chapters.armv7 */ = {isa = PBXFileReference; lastKnownFileType = file.armv7; path = Chapters.armv7; sourceTree = ""; }; 61 | B3616C17C3EF2291E6BF0589 /* Chapters.xm.mm.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = Chapters.xm.mm.o; sourceTree = ""; }; 62 | B3616C4FB2269D7D53512771 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 63 | B3616C5C9545727D7D2598D7 /* Chapters.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Chapters.plist; sourceTree = ""; }; 64 | B3616C85EC7E40E8014EB435 /* CHPManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHPManager.m; sourceTree = ""; }; 65 | B3616CE28DC522B976D5AC96 /* CHPPageLabelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHPPageLabelView.h; sourceTree = ""; }; 66 | B3616D13B1C5EFE0C707F4BA /* CHPPageLabelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHPPageLabelView.m; sourceTree = ""; }; 67 | B3616DD0FE1D5F4169AF6AB5 /* Chapters.dylib.unsym */ = {isa = PBXFileReference; lastKnownFileType = file.unsym; path = Chapters.dylib.unsym; sourceTree = ""; }; 68 | B3616F506D1551FCBD18F795 /* Chapters.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Chapters.plist; sourceTree = ""; }; 69 | /* End PBXFileReference section */ 70 | 71 | /* Begin PBXGroup section */ 72 | 5FBB363024651C92007A485A /* Chapters */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | B361671BC6A22D60F5880D8B /* CHPLabelDelegate.h */, 76 | B3616C85EC7E40E8014EB435 /* CHPManager.m */, 77 | B36169A18565E292406AAFA0 /* CHPManager.h */, 78 | B3616D13B1C5EFE0C707F4BA /* CHPPageLabelView.m */, 79 | B3616CE28DC522B976D5AC96 /* CHPPageLabelView.h */, 80 | B36161B714D0D7E2A9C96FA6 /* include */, 81 | ); 82 | path = Chapters; 83 | sourceTree = ""; 84 | }; 85 | B361606AFB222CB417DF708A /* MobileSubstrate */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | B36162A3C9329D818161181B /* DynamicLibraries */, 89 | ); 90 | path = MobileSubstrate; 91 | sourceTree = ""; 92 | }; 93 | B36161B714D0D7E2A9C96FA6 /* include */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | B3616473FE27E9B602FD9117 /* substrate.h */, 97 | ); 98 | path = include; 99 | sourceTree = SOURCE_ROOT; 100 | }; 101 | B361622ACF40EA328F8409EE /* arm64e */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | B36168971A16E6272DF716C7 /* CHPManager.m.o */, 105 | B3616C17C3EF2291E6BF0589 /* Chapters.xm.mm.o */, 106 | B3616154E6FD96D27D223E20 /* CHPPageLabelView.m.o */, 107 | ); 108 | path = arm64e; 109 | sourceTree = ""; 110 | }; 111 | B36162A3C9329D818161181B /* DynamicLibraries */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | B361638219441DC3E872F98F /* Chapters.dylib */, 115 | B3616C5C9545727D7D2598D7 /* Chapters.plist */, 116 | ); 117 | path = DynamicLibraries; 118 | sourceTree = ""; 119 | }; 120 | B36164D5789DEFDEE99224D3 /* Library */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | B361680D1DB94494CE415273 /* MobileSubstrate */, 124 | ); 125 | path = Library; 126 | sourceTree = ""; 127 | }; 128 | B361650C953A2A58EEC36F4D /* arm64 */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | B36169BD03CDEEF82574968B /* CHPManager.m.o */, 132 | B36161F9758ACE4A74486267 /* Chapters.xm.mm.o */, 133 | B36168FE2DF97819EF7EDF5C /* CHPPageLabelView.m.o */, 134 | ); 135 | path = arm64; 136 | sourceTree = ""; 137 | }; 138 | B361652C99D9B0886B9F711A /* ninja */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | B36162042FFDC1B890BA2426 /* build.ninja */, 142 | ); 143 | path = ninja; 144 | sourceTree = ""; 145 | }; 146 | B361677E54EAE72A1861B6A8 = { 147 | isa = PBXGroup; 148 | children = ( 149 | 5FBB363024651C92007A485A /* Chapters */, 150 | B3616958D458BDB4646FB7DF /* Products */, 151 | B36169D9DCA9779AAF7B1732 /* DragonMake */, 152 | B3616F506D1551FCBD18F795 /* Chapters.plist */, 153 | B361622756164C8A195005BD /* control */, 154 | B3616C0ADD187ADD5E2678C0 /* .dragon */, 155 | B3616369A63AE1CD196A4C39 /* Chapters.mm */, 156 | B3616868262419BE78C765B0 /* SpringBoardHome.h */, 157 | ); 158 | sourceTree = ""; 159 | }; 160 | B36167FF51F587A06EFD799B /* _ */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | B36164D5789DEFDEE99224D3 /* Library */, 164 | ); 165 | path = _; 166 | sourceTree = ""; 167 | }; 168 | B361680D1DB94494CE415273 /* MobileSubstrate */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | B3616BA05D24781B0D12E787 /* DynamicLibraries */, 172 | ); 173 | path = MobileSubstrate; 174 | sourceTree = ""; 175 | }; 176 | B36168D6511F2F34335205D5 /* armv7 */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | B36166AB3C1CF2BE1B4753E2 /* CHPManager.m.o */, 180 | B36169C680A16B8BD2A0798A /* Chapters.xm.mm.o */, 181 | B361647BE240844DC806E322 /* CHPPageLabelView.m.o */, 182 | ); 183 | path = armv7; 184 | sourceTree = ""; 185 | }; 186 | B36168D9F241E7A348972009 /* Contents */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | B3616FA15059FAC89C8F015D /* Resources */, 190 | B3616C4FB2269D7D53512771 /* Info.plist */, 191 | ); 192 | path = Contents; 193 | sourceTree = ""; 194 | }; 195 | B36168E7E67A70A854CC6FBB /* sign */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | B3616E46D23550E516204667 /* .dragon */, 199 | ); 200 | path = sign; 201 | sourceTree = ""; 202 | }; 203 | B361693A34B7795EA8E98EBC /* build */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | B361650C953A2A58EEC36F4D /* arm64 */, 207 | B36168D6511F2F34335205D5 /* armv7 */, 208 | B3616FF228F10C4985670A1F /* logos */, 209 | B361622ACF40EA328F8409EE /* arm64e */, 210 | B36160011937A9C509DFB4F4 /* .ninja_log */, 211 | B36167354EC8181EDAB7751B /* .ninja_deps */, 212 | B361660799698E8E68C206FF /* Chapters.arm64 */, 213 | B3616BD7247D3A24B8768860 /* Chapters.armv7 */, 214 | B361642D95123CF53B8CBA21 /* Chapters.arm64e */, 215 | ); 216 | path = build; 217 | sourceTree = ""; 218 | }; 219 | B3616958D458BDB4646FB7DF /* Products */ = { 220 | isa = PBXGroup; 221 | children = ( 222 | 5FBB362F24651C92007A485A /* Chapters.framework */, 223 | ); 224 | name = Products; 225 | sourceTree = ""; 226 | }; 227 | B3616A5DFD0BE55A8E78BABE /* Chapters.dylib.unsym.dSYM */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | B36168D9F241E7A348972009 /* Contents */, 231 | ); 232 | path = Chapters.dylib.unsym.dSYM; 233 | sourceTree = ""; 234 | }; 235 | B3616A855E920F684884444F /* DEBIAN */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | B3616B734561A7F107C7AF96 /* control */, 239 | ); 240 | path = DEBIAN; 241 | sourceTree = ""; 242 | }; 243 | B3616ACBDF1F46F24AA304D8 /* modules */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | ); 247 | path = modules; 248 | sourceTree = ""; 249 | }; 250 | B3616B036789D62179D02033 /* Library */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | B361606AFB222CB417DF708A /* MobileSubstrate */, 254 | ); 255 | path = Library; 256 | sourceTree = ""; 257 | }; 258 | B3616BA05D24781B0D12E787 /* DynamicLibraries */ = { 259 | isa = PBXGroup; 260 | children = ( 261 | B3616DD0FE1D5F4169AF6AB5 /* Chapters.dylib.unsym */, 262 | B36163CE327BA137A09D4E68 /* Chapters.dylib.unsigned */, 263 | B3616A5DFD0BE55A8E78BABE /* Chapters.dylib.unsym.dSYM */, 264 | ); 265 | path = DynamicLibraries; 266 | sourceTree = ""; 267 | }; 268 | B3616C0ADD187ADD5E2678C0 /* .dragon */ = { 269 | isa = PBXGroup; 270 | children = ( 271 | B3616F75E70BB19382ADF0C8 /* _ */, 272 | B36168E7E67A70A854CC6FBB /* sign */, 273 | B361693A34B7795EA8E98EBC /* build */, 274 | B361652C99D9B0886B9F711A /* ninja */, 275 | B3616ACBDF1F46F24AA304D8 /* modules */, 276 | B361622A51ECB259AF128E5F /* last_package */, 277 | ); 278 | path = .dragon; 279 | sourceTree = ""; 280 | }; 281 | B3616E46D23550E516204667 /* .dragon */ = { 282 | isa = PBXGroup; 283 | children = ( 284 | B36167FF51F587A06EFD799B /* _ */, 285 | ); 286 | path = .dragon; 287 | sourceTree = ""; 288 | }; 289 | B3616F75E70BB19382ADF0C8 /* _ */ = { 290 | isa = PBXGroup; 291 | children = ( 292 | B3616A855E920F684884444F /* DEBIAN */, 293 | B3616B036789D62179D02033 /* Library */, 294 | ); 295 | path = _; 296 | sourceTree = ""; 297 | }; 298 | B3616FA15059FAC89C8F015D /* Resources */ = { 299 | isa = PBXGroup; 300 | children = ( 301 | B3616FDBAC7CCA9D3FB7A8E0 /* DWARF */, 302 | ); 303 | path = Resources; 304 | sourceTree = ""; 305 | }; 306 | B3616FDBAC7CCA9D3FB7A8E0 /* DWARF */ = { 307 | isa = PBXGroup; 308 | children = ( 309 | B3616985A88AF31B1E20D7B5 /* Chapters.dylib.unsym */, 310 | ); 311 | path = DWARF; 312 | sourceTree = ""; 313 | }; 314 | B3616FF228F10C4985670A1F /* logos */ = { 315 | isa = PBXGroup; 316 | children = ( 317 | B36162B9ABFEF0DF3827E38E /* Chapters.xm.mm */, 318 | ); 319 | path = logos; 320 | sourceTree = ""; 321 | }; 322 | /* End PBXGroup section */ 323 | 324 | /* Begin PBXNativeTarget section */ 325 | 5FBB362E24651C92007A485A /* Chapters */ = { 326 | isa = PBXNativeTarget; 327 | buildConfigurationList = 5FBB363624651C92007A485A /* Build configuration list for PBXNativeTarget "Chapters" */; 328 | buildPhases = ( 329 | 5FBB363924651F7C007A485A /* Sources */, 330 | 5FBB363724651CC2007A485A /* ShellScript */, 331 | ); 332 | buildRules = ( 333 | 5FBB363824651D87007A485A /* PBXBuildRule */, 334 | ); 335 | dependencies = ( 336 | ); 337 | name = Chapters; 338 | productName = Chapters; 339 | productReference = 5FBB362F24651C92007A485A /* Chapters.framework */; 340 | productType = "com.apple.product-type.framework"; 341 | }; 342 | /* End PBXNativeTarget section */ 343 | 344 | /* Begin PBXProject section */ 345 | B361602762CFC4F7AACC4725 /* Project object */ = { 346 | isa = PBXProject; 347 | attributes = { 348 | TargetAttributes = { 349 | 5FBB362E24651C92007A485A = { 350 | CreatedOnToolsVersion = 11.4; 351 | ProvisioningStyle = Automatic; 352 | }; 353 | }; 354 | }; 355 | buildConfigurationList = B3616B07BF17BAF3A7A48D5E /* Build configuration list for PBXProject "Chapters" */; 356 | compatibilityVersion = "Xcode 3.2"; 357 | developmentRegion = English; 358 | hasScannedForEncodings = 0; 359 | knownRegions = ( 360 | English, 361 | en, 362 | ); 363 | mainGroup = B361677E54EAE72A1861B6A8; 364 | productRefGroup = B3616958D458BDB4646FB7DF /* Products */; 365 | projectDirPath = ""; 366 | projectRoot = ""; 367 | targets = ( 368 | 5FBB362E24651C92007A485A /* Chapters */, 369 | ); 370 | }; 371 | /* End PBXProject section */ 372 | 373 | /* Begin PBXShellScriptBuildPhase section */ 374 | 5FBB363724651CC2007A485A /* ShellScript */ = { 375 | isa = PBXShellScriptBuildPhase; 376 | buildActionMask = 2147483647; 377 | files = ( 378 | ); 379 | inputFileListPaths = ( 380 | ); 381 | inputPaths = ( 382 | ); 383 | outputFileListPaths = ( 384 | ); 385 | outputPaths = ( 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | shellPath = /bin/zsh; 389 | shellScript = "dragon build\n"; 390 | }; 391 | /* End PBXShellScriptBuildPhase section */ 392 | 393 | /* Begin PBXSourcesBuildPhase section */ 394 | 5FBB363924651F7C007A485A /* Sources */ = { 395 | isa = PBXSourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | B3616EA25D2A930E2BBB4370 /* Chapters.xm.mm in Sources */, 399 | B36163EC7ED6600241098844 /* CHPManager.m in Sources */, 400 | B361655335221B47937F4CE7 /* CHPPageLabelView.m in Sources */, 401 | B361671068BF9B58CC936496 /* Chapters.mm in Sources */, 402 | ); 403 | runOnlyForDeploymentPostprocessing = 0; 404 | }; 405 | /* End PBXSourcesBuildPhase section */ 406 | 407 | /* Begin XCBuildConfiguration section */ 408 | 5FBB363424651C92007A485A /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | ALWAYS_SEARCH_USER_PATHS = NO; 412 | CLANG_ANALYZER_NONNULL = YES; 413 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 414 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 415 | CLANG_CXX_LIBRARY = "libc++"; 416 | CLANG_ENABLE_MODULES = YES; 417 | CLANG_ENABLE_OBJC_ARC = YES; 418 | CLANG_ENABLE_OBJC_WEAK = YES; 419 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 420 | CLANG_WARN_BOOL_CONVERSION = YES; 421 | CLANG_WARN_COMMA = YES; 422 | CLANG_WARN_CONSTANT_CONVERSION = YES; 423 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 424 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 425 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 426 | CLANG_WARN_EMPTY_BODY = YES; 427 | CLANG_WARN_ENUM_CONVERSION = YES; 428 | CLANG_WARN_INFINITE_RECURSION = YES; 429 | CLANG_WARN_INT_CONVERSION = YES; 430 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 431 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 432 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 434 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 435 | CLANG_WARN_STRICT_PROTOTYPES = YES; 436 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 437 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 438 | CLANG_WARN_UNREACHABLE_CODE = YES; 439 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 440 | CODE_SIGN_STYLE = Automatic; 441 | COPY_PHASE_STRIP = NO; 442 | CURRENT_PROJECT_VERSION = 1; 443 | DEBUG_INFORMATION_FORMAT = dwarf; 444 | DEFINES_MODULE = YES; 445 | DYLIB_COMPATIBILITY_VERSION = 1; 446 | DYLIB_CURRENT_VERSION = 1; 447 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 448 | ENABLE_STRICT_OBJC_MSGSEND = YES; 449 | ENABLE_TESTABILITY = YES; 450 | GCC_C_LANGUAGE_STANDARD = gnu11; 451 | GCC_DYNAMIC_NO_PIC = NO; 452 | GCC_NO_COMMON_BLOCKS = YES; 453 | GCC_OPTIMIZATION_LEVEL = 0; 454 | GCC_PREPROCESSOR_DEFINITIONS = ( 455 | "DEBUG=1", 456 | "$(inherited)", 457 | ); 458 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 459 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 460 | GCC_WARN_UNDECLARED_SELECTOR = YES; 461 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 462 | GCC_WARN_UNUSED_FUNCTION = YES; 463 | GCC_WARN_UNUSED_VARIABLE = YES; 464 | INFOPLIST_FILE = Chapters/Info.plist; 465 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 466 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 467 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 468 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 469 | MTL_FAST_MATH = YES; 470 | ONLY_ACTIVE_ARCH = NO; 471 | PRODUCT_BUNDLE_IDENTIFIER = me.kritanta.Chapters; 472 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 473 | SDKROOT = iphoneos; 474 | SKIP_INSTALL = YES; 475 | SUPPORTS_MACCATALYST = NO; 476 | TARGETED_DEVICE_FAMILY = "1,2"; 477 | VERSIONING_SYSTEM = "apple-generic"; 478 | VERSION_INFO_PREFIX = ""; 479 | }; 480 | name = Debug; 481 | }; 482 | 5FBB363524651C92007A485A /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | ALWAYS_SEARCH_USER_PATHS = NO; 486 | CLANG_ANALYZER_NONNULL = YES; 487 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 488 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 489 | CLANG_CXX_LIBRARY = "libc++"; 490 | CLANG_ENABLE_MODULES = YES; 491 | CLANG_ENABLE_OBJC_ARC = YES; 492 | CLANG_ENABLE_OBJC_WEAK = YES; 493 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 494 | CLANG_WARN_BOOL_CONVERSION = YES; 495 | CLANG_WARN_COMMA = YES; 496 | CLANG_WARN_CONSTANT_CONVERSION = YES; 497 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 498 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 499 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 500 | CLANG_WARN_EMPTY_BODY = YES; 501 | CLANG_WARN_ENUM_CONVERSION = YES; 502 | CLANG_WARN_INFINITE_RECURSION = YES; 503 | CLANG_WARN_INT_CONVERSION = YES; 504 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 505 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 506 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 507 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 508 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 509 | CLANG_WARN_STRICT_PROTOTYPES = YES; 510 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 511 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 512 | CLANG_WARN_UNREACHABLE_CODE = YES; 513 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 514 | CODE_SIGN_STYLE = Automatic; 515 | COPY_PHASE_STRIP = NO; 516 | CURRENT_PROJECT_VERSION = 1; 517 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 518 | DEFINES_MODULE = YES; 519 | DYLIB_COMPATIBILITY_VERSION = 1; 520 | DYLIB_CURRENT_VERSION = 1; 521 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 522 | ENABLE_NS_ASSERTIONS = NO; 523 | ENABLE_STRICT_OBJC_MSGSEND = YES; 524 | GCC_C_LANGUAGE_STANDARD = gnu11; 525 | GCC_NO_COMMON_BLOCKS = YES; 526 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 527 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 528 | GCC_WARN_UNDECLARED_SELECTOR = YES; 529 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 530 | GCC_WARN_UNUSED_FUNCTION = YES; 531 | GCC_WARN_UNUSED_VARIABLE = YES; 532 | INFOPLIST_FILE = Chapters/Info.plist; 533 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 534 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 535 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 536 | MTL_ENABLE_DEBUG_INFO = NO; 537 | MTL_FAST_MATH = YES; 538 | PRODUCT_BUNDLE_IDENTIFIER = me.kritanta.Chapters; 539 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 540 | SDKROOT = iphoneos; 541 | SKIP_INSTALL = YES; 542 | SUPPORTS_MACCATALYST = NO; 543 | TARGETED_DEVICE_FAMILY = "1,2"; 544 | VALIDATE_PRODUCT = YES; 545 | VERSIONING_SYSTEM = "apple-generic"; 546 | VERSION_INFO_PREFIX = ""; 547 | }; 548 | name = Release; 549 | }; 550 | B361662733E40EBC59945D90 /* Debug */ = { 551 | isa = XCBuildConfiguration; 552 | buildSettings = { 553 | ADDITIONAL_SDKS = /Users/kritanta/ios/DragonBuild/sdks/iPhoneOS.sdk; 554 | }; 555 | name = Debug; 556 | }; 557 | B3616D1097EB0E34F41CE9C4 /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | ADDITIONAL_SDKS = /Users/kritanta/ios/DragonBuild/sdks/iPhoneOS.sdk; 561 | }; 562 | name = Release; 563 | }; 564 | /* End XCBuildConfiguration section */ 565 | 566 | /* Begin XCConfigurationList section */ 567 | 5FBB363624651C92007A485A /* Build configuration list for PBXNativeTarget "Chapters" */ = { 568 | isa = XCConfigurationList; 569 | buildConfigurations = ( 570 | 5FBB363424651C92007A485A /* Debug */, 571 | 5FBB363524651C92007A485A /* Release */, 572 | ); 573 | defaultConfigurationIsVisible = 0; 574 | defaultConfigurationName = Release; 575 | }; 576 | B3616B07BF17BAF3A7A48D5E /* Build configuration list for PBXProject "Chapters" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | B361662733E40EBC59945D90 /* Debug */, 580 | B3616D1097EB0E34F41CE9C4 /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | defaultConfigurationName = Release; 584 | }; 585 | /* End XCConfigurationList section */ 586 | }; 587 | rootObject = B361602762CFC4F7AACC4725 /* Project object */; 588 | } 589 | -------------------------------------------------------------------------------- /Chapters.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapters.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapters.xcodeproj/project.xcworkspace/xcuserdata/kritanta.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kritanta-ios-tweaks/Chapters/37f70502cbd2f145d3c8648e54caf269c09bc0c2/Chapters.xcodeproj/project.xcworkspace/xcuserdata/kritanta.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Chapters.xcodeproj/project.xcworkspace/xcuserdata/kritanta.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Chapters.xcodeproj/xcuserdata/kritanta.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Chapters.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapters/CHPLabelDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by _kritanta on 5/7/20. 3 | // 4 | 5 | @import Foundation; 6 | 7 | #ifndef CHPLABELDELEGATE_h 8 | #define CHPLABELDELEGATE_h 9 | 10 | @protocol CHPLabelDelegate 11 | 12 | @property (nonatomic, strong, readwrite) UIColor *labelColor; 13 | 14 | - (NSString *)nameForPageIndex:(NSInteger)index; 15 | 16 | - (void)setName:(NSString *)name forPageIndex:(NSInteger)index; 17 | 18 | - (CGRect)frameForLabel; 19 | 20 | @end 21 | 22 | #endif -------------------------------------------------------------------------------- /Chapters/CHPManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by _kritanta on 5/7/20. 3 | // 4 | 5 | @import UIKit; 6 | 7 | #include "CHPLabelDelegate.h" 8 | #import "SpringBoardHome.h" 9 | 10 | #ifndef CHPMANAGER_H 11 | #define CHPMANAGER_H 12 | 13 | static NSUserDefaults *prefs = nil; 14 | 15 | @interface CHPManager : NSObject 16 | 17 | - (instancetype)initWithDomain:(NSString *)domain; 18 | 19 | - (void)relayoutIfNeeded; 20 | 21 | - (void)reloadLabelsForRootFolderController:(SBRootFolderController *)controller index:(NSInteger)index; 22 | 23 | + (instancetype)sharedInstance; 24 | 25 | @property (nonatomic, strong, readwrite) NSMutableDictionary *labels; 26 | 27 | @property (nonatomic, readonly) BOOL reloadNeeded; 28 | @property (nonatomic, strong, readwrite) UIColor *labelColor; 29 | @property (nonatomic, strong, readonly) NSUserDefaults *store; 30 | @property (nonatomic, readwrite) struct SBIconListLayoutMetrics layoutMetrics; 31 | 32 | @end 33 | 34 | #endif //CHPMANAGER_H -------------------------------------------------------------------------------- /Chapters/CHPManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by _kritanta on 5/7/20. 3 | // 4 | 5 | #import "CHPManager.h" 6 | #import "CHPPageLabelView.h" 7 | #import "../include/SpringBoardHome.h" 8 | 9 | @implementation CHPManager 10 | { 11 | 12 | @private 13 | NSUserDefaults *_store; 14 | UIColor *_labelColor; 15 | } 16 | 17 | @synthesize store = _store; 18 | @synthesize labels = _labels; 19 | @synthesize reloadNeeded = _reloadNeeded; 20 | 21 | + (instancetype)sharedInstance 22 | { 23 | static id _sharedInstance = nil; 24 | static dispatch_once_t onceToken; 25 | dispatch_once(&onceToken, ^ 26 | { 27 | _sharedInstance = [[self alloc] initWithDomain:@"me.kritanta.chapters"]; 28 | }); 29 | 30 | return _sharedInstance; 31 | } 32 | 33 | - (instancetype)initWithDomain:(NSString *)domain 34 | { 35 | self = [super init]; 36 | 37 | if (self) 38 | { 39 | _store = [[NSUserDefaults alloc] initWithSuiteName:domain]; 40 | _labels = [NSMutableDictionary new]; 41 | 42 | _reloadNeeded = YES; 43 | } 44 | 45 | return self; 46 | } 47 | 48 | /** 49 | * Call `reload` on any labels we've rendered if a reload is needed. 50 | */ 51 | - (void)relayoutIfNeeded 52 | { 53 | if (!_reloadNeeded) 54 | { 55 | return; 56 | } 57 | 58 | for (CHPPageLabelView *label in [_labels allValues]) 59 | { 60 | [label reload]; 61 | } 62 | } 63 | 64 | /** 65 | * @return A label color if one has been set, else white 66 | */ 67 | - (UIColor *)labelColor 68 | { 69 | return _labelColor ?: [UIColor whiteColor]; 70 | } 71 | 72 | /** 73 | * Set label color and indicate a reload is needed 74 | * 75 | * @param color Color that labels should update to. 76 | */ 77 | - (void)setLabelColor:(UIColor *)color 78 | { 79 | _labelColor = color; 80 | _reloadNeeded = YES; 81 | } 82 | 83 | /** 84 | * Load/Reload labels for a given rootFolderController by iterating through added pages 85 | * and inserting labels where _labels contains no object at that index 86 | * 87 | * @param controller SBRootFolderController that we're loading labels into 88 | * @param index Specific page index, -1 will reload all 89 | */ 90 | - (void)reloadLabelsForRootFolderController:(SBRootFolderController *)controller index:(NSInteger)index 91 | { 92 | // Occasionally springboard throws an insanely high number at us 93 | // Rather than finding the source of this issue I've opted to just 94 | // nix any index thrown at us higher than 500. It works. 95 | if (index >= 500 || [controller folderDelegate] == nil) 96 | { 97 | return; 98 | } 99 | 100 | struct SBIconListLayoutMetrics metrics; 101 | metrics.layoutInsets = [[[[controller folderDelegate] rootIconListAtIndex:0] layout] layoutInsetsForOrientation:1]; 102 | _layoutMetrics = metrics; 103 | 104 | if (index != -1) 105 | { 106 | CHPPageLabelView *label = [self labelForIndex:index onController:controller createIfNecessary:YES]; 107 | [label reload]; 108 | } 109 | 110 | for (int i = 0; i < [controller iconListViewCount]; i++) 111 | { 112 | if ([[controller folderDelegate] rootIconListAtIndex:i]) 113 | { 114 | CHPPageLabelView *label = [self labelForIndex:i onController:controller createIfNecessary:YES]; 115 | [label reload]; 116 | } 117 | } 118 | } 119 | 120 | - (CHPPageLabelView *)labelForIndex:(NSInteger)index onController:(SBRootFolderController *)controller 121 | createIfNecessary:(BOOL)create 122 | { 123 | // Check if a value exists for the index we were given 124 | if (!_labels[@(index)] && create) 125 | { 126 | @try 127 | { 128 | // If not, create a label and assign it to that index 129 | CHPPageLabelView *label = [[CHPPageLabelView alloc] initWithPageIndex:index andLabelDelegate:self]; 130 | 131 | // We add the view as a subview here. I'd like to move this to somewhere more 132 | // pointed, but this works perfectly fine. 133 | [[[controller folderDelegate] rootIconListAtIndex:index] addSubview:label]; 134 | _labels[@(index)] = label; 135 | } 136 | @catch (NSException *ex) 137 | { 138 | return nil; 139 | } 140 | } 141 | 142 | // Give the label for that index. 143 | return _labels[@(index)]; 144 | } 145 | 146 | /** 147 | * Retrieve stored label text for a page 148 | * 149 | * @param index Index of page, starting at 0 150 | * @return NSString stored name for page index requested, Page ${index+1} if none exists 151 | */ 152 | - (NSString *)nameForPageIndex:(NSInteger)index 153 | { 154 | return [_store objectForKey:[NSString stringWithFormat:@"%ld", (long) index]] 155 | ?: [NSString stringWithFormat:@"Page %ld", (long)index + 1]; 156 | } 157 | 158 | /** 159 | * Set the stored value for a label 160 | * 161 | * @param name NSString Label text to store 162 | * @param index NSInteger index of the page starting at 0 163 | */ 164 | - (void)setName:(NSString *)name forPageIndex:(NSInteger)index 165 | { 166 | [_store setObject:name forKey:[NSString stringWithFormat:@"%ld", (long) index]]; 167 | } 168 | 169 | /** 170 | * Calculate the frame for a label based on layoutMetrics given. 171 | * 172 | * @return CGRect frame calculated 173 | */ 174 | - (CGRect)frameForLabel 175 | { 176 | // If we don't have a proper rect, just assume iPhone X defaults. 177 | if (_layoutMetrics.layoutInsets.left == 0) 178 | return CGRectMake(27, 54 + [[_store valueForKey:@"TopMargin"] intValue], [[UIScreen mainScreen] bounds].size.width - 54, 70); 179 | 180 | return CGRectMake(_layoutMetrics.layoutInsets.left + 2, _layoutMetrics.layoutInsets.top - 10 + [[_store valueForKey:@"TopMargin"] intValue], [[UIScreen 181 | mainScreen] bounds].size.width - _layoutMetrics.layoutInsets.left * 2, 70); 182 | } 183 | 184 | + (NSString *)processedTitleForText:(NSString *)string 185 | { 186 | 187 | } 188 | 189 | @end -------------------------------------------------------------------------------- /Chapters/CHPPageLabelView.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by _kritanta on 5/7/20. 3 | // 4 | 5 | @import UIKit; 6 | 7 | #include "CHPLabelDelegate.h" 8 | 9 | #ifndef CHPPAGELABELVIEW_H 10 | #define CHPPAGELABELVIEW_H 11 | 12 | @interface CHPPageLabelView : UIView 13 | 14 | @property (nonatomic, readonly) NSInteger index; 15 | @property (nonatomic, weak, readwrite) NSObject *labelDelegate; 16 | @property (nonatomic, strong, readonly) NSString *realText; 17 | @property (nonatomic, strong, readonly) UITextField *actualLabel; 18 | 19 | - (instancetype)initWithPageIndex:(NSInteger)index andLabelDelegate:(NSObject *)labelDelegate; 20 | 21 | - (void)reload; 22 | 23 | @end 24 | 25 | #endif //CHPPAGELABELVIEW_H 26 | -------------------------------------------------------------------------------- /Chapters/CHPPageLabelView.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by _kritanta on 5/7/20. 3 | // 4 | 5 | #import "CHPPageLabelView.h" 6 | 7 | 8 | @implementation CHPPageLabelView 9 | { 10 | 11 | } 12 | 13 | @synthesize index = _index; 14 | @synthesize realText = _realText; 15 | @synthesize labelDelegate = _labelDelegate; 16 | 17 | /** 18 | * I'd like to see this expanded into some preference logic eventually, not 19 | * everyone is a sucker for helvetica 20 | * 21 | * @return UIFont Font that should be used with the label 22 | */ 23 | + (UIFont *)labelFont 24 | { 25 | return [UIFont fontWithName:@"HelveticaNeue-Bold" size:30.0]; 26 | } 27 | 28 | /** 29 | * Initialize with a specific index, and then pass that info 30 | * to our labelDelegate and create our view there. 31 | * 32 | * @param index Page index starting at 0 33 | * @param labelDelegate class conforming to the CHPLabelDelegate protocol that provides information for us to use 34 | * when setting up our label view 35 | * @return CHPPageLabelView self 36 | */ 37 | - (instancetype)initWithPageIndex:(NSInteger)index andLabelDelegate:(NSObject *)labelDelegate 38 | { 39 | self = [super init]; 40 | 41 | if (self) 42 | { 43 | _index = index; 44 | _labelDelegate = labelDelegate; 45 | 46 | [self setFrame:[_labelDelegate frameForLabel]]; 47 | 48 | _actualLabel = [[UITextField alloc] initWithFrame:[self bounds]]; 49 | [self updateTextWithString:[_labelDelegate nameForPageIndex:index]]; 50 | [_actualLabel setFont:[CHPPageLabelView labelFont]]; 51 | [_actualLabel setDelegate:self]; 52 | 53 | [self addSubview:_actualLabel]; 54 | } 55 | 56 | return self; 57 | } 58 | 59 | /** 60 | * Called mainly by the controller of this view 61 | * 62 | * Should re-render anything graphical we might want to update 63 | */ 64 | - (void)reload 65 | { 66 | self.frame = [_labelDelegate frameForLabel]; 67 | [_actualLabel setTextColor:[_labelDelegate labelColor]]; 68 | } 69 | 70 | - (void)updateTextWithString:(NSString *)string 71 | { 72 | // TODO: process 73 | [_actualLabel setText:string]; 74 | } 75 | 76 | - (void)textFieldDidBeginEditing:(UITextField *)textField 77 | { 78 | 79 | } 80 | 81 | /** 82 | * Ensure we properly exit the text field and save our values 83 | * 84 | * @param textField UITextField self.actualLabel 85 | * @return BOOL yes 86 | */ 87 | - (BOOL)textFieldShouldReturn:(UITextField *)textField 88 | { 89 | [textField resignFirstResponder]; 90 | 91 | [_labelDelegate setName:[textField text] forPageIndex:_index]; 92 | 93 | return YES; 94 | } 95 | 96 | @end -------------------------------------------------------------------------------- /DragonMake: -------------------------------------------------------------------------------- 1 | --- 2 | name: Chapters 3 | icmd: killall -9 SpringBoard 4 | id: me.kritanta.chapters 5 | depends: mobilesubstrate 6 | version: 1.0.1 7 | architecture: iphoneos-arm 8 | description: Label your pages. 9 | author: Kritanta 10 | section: Tweaks 11 | icon: http://repo.openpack.io/icon/Chapters.png 12 | 13 | Chapters: 14 | type: tweak 15 | cflags: -w 16 | include: 17 | - include/ 18 | files: 19 | - Chapters.mm 20 | - Chapters/CHPManager.m 21 | - Chapters/CHPPageLabelView.m 22 | stage: 23 | - mkdir -p .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle 24 | - cp icon@2x.png .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle 25 | - cp Prefs.plist .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle/Info.plist 26 | - cp HomePlus.plist .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle -------------------------------------------------------------------------------- /HomePlus.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pages 6 | 7 | 8 | icon 9 | icon.png 10 | topLabel 11 | Top Margin 12 | topControlType 13 | Slider 14 | topPreferenceKeyLink 15 | TopMargin 16 | topPostNotification 17 | me.krit.chapters/prefs 18 | topMax 19 | 100 20 | topMin 21 | -100 22 | bottomLabel 23 | Bottom 24 | bottomControlType 25 | Slider 26 | bottomPreferenceKeyLink 27 | BottomMargin 28 | bottomPostNotification 29 | me.krit.chapters/prefs 30 | bottomMax 31 | 100 32 | bottomMin 33 | -100 34 | 35 | 36 | icon 37 | icon.png 38 | title 39 | Chapters 40 | 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | copyright (c) 2020 kritanta 2 | 3 | dragon license version 1 4 | 5 | the following statement, within quotation marks, is a non-binding summation of the following license: 6 | 7 | " 8 | Clauses: 9 | 1. If you're forking/repacking the project, include this LICENSE file 10 | 2. If you use an individual file somewhere else, you need to keep the copyright header comment 11 | 3. Don't take a snippet/snippets of code from here and relicense it unless you've added it to a larger project. 12 | 4. If you repackage/fork this project, indicate so in the name and description of the project to a reasonable extent. 13 | 14 | Exemptions: 15 | 1. Anything you used this tool to create isn't bound by this license 16 | 2. Submodules of this project aren't bound by this license unless they also include it. 17 | 18 | This license isn't strictly enforced, and is very loose in general, so respecting it is appreciated. 19 | " 20 | 21 | redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 22 | 23 | 1. redistributions of substantial portions of the source code of this project must retain the above copyright notice, this list of conditions and the following disclaimer. 24 | 25 | 2. redistributions of source code in any capacity must maintain the copyright notice within individual files. this does not apply to snippets of code. 26 | 27 | 3. individual snippets of code alone should not be relicensed unless they do not make up a substantial portion of the project. 28 | 29 | 4. redistributions of substantial portions of the source code of this project must differentiate themselves from this project within their name and within extended descriptions of the project. 30 | 31 | 4a. modified redistributions of substantial portions of the source code or compiled binary must indicate they have been modified 32 | 33 | 34 | the following are exempt from this license: 35 | 36 | 1. projects, binaries, or any packages generated through this program are not considered derivative works, and are not bound by this license. 37 | 38 | 2. submodules of this project are not bound by this license unless explicitly stated. 39 | -------------------------------------------------------------------------------- /Prefs.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ChapterPrefs 9 | CFBundleIdentifier 10 | me.kritanta.chapters 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | NSPrincipalClass 22 | CPTRootListController 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chapters 2 | 3 | Adds labels to your homescreen pages 4 | 5 | Get it on https://repo.openpack.io/ 6 | -------------------------------------------------------------------------------- /build.ninja: -------------------------------------------------------------------------------- 1 | name = Chapters 2 | lowername = chapters 3 | 4 | # Build file for Chapters 5 | # Generated at 01/04/21 20:29:15 6 | 7 | stagedir = _ 8 | location = /Library/MobileSubstrate/DynamicLibraries/ 9 | dragondir = $$DRAGONBUILD 10 | sysroot = -isysroot $dragondir/sdks/iPhoneOS.sdk 11 | proj_build_dir = .dragon 12 | objdir = $proj_build_dir/obj 13 | signdir = $proj_build_dir/sign 14 | builddir = $proj_build_dir/build 15 | build_target_file = $proj_build_dir/$stagedir/$location$name.dylib 16 | pwd = . 17 | resource_dir = Resources 18 | toolchain-prefix = arm64-apple-darwin14- 19 | 20 | stage = mkdir -p .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle; $ 21 | cp icon@2x.png $ 22 | .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle; cp $ 23 | Prefs.plist $ 24 | .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle/Info.plist; cp $ 25 | HomePlus.plist .dragon/_/Library/PreferenceBundles/ChaptersPrefs.bundle 26 | stage2 = cp $name.plist $ 27 | $proj_build_dir/_/Library/MobileSubstrate/DynamicLibraries/$name.plist 28 | 29 | 30 | internalsigntarget = $signdir/$build_target_file.unsigned 31 | internalsymtarget = $signdir/$build_target_file.unsym 32 | 33 | fwSearch = -F$dragondir/sdks/iPhoneOS.sdk/System/Library/PrivateFrameworks/ $ 34 | -F$dragondir/frameworks 35 | libSearch = -L$dragondir/lib -L. 36 | modulesinternal = -fmodules -fcxx-modules -fmodule-name=$name $ 37 | -fbuild-session-file=$proj_build_dir/modules/ $ 38 | -fmodules-validate-once-per-build-session -fmodules-prune-after=345600 $ 39 | -fmodules-prune-interval=86400 40 | 41 | cc = clang 42 | codesign = ldid 43 | cxx = clang++ 44 | dsym = dsymutil 45 | ld = clang++ 46 | lipo = lipo 47 | logos = $dragondir/src/logos/bin/logos.pl 48 | optool = $dragondir/bin/optool 49 | plutil = plutil 50 | swift = swift 51 | 52 | targetvers = 10.0 53 | targetprefix = -miphoneos-version-min= 54 | targetos = iphoneos 55 | triple = 56 | 57 | frameworks = -framework UIKit -framework Foundation 58 | libs = 59 | 60 | macros = 61 | arc = -fobjc-arc 62 | btarg = 63 | debug = -fcolor-diagnostics 64 | entfile = 65 | entflag = -S 66 | optim = 0 67 | warnings = -Wall 68 | 69 | cinclude = -I$dragondir/include -I$dragondir/vendor/include $ 70 | -I$dragondir/include/_fallback -I$DRAGONBUILD/headers/ -I$pwd 71 | header_includes = -Iinclude/ 72 | public_headers = 73 | 74 | usrCflags = 75 | usrLDflags = 76 | 77 | libflags = 78 | lopts = -dynamiclib -ggdb -Xlinker -segalign -Xlinker 4000 -framework $ 79 | CydiaSubstrate 80 | typeldflags = 81 | 82 | cflags = -w 83 | ldflags = 84 | lflags = 85 | lfflags = 86 | swiftflags = 87 | 88 | theosshim = 89 | internalcflags = $cinclude $debug $fwSearch $cflags $btarg -O$optim $ 90 | $targetprefix$targetvers $sysroot $header_includes $arc $triple $ 91 | $theosshim $macros $warnings $modulesinternal 92 | internalldflags = $internalcflags $typeldflags $frameworks $libs $libflags $ 93 | $lopts $libSearch $ldflags $libs 94 | internallflags = 95 | internallfflags = 96 | internalswiftflags = -color-diagnostics -enable-objc-interop -sdk $ 97 | /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk $ 98 | -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos $ 99 | -g -L/usr/lib/swift -swift-version 5 -module-name $name 100 | 101 | rule linkarmv7 102 | command = $ld -arch armv7 $internallflags $internalldflags -o $out $in 103 | description = Linking $in with $ld [armv7] 104 | rule linkarm64 105 | command = $ld -arch arm64 $internallflags $internalldflags -o $out $in 106 | description = Linking $in with $ld [arm64] 107 | rule linkarm64e 108 | command = $ld -arch arm64e $internallflags $internalldflags -o $out $in 109 | description = Linking $in with $ld [arm64e] 110 | rule objcxxarmv7 111 | command = $cxx -arch armv7 $internalcflags -c $in -o $out 112 | description = Compiling $in with $cxx [armv7] 113 | rule lipo 114 | command = $lipo -create $in -output $out 115 | description = Merging architechtures 116 | rule objcxxarm64e 117 | command = $cxx -arch arm64e $internalcflags -c $in -o $out 118 | description = Compiling $in with $cxx [arm64e] 119 | rule debug 120 | command = $dsym \"$in\" 2&> /dev/null; cp $in $out 121 | description = Generating Debug Symbols for $name 122 | rule stage 123 | command = $stage && $stage2 124 | description = Running Stage for $name 125 | rule objcarm64 126 | command = $cc -arch arm64 $internalcflags -c $in -o $out 127 | description = Compiling $in with $cc [arm64] 128 | rule objcarmv7 129 | command = $cc -arch armv7 $internalcflags -c $in -o $out 130 | description = Compiling $in with $cc [armv7] 131 | rule sign 132 | command = $codesign $entflag$entfile $in && cp $in $out 133 | description = Signing $name 134 | rule objcarm64e 135 | command = $cc -arch arm64e $internalcflags -c $in -o $out 136 | description = Compiling $in with $cc [arm64e] 137 | rule objcxxarm64 138 | command = $cxx -arch arm64 $internalcflags -c $in -o $out 139 | description = Compiling $in with $cxx [arm64] 140 | 141 | build $builddir/armv7/CHPManager.m.o: objcarmv7 Chapters/CHPManager.m 142 | build $builddir/armv7/CHPPageLabelView.m.o: objcarmv7 $ 143 | Chapters/CHPPageLabelView.m 144 | build $builddir/armv7/Chapters.mm.o: objcxxarmv7 Chapters.mm 145 | build $builddir/$name.armv7: linkarmv7 $builddir/armv7/CHPManager.m.o $ 146 | $builddir/armv7/CHPPageLabelView.m.o $builddir/armv7/Chapters.mm.o 147 | build $builddir/arm64/CHPManager.m.o: objcarm64 Chapters/CHPManager.m 148 | build $builddir/arm64/CHPPageLabelView.m.o: objcarm64 $ 149 | Chapters/CHPPageLabelView.m 150 | build $builddir/arm64/Chapters.mm.o: objcxxarm64 Chapters.mm 151 | build $builddir/$name.arm64: linkarm64 $builddir/arm64/CHPManager.m.o $ 152 | $builddir/arm64/CHPPageLabelView.m.o $builddir/arm64/Chapters.mm.o 153 | build $builddir/arm64e/CHPManager.m.o: objcarm64e Chapters/CHPManager.m 154 | build $builddir/arm64e/CHPPageLabelView.m.o: objcarm64e $ 155 | Chapters/CHPPageLabelView.m 156 | build $builddir/arm64e/Chapters.mm.o: objcxxarm64e Chapters.mm 157 | build $builddir/$name.arm64e: linkarm64e $builddir/arm64e/CHPManager.m.o $ 158 | $builddir/arm64e/CHPPageLabelView.m.o $builddir/arm64e/Chapters.mm.o 159 | build $internalsymtarget: lipo $builddir/$name.armv7 $builddir/$name.arm64 $ 160 | $builddir/$name.arm64e 161 | build $internalsigntarget: debug $internalsymtarget 162 | build $build_target_file: sign $internalsigntarget 163 | build stage: stage build.ninja 164 | 165 | default $build_target_file 166 | -------------------------------------------------------------------------------- /icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kritanta-ios-tweaks/Chapters/37f70502cbd2f145d3c8648e54caf269c09bc0c2/icon@2x.png -------------------------------------------------------------------------------- /include/SpringBoardHome.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpringBoardHome.h 3 | // Chapters 4 | // 5 | // Created by _kritanta on 5/7/20. 6 | // Defines a few needed class types and structs available in SpringBoardHome.framework 7 | // 8 | @import UIKit; 9 | 10 | #ifndef SpringBoardHome_h 11 | #define SpringBoardHome_h 12 | 13 | typedef struct SBIconCoordinate { 14 | NSInteger row; 15 | NSInteger col; 16 | } SBIconCoordinate; 17 | 18 | struct SBIconListLayoutMetrics { 19 | unsigned long long _field1; 20 | unsigned long long _field2; 21 | struct CGSize _field3; 22 | struct CGSize _field4; 23 | double _field5; 24 | struct UIEdgeInsets layoutInsets; 25 | _Bool _field7; 26 | _Bool _field8; 27 | }; 28 | #pragma clang diagnostic push 29 | #pragma clang diagnostic ignored "-Wall" 30 | @interface SBIconListFlowLayout : NSObject 31 | 32 | - (UIEdgeInsets)layoutInsetsForOrientation:(NSInteger)orientation; 33 | 34 | @end 35 | 36 | @interface SBIconListView : UIView 37 | -(void)layoutIconsNow; 38 | @property (nonatomic, strong) SBIconListFlowLayout *layout; 39 | @property (nonatomic, assign) NSUInteger firstFreeSlotIndex; 40 | @property (readonly, nonatomic, getter=isFull) _Bool full; 41 | @property (nonatomic, assign) NSInteger maximumIconCount; 42 | @property (nonatomic, assign) NSInteger iconsInRowForSpacingCalculation; 43 | @property (nonatomic, retain) NSArray *icons; 44 | @property (nonatomic, retain) NSString *iconLocation; 45 | @property (nonatomic,readonly) CGSize alignmentIconSize; 46 | @end 47 | 48 | @protocol SBRootFolderControllerDelegate 49 | 50 | @end 51 | 52 | @interface SBHIconManager : NSObject 53 | - (SBIconListView *)rootIconListAtIndex:(long long)arg1; 54 | - (NSInteger)currentIconListIndex; 55 | @end 56 | 57 | @interface SBIconListView (SBHIconManager) 58 | @property (nonatomic, weak, readwrite) SBHIconManager *iconViewProvider; 59 | @property (nonatomic, assign) UIEdgeInsets additionalLayoutInsets API_AVAILABLE(ios(14)); 60 | @end 61 | @interface SBRootIconListView : SBIconListView 62 | @end 63 | 64 | @interface SBRootFolderController 65 | @property (nonatomic, weak, readwrite) SBHIconManager *folderDelegate; 66 | @property (nonatomic, assign) NSInteger iconListViewCount; 67 | @end 68 | 69 | @interface SBHIconManager (SBRootFolderController) 70 | @property (nonatomic, strong,readwrite) SBRootFolderController *rootFolderController; 71 | -(SBRootFolderController *) _rootFolderController; 72 | @end 73 | 74 | @interface SBIconController 75 | @property (nonatomic, strong) SBHIconManager *iconManager; 76 | +(instancetype) sharedInstance; 77 | @end 78 | 79 | @interface SBHomeScreenPreviewView : UIView 80 | 81 | @end 82 | 83 | #endif /* SpringBoardHome_h */ 84 | #pragma clang diagnostic pop -------------------------------------------------------------------------------- /include/substrate.h: -------------------------------------------------------------------------------- 1 | /* Cydia Substrate - Powerful Code Insertion Platform 2 | * Copyright (C) 2008-2012 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Substrate is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Substrate. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef SUBSTRATE_H_ 23 | #define SUBSTRATE_H_ 24 | 25 | #ifdef __APPLE__ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | #include 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #include 35 | #include 36 | #endif 37 | 38 | #include 39 | #include 40 | 41 | #define _finline \ 42 | inline __attribute__((__always_inline__)) 43 | #define _disused \ 44 | __attribute__((__unused__)) 45 | 46 | #define _extern \ 47 | extern "C" __attribute__((__visibility__("default"))) 48 | 49 | #ifdef __cplusplus 50 | #define _default(value) = value 51 | #else 52 | #define _default(value) 53 | #endif 54 | 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | bool MSHookProcess(pid_t pid, const char *library); 60 | 61 | typedef const void *MSImageRef; 62 | 63 | MSImageRef MSGetImageByName(const char *file); 64 | void *MSFindSymbol(MSImageRef image, const char *name); 65 | 66 | void MSHookFunction(void *symbol, void *replace, void **result); 67 | 68 | #ifdef __APPLE__ 69 | #ifdef __arm__ 70 | __attribute__((__deprecated__)) 71 | IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix _default(NULL)); 72 | #endif 73 | void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result); 74 | #endif 75 | 76 | #ifdef SubstrateInternal 77 | typedef void *SubstrateAllocatorRef; 78 | typedef struct __SubstrateProcess *SubstrateProcessRef; 79 | typedef struct __SubstrateMemory *SubstrateMemoryRef; 80 | 81 | SubstrateProcessRef SubstrateProcessCreate(SubstrateAllocatorRef allocator, pid_t pid); 82 | void SubstrateProcessRelease(SubstrateProcessRef process); 83 | 84 | SubstrateMemoryRef SubstrateMemoryCreate(SubstrateAllocatorRef allocator, SubstrateProcessRef process, void *data, size_t size); 85 | void SubstrateMemoryRelease(SubstrateMemoryRef memory); 86 | #endif 87 | 88 | #ifdef __ANDROID__ 89 | #include 90 | _extern void MSJavaHookClassLoad(JNIEnv *jni, const char *name, void (*callback)(JNIEnv *, jclass, void *), void *data _default(NULL)); 91 | _extern void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result); 92 | _extern void MSJavaBlessClassLoader(JNIEnv *jni, jobject loader); 93 | 94 | typedef struct MSJavaObjectKey_ *MSJavaObjectKey; 95 | _extern MSJavaObjectKey MSJavaNewObjectKey(); 96 | _extern void MSJavaDeleteObjectKey(MSJavaObjectKey key); 97 | _extern void *MSJavaGetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key); 98 | _extern void MSJavaSetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key, void *value, void (*clean)(void *, JNIEnv *, void *) _default(NULL), void *data _default(NULL)); 99 | #endif 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #ifdef __cplusplus 106 | 107 | #ifdef SubstrateInternal 108 | struct SubstrateHookMemory { 109 | SubstrateMemoryRef handle_; 110 | 111 | SubstrateHookMemory(SubstrateProcessRef process, void *data, size_t size) : 112 | handle_(SubstrateMemoryCreate(NULL, NULL, data, size)) 113 | { 114 | } 115 | 116 | ~SubstrateHookMemory() { 117 | if (handle_ != NULL) 118 | SubstrateMemoryRelease(handle_); 119 | } 120 | }; 121 | #endif 122 | 123 | #ifdef __APPLE__ 124 | 125 | namespace etl { 126 | 127 | template 128 | struct Case { 129 | static char value[Case_ + 1]; 130 | }; 131 | 132 | typedef Case Yes; 133 | typedef Case No; 134 | 135 | namespace be { 136 | template 137 | static Yes CheckClass_(void (Checked_::*)()); 138 | 139 | template 140 | static No CheckClass_(...); 141 | } 142 | 143 | template 144 | struct IsClass { 145 | void gcc32(); 146 | 147 | static const bool value = (sizeof(be::CheckClass_(0).value) == sizeof(Yes::value)); 148 | }; 149 | 150 | } 151 | 152 | #ifdef __arm__ 153 | template 154 | __attribute__((__deprecated__)) 155 | static inline Type_ *MSHookMessage(Class _class, SEL sel, Type_ *imp, const char *prefix = NULL) { 156 | return reinterpret_cast(MSHookMessage(_class, sel, reinterpret_cast(imp), prefix)); 157 | } 158 | #endif 159 | 160 | template 161 | static inline void MSHookMessage(Class _class, SEL sel, Type_ *imp, Type_ **result) { 162 | return MSHookMessageEx(_class, sel, reinterpret_cast(imp), reinterpret_cast(result)); 163 | } 164 | 165 | template 166 | static inline Type_ &MSHookIvar(id self, const char *name) { 167 | Ivar ivar(class_getInstanceVariable(object_getClass(self), name)); 168 | #if __has_feature(objc_arc) 169 | void *pointer(ivar == NULL ? NULL : reinterpret_cast((__bridge void *)self) + ivar_getOffset(ivar)); 170 | #else 171 | void *pointer(ivar == NULL ? NULL : reinterpret_cast(self) + ivar_getOffset(ivar)); 172 | #endif 173 | return *reinterpret_cast(pointer); 174 | } 175 | 176 | #define MSAddMessage0(_class, type, arg0) \ 177 | class_addMethod($ ## _class, @selector(arg0), (IMP) &$ ## _class ## $ ## arg0, type); 178 | #define MSAddMessage1(_class, type, arg0) \ 179 | class_addMethod($ ## _class, @selector(arg0:), (IMP) &$ ## _class ## $ ## arg0 ## $, type); 180 | #define MSAddMessage2(_class, type, arg0, arg1) \ 181 | class_addMethod($ ## _class, @selector(arg0:arg1:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $, type); 182 | #define MSAddMessage3(_class, type, arg0, arg1, arg2) \ 183 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $, type); 184 | #define MSAddMessage4(_class, type, arg0, arg1, arg2, arg3) \ 185 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $, type); 186 | #define MSAddMessage5(_class, type, arg0, arg1, arg2, arg3, arg4) \ 187 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $, type); 188 | #define MSAddMessage6(_class, type, arg0, arg1, arg2, arg3, arg4, arg5) \ 189 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $, type); 190 | #define MSAddMessage7(_class, type, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ 191 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ $$ arg6 ## $, type); 192 | #define MSAddMessage8(_class, type, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ 193 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:arg7:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ $$ arg6 ## $ ## arg7 ## $, type); 194 | 195 | #define MSHookMessage0(_class, arg0) \ 196 | MSHookMessage($ ## _class, @selector(arg0), MSHake(_class ## $ ## arg0)) 197 | #define MSHookMessage1(_class, arg0) \ 198 | MSHookMessage($ ## _class, @selector(arg0:), MSHake(_class ## $ ## arg0 ## $)) 199 | #define MSHookMessage2(_class, arg0, arg1) \ 200 | MSHookMessage($ ## _class, @selector(arg0:arg1:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $)) 201 | #define MSHookMessage3(_class, arg0, arg1, arg2) \ 202 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $)) 203 | #define MSHookMessage4(_class, arg0, arg1, arg2, arg3) \ 204 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $)) 205 | #define MSHookMessage5(_class, arg0, arg1, arg2, arg3, arg4) \ 206 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $)) 207 | #define MSHookMessage6(_class, arg0, arg1, arg2, arg3, arg4, arg5) \ 208 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $)) 209 | #define MSHookMessage7(_class, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ 210 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ ## arg6 ## $)) 211 | #define MSHookMessage8(_class, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ 212 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:arg7:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ ## arg6 ## $ ## arg7 ## $)) 213 | 214 | #define MSRegister_(name, dollar, colon) \ 215 | namespace { static class C_$ ## name ## $ ## dollar { public: _finline C_$ ## name ## $ ##dollar() { \ 216 | MSHookMessage($ ## name, @selector(colon), MSHake(name ## $ ## dollar)); \ 217 | } } V_$ ## name ## $ ## dollar; } \ 218 | 219 | #define MSIgnore_(name, dollar, colon) 220 | 221 | #define MSMessage_(extra, type, _class, name, dollar, colon, call, args...) \ 222 | static type _$ ## name ## $ ## dollar(Class _cls, type (*_old)(_class, SEL, ## args, ...), type (*_spr)(struct objc_super *, SEL, ## args, ...), _class self, SEL _cmd, ## args); \ 223 | MSHook(type, name ## $ ## dollar, _class self, SEL _cmd, ## args) { \ 224 | Class const _cls($ ## name); \ 225 | type (* const _old)(_class, SEL, ## args, ...) = reinterpret_cast(_ ## name ## $ ## dollar); \ 226 | typedef type (*msgSendSuper_t)(struct objc_super *, SEL, ## args, ...); \ 227 | msgSendSuper_t const _spr(::etl::IsClass::value ? reinterpret_cast(&objc_msgSendSuper_stret) : reinterpret_cast(&objc_msgSendSuper)); \ 228 | return _$ ## name ## $ ## dollar call; \ 229 | } \ 230 | extra(name, dollar, colon) \ 231 | static _finline type _$ ## name ## $ ## dollar(Class _cls, type (*_old)(_class, SEL, ## args, ...), type (*_spr)(struct objc_super *, SEL, ## args, ...), _class self, SEL _cmd, ## args) 232 | 233 | /* for((x=1;x!=7;++x)){ echo -n "#define MSMessage${x}_(extra, type, _class, name";for((y=0;y!=x;++y));do echo -n ", sel$y";done;for((y=0;y!=x;++y));do echo -n ", type$y, arg$y";done;echo ") \\";echo -n " MSMessage_(extra, type, _class, name,";for((y=0;y!=x;++y));do if [[ $y -ne 0 ]];then echo -n " ##";fi;echo -n " sel$y ## $";done;echo -n ", ";for((y=0;y!=x;++y));do echo -n "sel$y:";done;echo -n ", (_cls, _old, _spr, self, _cmd";for((y=0;y!=x;++y));do echo -n ", arg$y";done;echo -n ")";for((y=0;y!=x;++y));do echo -n ", type$y arg$y";done;echo ")";} */ 234 | 235 | #define MSMessage0_(extra, type, _class, name, sel0) \ 236 | MSMessage_(extra, type, _class, name, sel0, sel0, (_cls, _old, _spr, self, _cmd)) 237 | #define MSMessage1_(extra, type, _class, name, sel0, type0, arg0) \ 238 | MSMessage_(extra, type, _class, name, sel0 ## $, sel0:, (_cls, _old, _spr, self, _cmd, arg0), type0 arg0) 239 | #define MSMessage2_(extra, type, _class, name, sel0, sel1, type0, arg0, type1, arg1) \ 240 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $, sel0:sel1:, (_cls, _old, _spr, self, _cmd, arg0, arg1), type0 arg0, type1 arg1) 241 | #define MSMessage3_(extra, type, _class, name, sel0, sel1, sel2, type0, arg0, type1, arg1, type2, arg2) \ 242 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $, sel0:sel1:sel2:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2), type0 arg0, type1 arg1, type2 arg2) 243 | #define MSMessage4_(extra, type, _class, name, sel0, sel1, sel2, sel3, type0, arg0, type1, arg1, type2, arg2, type3, arg3) \ 244 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $, sel0:sel1:sel2:sel3:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3), type0 arg0, type1 arg1, type2 arg2, type3 arg3) 245 | #define MSMessage5_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \ 246 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $, sel0:sel1:sel2:sel3:sel4:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4) 247 | #define MSMessage6_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \ 248 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $, sel0:sel1:sel2:sel3:sel4:sel5:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 249 | #define MSMessage7_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, sel6, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \ 250 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $ ## sel6 ## $, sel0:sel1:sel2:sel3:sel4:sel5:sel6:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5, arg6), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 251 | #define MSMessage8_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, sel6, sel7, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7) \ 252 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $ ## sel6 ## $ ## sel7 ## $, sel0:sel1:sel2:sel3:sel4:sel5:sel6:sel7:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 253 | 254 | #define MSInstanceMessage0(type, _class, args...) MSMessage0_(MSIgnore_, type, _class *, _class, ## args) 255 | #define MSInstanceMessage1(type, _class, args...) MSMessage1_(MSIgnore_, type, _class *, _class, ## args) 256 | #define MSInstanceMessage2(type, _class, args...) MSMessage2_(MSIgnore_, type, _class *, _class, ## args) 257 | #define MSInstanceMessage3(type, _class, args...) MSMessage3_(MSIgnore_, type, _class *, _class, ## args) 258 | #define MSInstanceMessage4(type, _class, args...) MSMessage4_(MSIgnore_, type, _class *, _class, ## args) 259 | #define MSInstanceMessage5(type, _class, args...) MSMessage5_(MSIgnore_, type, _class *, _class, ## args) 260 | #define MSInstanceMessage6(type, _class, args...) MSMessage6_(MSIgnore_, type, _class *, _class, ## args) 261 | #define MSInstanceMessage7(type, _class, args...) MSMessage7_(MSIgnore_, type, _class *, _class, ## args) 262 | #define MSInstanceMessage8(type, _class, args...) MSMessage8_(MSIgnore_, type, _class *, _class, ## args) 263 | 264 | #define MSClassMessage0(type, _class, args...) MSMessage0_(MSIgnore_, type, Class, $ ## _class, ## args) 265 | #define MSClassMessage1(type, _class, args...) MSMessage1_(MSIgnore_, type, Class, $ ## _class, ## args) 266 | #define MSClassMessage2(type, _class, args...) MSMessage2_(MSIgnore_, type, Class, $ ## _class, ## args) 267 | #define MSClassMessage3(type, _class, args...) MSMessage3_(MSIgnore_, type, Class, $ ## _class, ## args) 268 | #define MSClassMessage4(type, _class, args...) MSMessage4_(MSIgnore_, type, Class, $ ## _class, ## args) 269 | #define MSClassMessage5(type, _class, args...) MSMessage5_(MSIgnore_, type, Class, $ ## _class, ## args) 270 | #define MSClassMessage6(type, _class, args...) MSMessage6_(MSIgnore_, type, Class, $ ## _class, ## args) 271 | #define MSClassMessage7(type, _class, args...) MSMessage7_(MSIgnore_, type, Class, $ ## _class, ## args) 272 | #define MSClassMessage8(type, _class, args...) MSMessage8_(MSIgnore_, type, Class, $ ## _class, ## args) 273 | 274 | #define MSInstanceMessageHook0(type, _class, args...) MSMessage0_(MSRegister_, type, _class *, _class, ## args) 275 | #define MSInstanceMessageHook1(type, _class, args...) MSMessage1_(MSRegister_, type, _class *, _class, ## args) 276 | #define MSInstanceMessageHook2(type, _class, args...) MSMessage2_(MSRegister_, type, _class *, _class, ## args) 277 | #define MSInstanceMessageHook3(type, _class, args...) MSMessage3_(MSRegister_, type, _class *, _class, ## args) 278 | #define MSInstanceMessageHook4(type, _class, args...) MSMessage4_(MSRegister_, type, _class *, _class, ## args) 279 | #define MSInstanceMessageHook5(type, _class, args...) MSMessage5_(MSRegister_, type, _class *, _class, ## args) 280 | #define MSInstanceMessageHook6(type, _class, args...) MSMessage6_(MSRegister_, type, _class *, _class, ## args) 281 | #define MSInstanceMessageHook7(type, _class, args...) MSMessage7_(MSRegister_, type, _class *, _class, ## args) 282 | #define MSInstanceMessageHook8(type, _class, args...) MSMessage8_(MSRegister_, type, _class *, _class, ## args) 283 | 284 | #define MSClassMessageHook0(type, _class, args...) MSMessage0_(MSRegister_, type, Class, $ ## _class, ## args) 285 | #define MSClassMessageHook1(type, _class, args...) MSMessage1_(MSRegister_, type, Class, $ ## _class, ## args) 286 | #define MSClassMessageHook2(type, _class, args...) MSMessage2_(MSRegister_, type, Class, $ ## _class, ## args) 287 | #define MSClassMessageHook3(type, _class, args...) MSMessage3_(MSRegister_, type, Class, $ ## _class, ## args) 288 | #define MSClassMessageHook4(type, _class, args...) MSMessage4_(MSRegister_, type, Class, $ ## _class, ## args) 289 | #define MSClassMessageHook5(type, _class, args...) MSMessage5_(MSRegister_, type, Class, $ ## _class, ## args) 290 | #define MSClassMessageHook6(type, _class, args...) MSMessage6_(MSRegister_, type, Class, $ ## _class, ## args) 291 | #define MSClassMessageHook7(type, _class, args...) MSMessage7_(MSRegister_, type, Class, $ ## _class, ## args) 292 | #define MSClassMessageHook8(type, _class, args...) MSMessage8_(MSRegister_, type, Class, $ ## _class, ## args) 293 | 294 | #define MSOldCall(args...) \ 295 | _old(self, _cmd, ## args) 296 | #define MSSuperCall(args...) \ 297 | _spr(& (struct objc_super) {self, class_getSuperclass(_cls)}, _cmd, ## args) 298 | 299 | #define MSIvarHook(type, name) \ 300 | type &name(MSHookIvar(self, #name)) 301 | 302 | #define MSClassHook(name) \ 303 | @class name; \ 304 | static Class $ ## name = objc_getClass(#name); 305 | #define MSMetaClassHook(name) \ 306 | @class name; \ 307 | static Class $$ ## name = object_getClass($ ## name); 308 | 309 | #endif/*__APPLE__*/ 310 | 311 | template 312 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace, Type_ **result) { 313 | return MSHookFunction( 314 | reinterpret_cast(symbol), 315 | reinterpret_cast(replace), 316 | reinterpret_cast(result) 317 | ); 318 | } 319 | 320 | template 321 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace) { 322 | return MSHookFunction(symbol, replace, reinterpret_cast(NULL)); 323 | } 324 | 325 | template 326 | static inline void MSHookSymbol(Type_ *&value, const char *name, MSImageRef image = NULL) { 327 | value = reinterpret_cast(MSFindSymbol(image, name)); 328 | } 329 | 330 | template 331 | static inline void MSHookFunction(const char *name, Type_ *replace, Type_ **result = NULL) { 332 | Type_ *symbol; 333 | MSHookSymbol(symbol, name); 334 | return MSHookFunction(symbol, replace, result); 335 | } 336 | 337 | template 338 | static inline void MSHookFunction(MSImageRef image, const char *name, Type_ *replace, Type_ **result = NULL) { 339 | Type_ *symbol; 340 | MSHookSymbol(symbol, name, image); 341 | return MSHookFunction(symbol, replace, result); 342 | } 343 | 344 | #endif 345 | 346 | #ifdef __ANDROID__ 347 | 348 | #ifdef __cplusplus 349 | 350 | template 351 | static inline void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID method, Type_ (*replace)(JNIEnv *, Kind_, Args_...), Type_ (**result)(JNIEnv *, Kind_, ...)) { 352 | return MSJavaHookMethod( 353 | jni, _class, method, 354 | reinterpret_cast(replace), 355 | reinterpret_cast(result) 356 | ); 357 | } 358 | 359 | #endif 360 | 361 | static inline void MSAndroidGetPackage(JNIEnv *jni, jobject global, const char *name, jobject &local, jobject &loader) { 362 | jclass Context(jni->FindClass("android/content/Context")); 363 | jmethodID Context$createPackageContext(jni->GetMethodID(Context, "createPackageContext", "(Ljava/lang/String;I)Landroid/content/Context;")); 364 | jmethodID Context$getClassLoader(jni->GetMethodID(Context, "getClassLoader", "()Ljava/lang/ClassLoader;")); 365 | 366 | jstring string(jni->NewStringUTF(name)); 367 | local = jni->CallObjectMethod(global, Context$createPackageContext, string, 3); 368 | loader = jni->CallObjectMethod(local, Context$getClassLoader); 369 | } 370 | 371 | static inline jclass MSJavaFindClass(JNIEnv *jni, jobject loader, const char *name) { 372 | jclass Class(jni->FindClass("java/lang/Class")); 373 | jmethodID Class$forName(jni->GetStaticMethodID(Class, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;")); 374 | 375 | jstring string(jni->NewStringUTF(name)); 376 | jobject _class(jni->CallStaticObjectMethod(Class, Class$forName, string, JNI_TRUE, loader)); 377 | if (jni->ExceptionCheck()) 378 | return NULL; 379 | 380 | return reinterpret_cast(_class); 381 | } 382 | 383 | _disused static void MSJavaCleanWeak(void *data, JNIEnv *jni, void *value) { 384 | jni->DeleteWeakGlobalRef(reinterpret_cast(value)); 385 | } 386 | 387 | #endif 388 | 389 | #define MSHook(type, name, args...) \ 390 | _disused static type (*_ ## name)(args); \ 391 | static type $ ## name(args) 392 | 393 | #define MSJavaHook(type, name, arg0, args...) \ 394 | _disused static type (*_ ## name)(JNIEnv *jni, arg0, ...); \ 395 | static type $ ## name(JNIEnv *jni, arg0, ## args) 396 | 397 | #ifdef __cplusplus 398 | #define MSHake(name) \ 399 | &$ ## name, &_ ## name 400 | #else 401 | #define MSHake(name) \ 402 | &$ ## name, (void **) &_ ## name 403 | #endif 404 | 405 | #define SubstrateConcat_(lhs, rhs) \ 406 | lhs ## rhs 407 | #define SubstrateConcat(lhs, rhs) \ 408 | SubstrateConcat_(lhs, rhs) 409 | 410 | #ifdef __APPLE__ 411 | #define SubstrateSection \ 412 | __attribute__((__section__("__TEXT, __substrate"))) 413 | #else 414 | #define SubstrateSection \ 415 | __attribute__((__section__(".substrate"))) 416 | #endif 417 | 418 | #ifdef __APPLE__ 419 | #define MSFilterCFBundleID "Filter:CFBundleID" 420 | #define MSFilterObjC_Class "Filter:ObjC.Class" 421 | #endif 422 | 423 | #define MSFilterLibrary "Filter:Library" 424 | #define MSFilterExecutable "Filter:Executable" 425 | 426 | #define MSConfig(name, value) \ 427 | extern const char SubstrateConcat(_substrate_, __LINE__)[] SubstrateSection = name "=" value; 428 | 429 | #ifdef __cplusplus 430 | #define MSInitialize \ 431 | static void _MSInitialize(void); \ 432 | namespace { static class $MSInitialize { public: _finline $MSInitialize() { \ 433 | _MSInitialize(); \ 434 | } } $MSInitialize; } \ 435 | static void _MSInitialize() 436 | #else 437 | #define MSInitialize \ 438 | __attribute__((__constructor__)) static void _MSInitialize(void) 439 | #endif 440 | 441 | #define Foundation_f "/System/Library/Frameworks/Foundation.framework/Foundation" 442 | #define UIKit_f "/System/Library/Frameworks/UIKit.framework/UIKit" 443 | #define JavaScriptCore_f "/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore" 444 | #define IOKit_f "/System/Library/Frameworks/IOKit.framework/IOKit" 445 | 446 | #endif//SUBSTRATE_H_ --------------------------------------------------------------------------------