-
Notifications
You must be signed in to change notification settings - Fork 2
/
Tweak.xm
231 lines (182 loc) · 6.04 KB
/
Tweak.xm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
//old preferences file
#define BLACKLIST @"/var/mobile/Library/Preferences/com.gnos.BadgeClearer.blacklist.plist"
//new preferences file
#define PREFERENCESFILE @"/var/mobile/Library/Preferences/com.gnos.BadgeClearer.plist"
#define GNPreferencesChangedNotification "com.gnos.BadgeClearer.preferences.changed"
typedef enum {
SBIconLocationHomeScreen = 0,
SBIconLocationDock = 1,
SBIconLocationSwitcher = 2
} SBIconLocation;
@interface SBApplicationIcon
- (int)badgeValue;
- (void)setBadge:(id)badge;
- (NSString *)applicationBundleID;
- (NSString *)displayName;
- (void)launch; // <=iOS 7
- (void)launchFromLocation:(SBIconLocation)location; // =iOS 8
- (void)launchFromLocation:(SBIconLocation)location context:(id)arg2; // >=iOS 9-10
@end
@interface GNUIAlertViewDelegateClass : NSObject <UIAlertViewDelegate> {
}
@end
static GNUIAlertViewDelegateClass *_si;
static BOOL _justLaunch = NO;
static NSDictionary *_prefs = nil;
static SBApplicationIcon *_appIcon = nil;
static SBIconLocation _appLocation = SBIconLocationHomeScreen;
//lang: C
static void GN_updatePreferencesFile(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:BLACKLIST]) {
NSError *error = nil;
if (![fm moveItemAtPath:BLACKLIST toPath:PREFERENCESFILE error:&error]) {
NSLog(@"Failed to move '%@' to '%@': %@", BLACKLIST, PREFERENCESFILE, [error localizedDescription]);
}
}
[pool release];
}
static void GN_createDefaultPreferences(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDictionary *d = [[NSDictionary alloc] initWithObjects:
[NSArray arrayWithObjects:
[NSNumber numberWithBool:YES],
[NSNumber numberWithBool:NO],
nil]
forKeys:
[NSArray arrayWithObjects:
@"enabled",
@"debug",
nil]
];
[d writeToFile:PREFERENCESFILE atomically:YES];
[d release];
[pool release];
}
static void GN_reloadPreferences(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GN_updatePreferencesFile();
if (_prefs != nil) {
[_prefs release];
}
_prefs = [[NSDictionary alloc] initWithContentsOfFile:PREFERENCESFILE]; // Load the plist
//Is PREFERENCESFILE not existent?
if (_prefs == nil) { // create new plist
GN_createDefaultPreferences();
// Load the plist again
_prefs = [[NSDictionary alloc] initWithContentsOfFile:PREFERENCESFILE];
}
[pool release];
}
static inline BOOL GN_keyIsEnabled(NSString *key) {
return [[_prefs objectForKey:key] boolValue];
}
static BOOL GN_applicationIconWithLocationShouldLaunch(SBApplicationIcon *icon, SBIconLocation location) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
_appIcon = icon;
_appLocation = location;
NSString *applicationBundleID = (_appIcon == nil)? @"" : [_appIcon applicationBundleID];
int badgeValue = (_appIcon == nil)? 0 : [_appIcon badgeValue];
BOOL enabled = GN_keyIsEnabled(@"enabled");
BOOL appIsBlacklisted = GN_keyIsEnabled(applicationBundleID);
BOOL r = ((badgeValue != 0) && enabled)? appIsBlacklisted : YES;
_justLaunch = (_justLaunch == NO)? r : YES;
[pool release];
return _justLaunch;
}
static void GN_showAlert(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
BOOL debug = GN_keyIsEnabled(@"debug");
NSString *displayName = (_appIcon == nil)? @"" : [_appIcon displayName];
NSString *applicationBundleID = (_appIcon == nil)? @"" : [_appIcon applicationBundleID];
id launchView = [[%c(UIAlertView) alloc] initWithTitle:(debug? applicationBundleID : displayName)
message:nil
delegate:_si
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Clear Badges", @"Launch app", @"Both", nil];
[launchView show];
[launchView release];
[pool release];
}
//lang: Objective-C
@implementation GNUIAlertViewDelegateClass
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { // after animation
if (_appIcon == nil) {
return;
}
switch (buttonIndex) {
case 3: // "Both" pressed
// Because there is no 'break;', code will continue onto case 2 and then break
[_appIcon setBadge:nil];
case 2: // "Launch app" pressed
// Launch the app, skip all the other checks
_justLaunch = YES;
if (kCFCoreFoundationVersionNumber < 847.20) {// iOS 7
[_appIcon launch];
} else if (kCFCoreFoundationVersionNumber < 1200){// iOS 8
[_appIcon launchFromLocation:_appLocation];
} else {// iOS 9-10
[_appIcon launchFromLocation:_appLocation context:nil];
}
break;
case 1: // "Clear Badges" pressed
// Clear badge count
[_appIcon setBadge:nil];
break;
}
}
@end
//lang: Logos
%hook SBApplicationIcon
// iOS 7
- (void)launch {
if (GN_applicationIconWithLocationShouldLaunch(self, SBIconLocationHomeScreen)) {
_justLaunch = NO; //reset for next launch
%orig();
} else {
GN_showAlert();
}
}
// iOS 8
- (void)launchFromLocation:(SBIconLocation)location {
if (GN_applicationIconWithLocationShouldLaunch(self, location)) {
_justLaunch = NO; //reset for next launch
%orig();
} else {
GN_showAlert();
}
}
// iOS 9-10
- (void)launchFromLocation:(SBIconLocation)location context:(id)context {
if (GN_applicationIconWithLocationShouldLaunch(self, location)) {
_justLaunch = NO; //reset for next launch
%orig();
} else {
GN_showAlert();
}
}
%end
%hook SBNotificationCenterTouchEater
-(void)touchesBegan:(id)arg1 withEvent:(id)arg2 {
%log(@"BCUS");
return %orig;
}
%end
//notification managing
static void GNPreferencesChanged(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GN_reloadPreferences();
[pool release];
}
static void GNPreferencesChangedCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
GNPreferencesChanged();
}
%ctor {
%init();
_si = [[GNUIAlertViewDelegateClass alloc] init];
GNPreferencesChanged();
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, GNPreferencesChangedCallback, CFSTR(GNPreferencesChangedNotification), NULL, CFNotificationSuspensionBehaviorCoalesce);
[pool release];
}