-Adds preferences -Adds credits to prefefrences -Icon for preferences -Share button for sharing to social media. -Code cleanup -Thanks @skittyblock!master
@@ -1,19 +1,18 @@ | |||
ARCHS = arm64 arm64e | |||
SDK = iPhoneOS13.0 | |||
SDK = iPhoneOS12.4 | |||
FINALPACKAGE = 1 | |||
export TARGET = iphone:clang:13.0:latest | |||
include $(THEOS)/makefiles/common.mk | |||
TWEAK_NAME = ZenithDark | |||
ZenithDark_FILES = Tweak.xm | |||
ZenithDark_CFLAGS = -fobjc-arc | |||
ZenithDark_FRAMEWORKS = UIKit CoreGraphics | |||
include $(THEOS_MAKE_PATH)/tweak.mk | |||
after-install:: | |||
install.exec "sbreload" | |||
SUBPROJECTS += zenithdarkprefs | |||
include $(THEOS_MAKE_PATH)/aggregate.mk | |||
after-install:: | |||
install.exec "sbreload" |
@@ -11,27 +11,14 @@ Written for Cooper Hull, @(mac-user669). | |||
#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” | |||
%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 { | |||
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 (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { | |||
[self setBackgroundColor:kDarkModeColor]; | |||
@@ -39,41 +26,73 @@ static void loadPrefs() { | |||
else { | |||
[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. | |||
// Since the grabber view is of type UIImageView we can modify this method :) | |||
-(void)setBackgroundColor:(UIColor *)backgroundColor { | |||
if (enabled) { | |||
%orig; | |||
if (kEnabled) { | |||
// by default have our tweak overide this. | |||
if (@available(iOS 13, *)) { | |||
if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { | |||
%orig(kDarkModeColor); | |||
} | |||
} | |||
else { | |||
%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 | |||
%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); | |||
} |
@@ -4,7 +4,7 @@ Dark Mode for Zenith's Grabber view! | |||
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. | |||
Written for Cooper Hull, @(mac-user669). | |||
Written for Cooper Hull, (@mac-user669). | |||
ZenithDark Header file to keep the tweak.x file clean! | |||
@@ -19,8 +19,17 @@ ZenithDark Header file to keep the tweak.x file clean! | |||
@interface ZNGrabberAccessoryView : UIImageView | |||
@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. | |||
#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. | |||
#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" |
@@ -1,8 +1,8 @@ | |||
Package: com.mac-user669.zenithdark | |||
Version: 1.0 | |||
Version: 1.0.1-1 | |||
Architecture: iphoneos-arm | |||
Maintainer: mac-user669 | |||
Depends: mobilesubstrate, com.muirey03.zenith, firmware (>=13.0) | |||
Depends: mobilesubstrate, preferenceloader, com.muirey03.zenith, firmware (>=13.0) | |||
Section: Tweaks | |||
Description: Changes Zeniths tabs to a dark blur | |||
Author: mac-user669 |
@@ -1,14 +1,14 @@ | |||
ARCHS = arm64 arm64e | |||
SDK = iPhoneOS12.4 | |||
FINALPACKAGE = 1 | |||
include $(THEOS)/makefiles/common.mk | |||
ARCHS = arm64 arm64e | |||
export TARGET = iphone:clang:13.0:latest | |||
BUNDLE_NAME = ZenithDarkPrefs | |||
ZenithDarkPrefs_FILES = ZnthDrkRootListController.m | |||
ZenithDarkPrefs_FILES = ZNDarkPrefsRootListController.m | |||
ZenithDarkPrefs_INSTALL_PATH = /Library/PreferenceBundles | |||
ZenithDarkPrefs_FRAMEWORKS = UIKit | |||
ZenithDarkPrefs_PRIVATE_FRAMEWORKS = Preferences | |||
ZenithDarkPrefs_CFLAGS = -fobjc-arc | |||
include $(THEOS_MAKE_PATH)/bundle.mk | |||
@@ -19,6 +19,6 @@ | |||
<key>CFBundleVersion</key> | |||
<string>1.0</string> | |||
<key>NSPrincipalClass</key> | |||
<string>ZnthDrkRootListController</string> | |||
<string>ZNDarkPrefsRootListController</string> | |||
</dict> | |||
</plist> |
@@ -8,35 +8,92 @@ | |||
<key>cell</key> | |||
<string>PSGroupCell</string> | |||
<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> | |||
<key>PostNotification</key> | |||
<string>com.mac-user669.zenithdark.prefschanged</string> | |||
<key>cell</key> | |||
<string>PSSwitchCell</string> | |||
<key>default</key> | |||
<true/> | |||
<key>defaults</key> | |||
<string>com.mac-user669.zenithdarkprefs</string> | |||
<string>com.mac-user669.zenithdark</string> | |||
<key>key</key> | |||
<string>enabled</string> | |||
<string>kEnabled</string> | |||
<key>label</key> | |||
<string>Enable</string> | |||
</dict> | |||
<dict> | |||
<key>cell</key> | |||
<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> | |||
<key>cell</key> | |||
<string>PSButtonCell</string> | |||
<key>label</key> | |||
<string>@mac_user669</string> | |||
<string>Respring</string> | |||
<key>action</key> | |||
<string>openTwitter</string> | |||
<string>doAFancyRespring</string> | |||
</dict> | |||
</array> | |||
<key>title</key> | |||
<string>ZenithDark</string> | |||
</dict> | |||
</plist> | |||
</plist> |
@@ -0,0 +1,35 @@ | |||
#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 |
@@ -0,0 +1,101 @@ | |||
#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 |
@@ -1,5 +0,0 @@ | |||
#import <Preferences/PSListController.h> | |||
@interface ZnthDrkRootListController : PSListController | |||
@end |
@@ -1,40 +0,0 @@ | |||
#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 |
@@ -9,13 +9,13 @@ | |||
<key>cell</key> | |||
<string>PSLinkCell</string> | |||
<key>detail</key> | |||
<string>ZnthDrkRootListController</string> | |||
<string>ZNDarkPrefsRootListController</string> | |||
<key>icon</key> | |||
<string>icon.png</string> | |||
<string>ZenithDark.png</string> | |||
<key>isController</key> | |||
<true/> | |||
<key>label</key> | |||
<string>ZenithDarkPrefs</string> | |||
<string>ZenithDark</string> | |||
</dict> | |||
</dict> | |||
</plist> |