-Adds preferences -Adds credits to prefefrences -Icon for preferences -Share button for sharing to social media. -Code cleanup -Thanks @skittyblock!master
ARCHS = arm64 arm64e | ARCHS = arm64 arm64e | ||||
SDK = iPhoneOS13.0 | |||||
SDK = iPhoneOS12.4 | |||||
FINALPACKAGE = 1 | FINALPACKAGE = 1 | ||||
export TARGET = iphone:clang:13.0:latest | |||||
include $(THEOS)/makefiles/common.mk | include $(THEOS)/makefiles/common.mk | ||||
TWEAK_NAME = ZenithDark | TWEAK_NAME = ZenithDark | ||||
ZenithDark_FILES = Tweak.xm | ZenithDark_FILES = Tweak.xm | ||||
ZenithDark_CFLAGS = -fobjc-arc | |||||
ZenithDark_FRAMEWORKS = UIKit CoreGraphics | ZenithDark_FRAMEWORKS = UIKit CoreGraphics | ||||
include $(THEOS_MAKE_PATH)/tweak.mk | include $(THEOS_MAKE_PATH)/tweak.mk | ||||
after-install:: | |||||
install.exec "sbreload" | |||||
SUBPROJECTS += zenithdarkprefs | SUBPROJECTS += zenithdarkprefs | ||||
include $(THEOS_MAKE_PATH)/aggregate.mk | include $(THEOS_MAKE_PATH)/aggregate.mk | ||||
after-install:: | |||||
install.exec "sbreload" |
#import "ZenithDark.h" | #import "ZenithDark.h" | ||||
static BOOL enabled; | |||||
static void loadPrefs() { | |||||
static NSMutableDictionary *settings; | |||||
CFArrayRef keyList = CFPreferencesCopyKeyList(CFSTR("com.mac-user669.zenithdarkprefs"), kCFPreferencesCurrentUser, kCFPreferencesAnyHost); | |||||
if (keyList) { | |||||
settings = (NSMutableDictionary *)CFBridgingRelease(CFPreferencesCopyMultiple(keyList, CFSTR("com.mac-user669.zenithdarkprefs"), kCFPreferencesCurrentUser, kCFPreferencesAnyHost)); | |||||
CFRelease(keyList); | |||||
} else { | |||||
settings = [NSMutableDictionary dictionaryWithContentsOfFile:@"/var/mobile/Library/Preferences/com.mac-user669.zenithdarkprefs.plist"]; | |||||
} | |||||
enabled = [([settings objectForKey:@"enabled"] ? [settings objectForKey:@"enabled"] : @(YES)) boolValue]; | |||||
} | |||||
// We then hook the class in this case Zenith's grabber view is called “ZNGrabberAccessoryView” | // We then hook the class in this case Zenith's grabber view is called “ZNGrabberAccessoryView” | ||||
%hook ZNGrabberAccessoryView | %hook ZNGrabberAccessoryView | ||||
// this is called when iOS 13's dark mode is enabled! | |||||
// this is called when iOS 13's dark mode is enabled! | |||||
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { | -(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { | ||||
if (enabled) { | |||||
%orig(previousTraitCollection); | |||||
%orig(previousTraitCollection); | |||||
if (kEnabled) { | |||||
// if the tweak is enabled and the version is iOS 13 or later run our code | |||||
if (@available(iOS 13, *)) { | if (@available(iOS 13, *)) { | ||||
if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { | if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { | ||||
[self setBackgroundColor:kDarkModeColor]; | [self setBackgroundColor:kDarkModeColor]; | ||||
else { | else { | ||||
[self setBackgroundColor:kLightModeColor]; | [self setBackgroundColor:kLightModeColor]; | ||||
} | |||||
} | } | ||||
} | } | ||||
%orig; | |||||
} | } | ||||
else { | |||||
%orig(previousTraitCollection); | |||||
} | |||||
} | |||||
// the method we modify is this method that is called from UIImageView to set the backgroundColor of the image view. | // the method we modify is this method that is called from UIImageView to set the backgroundColor of the image view. | ||||
// Since the grabber view is of type UIImageView we can modify this method :) | // Since the grabber view is of type UIImageView we can modify this method :) | ||||
-(void)setBackgroundColor:(UIColor *)backgroundColor { | -(void)setBackgroundColor:(UIColor *)backgroundColor { | ||||
if (enabled) { | |||||
%orig; | |||||
if (kEnabled) { | |||||
// by default have our tweak overide this. | // by default have our tweak overide this. | ||||
if (@available(iOS 13, *)) { | if (@available(iOS 13, *)) { | ||||
if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { | if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { | ||||
%orig(kDarkModeColor); | %orig(kDarkModeColor); | ||||
} | } | ||||
} | |||||
else { | else { | ||||
%orig; | %orig; | ||||
} | |||||
} | } | ||||
} | } | ||||
%orig; | |||||
} | } | ||||
// we need to make sure we tell theos that we are finished hooking this class not doing so with cause the end of the world :P | // we need to make sure we tell theos that we are finished hooking this class not doing so with cause the end of the world :P | ||||
%end | %end | ||||
// our constructor | |||||
%ctor { | |||||
loadPrefs(); | |||||
// Load preferences to make sure changes are written to the plist | |||||
static void loadPrefs() { | |||||
// Thanks to skittyblock! | |||||
CFArrayRef keyList = CFPreferencesCopyKeyList(CFSTR("com.mac-user669.zenithdark"), kCFPreferencesCurrentUser, kCFPreferencesAnyHost); | |||||
if(keyList) { | |||||
prefs = (NSMutableDictionary *)CFPreferencesCopyMultiple(keyList, CFSTR("com.mac-user669.zenithdark"), kCFPreferencesCurrentUser, kCFPreferencesAnyHost); | |||||
CFRelease(keyList); | |||||
} else { | |||||
prefs = nil; | |||||
} | |||||
// We use this to make sure we load Zenith's dynamic library at runtime so we can modify it with our tweak. | |||||
if (!prefs) { | |||||
prefs = [NSMutableDictionary dictionaryWithContentsOfFile:PLIST_PATH]; | |||||
} | |||||
//our preference values that write to a plist file when a user selects somethings | |||||
kEnabled = [([prefs objectForKey:@"kEnabled"] ?: @(YES)) boolValue]; | |||||
} | |||||
// thanks to skittyblock! | |||||
static void PreferencesChangedCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { | |||||
loadPrefs(); | |||||
} | |||||
// our constructor | |||||
%ctor { | |||||
// load our prefs | |||||
loadPrefs(); | |||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback) PreferencesChangedCallback, CFSTR("com.mac-user669.zenithdark.prefschanged"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); | |||||
// We use this to make sure we load Zenith's dynamic library at runtime so we can modify it with our tweak. | |||||
dlopen ("/Library/MobileSubstrate/DynamicLibraries/Zenith.dylib", RTLD_NOW); | dlopen ("/Library/MobileSubstrate/DynamicLibraries/Zenith.dylib", RTLD_NOW); | ||||
} | } |
Copyright 2020 J.K. Hayslip (@iKilledAppl3) & ToxicAppl3 INSDC/iKilledAppl3 LLC. | Copyright 2020 J.K. Hayslip (@iKilledAppl3) & ToxicAppl3 INSDC/iKilledAppl3 LLC. | ||||
All code was written for learning purposes and credit must be given to the original author. | All code was written for learning purposes and credit must be given to the original author. | ||||
Written for Cooper Hull, @(mac-user669). | |||||
Written for Cooper Hull, (@mac-user669). | |||||
ZenithDark Header file to keep the tweak.x file clean! | ZenithDark Header file to keep the tweak.x file clean! | ||||
@interface ZNGrabberAccessoryView : UIImageView | @interface ZNGrabberAccessoryView : UIImageView | ||||
@end | @end | ||||
// a boolean value to store to the tweak's property list path to see if the user has enabled or disabled the tweak. | |||||
BOOL kEnabled; | |||||
//Prefs dictionary | |||||
NSMutableDictionary *prefs; | |||||
// Dark Zenith color we are using macros so we can call it later if need be. | // Dark Zenith color we are using macros so we can call it later if need be. | ||||
#define kDarkModeColor [UIColor colorWithWhite:0.0 alpha:0.44] | #define kDarkModeColor [UIColor colorWithWhite:0.0 alpha:0.44] | ||||
// Stock Zenith color we are using macros so we can call it later if need be. | // Stock Zenith color we are using macros so we can call it later if need be. | ||||
#define kLightModeColor [UIColor colorWithWhite:1.0 alpha:0.7] | #define kLightModeColor [UIColor colorWithWhite:1.0 alpha:0.7] | ||||
// the PLIST path where all user settings are stored. | |||||
#define PLIST_PATH @"/var/mobile/Library/Preferences/com.mac-user669.zenithdark.plist" |
Package: com.mac-user669.zenithdark | Package: com.mac-user669.zenithdark | ||||
Version: 1.0 | |||||
Version: 1.0.1-1 | |||||
Architecture: iphoneos-arm | Architecture: iphoneos-arm | ||||
Maintainer: mac-user669 | Maintainer: mac-user669 | ||||
Depends: mobilesubstrate, com.muirey03.zenith, firmware (>=13.0) | |||||
Depends: mobilesubstrate, preferenceloader, com.muirey03.zenith, firmware (>=13.0) | |||||
Section: Tweaks | Section: Tweaks | ||||
Description: Changes Zeniths tabs to a dark blur | Description: Changes Zeniths tabs to a dark blur | ||||
Author: mac-user669 | Author: mac-user669 |
ARCHS = arm64 arm64e | |||||
SDK = iPhoneOS12.4 | |||||
FINALPACKAGE = 1 | |||||
include $(THEOS)/makefiles/common.mk | include $(THEOS)/makefiles/common.mk | ||||
ARCHS = arm64 arm64e | |||||
export TARGET = iphone:clang:13.0:latest | |||||
BUNDLE_NAME = ZenithDarkPrefs | BUNDLE_NAME = ZenithDarkPrefs | ||||
ZenithDarkPrefs_FILES = ZnthDrkRootListController.m | |||||
ZenithDarkPrefs_FILES = ZNDarkPrefsRootListController.m | |||||
ZenithDarkPrefs_INSTALL_PATH = /Library/PreferenceBundles | ZenithDarkPrefs_INSTALL_PATH = /Library/PreferenceBundles | ||||
ZenithDarkPrefs_FRAMEWORKS = UIKit | ZenithDarkPrefs_FRAMEWORKS = UIKit | ||||
ZenithDarkPrefs_PRIVATE_FRAMEWORKS = Preferences | ZenithDarkPrefs_PRIVATE_FRAMEWORKS = Preferences | ||||
ZenithDarkPrefs_CFLAGS = -fobjc-arc | |||||
include $(THEOS_MAKE_PATH)/bundle.mk | include $(THEOS_MAKE_PATH)/bundle.mk | ||||
<key>CFBundleVersion</key> | <key>CFBundleVersion</key> | ||||
<string>1.0</string> | <string>1.0</string> | ||||
<key>NSPrincipalClass</key> | <key>NSPrincipalClass</key> | ||||
<string>ZnthDrkRootListController</string> | |||||
<string>ZNDarkPrefsRootListController</string> | |||||
</dict> | </dict> | ||||
</plist> | </plist> |
<key>cell</key> | <key>cell</key> | ||||
<string>PSGroupCell</string> | <string>PSGroupCell</string> | ||||
<key>label</key> | <key>label</key> | ||||
<string>Enable</string> | |||||
<string>Enable Tweak</string> | |||||
<key>footerText</key> | |||||
<string>Enable to give Zenith's pull tabs a dark look!</string> | |||||
</dict> | </dict> | ||||
<dict> | <dict> | ||||
<key>PostNotification</key> | |||||
<string>com.mac-user669.zenithdark.prefschanged</string> | |||||
<key>cell</key> | <key>cell</key> | ||||
<string>PSSwitchCell</string> | <string>PSSwitchCell</string> | ||||
<key>default</key> | <key>default</key> | ||||
<true/> | <true/> | ||||
<key>defaults</key> | <key>defaults</key> | ||||
<string>com.mac-user669.zenithdarkprefs</string> | |||||
<string>com.mac-user669.zenithdark</string> | |||||
<key>key</key> | <key>key</key> | ||||
<string>enabled</string> | |||||
<string>kEnabled</string> | |||||
<key>label</key> | <key>label</key> | ||||
<string>Enable</string> | <string>Enable</string> | ||||
</dict> | </dict> | ||||
<dict> | <dict> | ||||
<key>cell</key> | <key>cell</key> | ||||
<string>PSGroupCell</string> | <string>PSGroupCell</string> | ||||
<key>label</key> | |||||
<string>Credits</string> | |||||
<key>footerText</key> | |||||
<string>Conceptualized by your yours truly.</string> | |||||
</dict> | |||||
<dict> | |||||
<key>icon</key> | |||||
<string>mac-user669.png</string> | |||||
<key>cell</key> | |||||
<string>PSButtonCell</string> | |||||
<key>label</key> | |||||
<string>mac-user669 (@mac-user669)</string> | |||||
<key>action</key> | |||||
<string>followMe</string> | |||||
</dict> | |||||
<dict> | |||||
<key>cell</key> | |||||
<string>PSGroupCell</string> | |||||
<key>footerText</key> | |||||
<string>Coded most of the tweak.</string> | |||||
</dict> | |||||
<dict> | |||||
<key>icon</key> | |||||
<string>iKA.png</string> | |||||
<key>cell</key> | |||||
<string>PSButtonCell</string> | |||||
<key>label</key> | |||||
<string>J.K. Hayslip (@iKilledAppl3) </string> | |||||
<key>action</key> | |||||
<string>followiKA</string> | |||||
</dict> | |||||
<dict> | |||||
<key>cell</key> | |||||
<string>PSGroupCell</string> | |||||
<key>footerText</key> | |||||
<string>Helped with some of our preferences code and amongst other things.</string> | |||||
</dict> | |||||
<dict> | |||||
<key>icon</key> | |||||
<string>skitty.png</string> | |||||
<key>cell</key> | |||||
<string>PSButtonCell</string> | |||||
<key>label</key> | |||||
<string>Skitty (@skittyblock) </string> | |||||
<key>action</key> | |||||
<string>followSkitty</string> | |||||
</dict> | |||||
<dict> | |||||
<key>cell</key> | |||||
<string>PSGroupCell</string> | |||||
<key>label</key> | |||||
<string>Apply Changes</string> | |||||
<key>footerText</key> | |||||
<string>A Respring is needed to apply changes!</string> | |||||
</dict> | </dict> | ||||
<dict> | <dict> | ||||
<key>cell</key> | <key>cell</key> | ||||
<string>PSButtonCell</string> | <string>PSButtonCell</string> | ||||
<key>label</key> | <key>label</key> | ||||
<string>@mac_user669</string> | |||||
<string>Respring</string> | |||||
<key>action</key> | <key>action</key> | ||||
<string>openTwitter</string> | |||||
<string>doAFancyRespring</string> | |||||
</dict> | </dict> | ||||
</array> | </array> | ||||
<key>title</key> | <key>title</key> | ||||
<string>ZenithDark</string> | <string>ZenithDark</string> | ||||
</dict> | </dict> | ||||
</plist> | |||||
</plist> |
#import <Preferences/PSListController.h> | |||||
@import UIKit; | |||||
// image for share button | |||||
#define kImagePath @"/Library/Application Support/ZenithDark/ZNDark.png" | |||||
@interface ZNDarkPrefsRootListController : PSListController | |||||
@property (nonatomic, strong) UIBlurEffect *respringBlur; | |||||
@property (nonatomic, strong) UIVisualEffectView *respringEffectView; | |||||
@property (nonatomic, strong) UIWindow *mainAppRootWindow; | |||||
@end | |||||
// we use this to respring our device! | |||||
@interface NSTask : NSObject | |||||
@property (copy) NSArray *arguments; | |||||
@property (copy) NSString *currentDirectoryPath; | |||||
@property (copy) NSDictionary *environment; | |||||
@property (copy) NSString *launchPath; | |||||
@property (readonly) int processIdentifier; | |||||
@property (retain) id standardError; | |||||
@property (retain) id standardInput; | |||||
@property (retain) id standardOutput; | |||||
+ (id)currentTaskDictionary; | |||||
+ (id)launchedTaskWithDictionary:(id)arg1; | |||||
+ (id)launchedTaskWithLaunchPath:(id)arg1 arguments:(id)arg2; | |||||
- (id)init; | |||||
- (void)interrupt; | |||||
- (bool)isRunning; | |||||
- (void)launch; | |||||
- (bool)resume; | |||||
- (bool)suspend; | |||||
- (void)terminate; | |||||
@end |
#import "ZNDarkPrefsRootListController.h" | |||||
@implementation ZNDarkPrefsRootListController | |||||
-(void)viewWillAppear:(BOOL)animated { | |||||
[super viewWillAppear:animated]; | |||||
// share button for our tweak :P | |||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(shareTapped)]; | |||||
} | |||||
//share button action | |||||
- (void)shareTapped { | |||||
NSString *shareText = @"Turn off the lights! It's too bright! Get dark tabs for #Zenith (@Muirey03) by using #ZenithDark from @mac_user669 and @iKilledAppl3! https://mac-user669.github.io/repo/"; | |||||
UIImage *image = [UIImage imageWithContentsOfFile:kImagePath]; | |||||
NSArray * itemsToShare = @[shareText, image]; | |||||
UIActivityViewController *controller = [[UIActivityViewController alloc]initWithActivityItems:itemsToShare applicationActivities:nil]; | |||||
// and present it | |||||
[self presentActivityController:controller]; | |||||
} | |||||
- (void)presentActivityController:(UIActivityViewController *)controller { | |||||
// for iPad: make the presentation a Popover | |||||
controller.modalPresentationStyle = UIModalPresentationPopover; | |||||
[self presentViewController:controller animated:YES completion:nil]; | |||||
UIPopoverPresentationController *popController = [controller popoverPresentationController]; | |||||
popController.permittedArrowDirections = UIPopoverArrowDirectionAny; | |||||
popController.barButtonItem = self.navigationItem.rightBarButtonItem; | |||||
} | |||||
- (NSArray *)specifiers { | |||||
if (!_specifiers) { | |||||
_specifiers = [[self loadSpecifiersFromPlistName:@"Root" target:self] retain]; | |||||
} | |||||
return _specifiers; | |||||
} | |||||
-(void)followMe { | |||||
NSURL *twitter = [NSURL URLWithString:@"https://twitter.com/mac_user669"]; | |||||
[[UIApplication sharedApplication] openURL:twitter options:@{} completionHandler:nil]; | |||||
} | |||||
-(void)followiKA { | |||||
NSURL *twitter = [NSURL URLWithString:@"https://twitter.com/iKilledAppl3"]; | |||||
[[UIApplication sharedApplication] openURL:twitter options:@{} completionHandler:nil]; | |||||
} | |||||
-(void)followSkitty { | |||||
NSURL *twitter = [NSURL URLWithString:@"https://twitter.com/SkittyBlock"]; | |||||
[[UIApplication sharedApplication] openURL:twitter options:@{} completionHandler:nil]; | |||||
} | |||||
-(void)respring { | |||||
NSTask *task = [[[NSTask alloc] init] autorelease]; | |||||
[task setLaunchPath:@"/usr/bin/killall"]; | |||||
[task setArguments:[NSArray arrayWithObjects:@"backboardd", nil]]; | |||||
[task launch]; | |||||
} | |||||
-(void)doAFancyRespring { | |||||
UIAlertController *confirmRespringAlert = [UIAlertController alertControllerWithTitle:@"Apply Settings?" message:@"This will respring your device." preferredStyle:UIAlertControllerStyleActionSheet]; | |||||
UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"Respring" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { | |||||
// blur then respring our device! | |||||
self.mainAppRootWindow = [UIApplication sharedApplication].keyWindow; | |||||
self.respringBlur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; | |||||
self.respringEffectView = [[UIVisualEffectView alloc] initWithEffect:self.respringBlur]; | |||||
self.respringEffectView.frame = [[UIScreen mainScreen] bounds]; | |||||
[self.mainAppRootWindow addSubview:self.respringEffectView]; | |||||
[UIView beginAnimations:nil context:NULL]; | |||||
[UIView setAnimationDuration:5.0]; | |||||
[self.respringEffectView setAlpha:0]; | |||||
[UIView commitAnimations]; | |||||
[self performSelector:@selector(respring) withObject:nil afterDelay:3.0]; | |||||
}]; | |||||
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; | |||||
[confirmRespringAlert addAction:cancel]; | |||||
[confirmRespringAlert addAction:confirm]; | |||||
[self presentViewController:confirmRespringAlert animated:YES completion:nil]; | |||||
} | |||||
@end |
#import <Preferences/PSListController.h> | |||||
@interface ZnthDrkRootListController : PSListController | |||||
@end |
#import "ZnthDrkRootListController.h" | |||||
#import <spawn.h> | |||||
@implementation ZnthDrkRootListController | |||||
- (void)viewWillAppear:(BOOL)animated { | |||||
[super viewWillAppear:animated]; | |||||
UIBarButtonItem *applyButton = [[UIBarButtonItem alloc] initWithTitle:@"Apply" style:UIBarButtonItemStylePlain target:self action:@selector(respringDevice)]; | |||||
self.navigationItem.rightBarButtonItem = applyButton; | |||||
} | |||||
- (NSArray *)specifiers { | |||||
if (!_specifiers) { | |||||
_specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self]; | |||||
} | |||||
return _specifiers; | |||||
} | |||||
- (void) respringDevice { | |||||
UIAlertController *confirmRespringAlert = [UIAlertController alertControllerWithTitle:@"Apply settings?" message:@"This will respring your device" preferredStyle:UIAlertControllerStyleAlert]; | |||||
UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { | |||||
pid_t pid; | |||||
const char *argv[] = {"sbreload", NULL}; | |||||
posix_spawn(&pid, "/usr/bin/sbreload", NULL, NULL, (char* const*)argv, NULL); | |||||
}]; | |||||
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; | |||||
[confirmRespringAlert addAction:cancel]; | |||||
[confirmRespringAlert addAction:confirm]; | |||||
[self presentViewController:confirmRespringAlert animated:YES completion:nil]; | |||||
} | |||||
-(void)openTwitter { | |||||
NSURL *twitter = [NSURL URLWithString:@"https://twitter.com/mac_user669"]; | |||||
[[UIApplication sharedApplication] openURL:twitter options:@{} completionHandler:nil]; | |||||
} | |||||
@end |
<key>cell</key> | <key>cell</key> | ||||
<string>PSLinkCell</string> | <string>PSLinkCell</string> | ||||
<key>detail</key> | <key>detail</key> | ||||
<string>ZnthDrkRootListController</string> | |||||
<string>ZNDarkPrefsRootListController</string> | |||||
<key>icon</key> | <key>icon</key> | ||||
<string>icon.png</string> | |||||
<string>ZenithDark.png</string> | |||||
<key>isController</key> | <key>isController</key> | ||||
<true/> | <true/> | ||||
<key>label</key> | <key>label</key> | ||||
<string>ZenithDarkPrefs</string> | |||||
<string>ZenithDark</string> | |||||
</dict> | </dict> | ||||
</dict> | </dict> | ||||
</plist> | </plist> |