source: trunk/Cocoa/F-Script Anywhere/Source/DeVercruesseProcessManager.m@ 352

Last change on this file since 352 was 342, checked in by rchin, 17 years ago

Leopard compatibility changes:

  • Removed some icon caching code that was causing crashes (not sure we really needed those optimizations anyway -- doesn't appear to affect performance)
  • Added code to automatically try to add certificate to keychain, for new code signing behavior (replaces previous procmod nonesense).
  • Note that the enclosed public certificate is mine, and so it will need to be signed by me. In the case that someone else wants to distribute this binary, please replace Certficiate.cer with your own public certificate, and then make sure o code sign the binary after it is built.
File size: 7.6 KB
Line 
1//
2// DeVercruesseProcessManager.m
3//
4// Created by Frank Vercruesse on Wed Apr 04 2001.
5// Copyright (c) 2001 Frank Vercruesse.
6//
7//
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU General Public License
10// as published by the Free Software Foundation; either version 2
11// of the License, or (at your option) any later version.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21// 02111-1307, USA.
22
23#import "DeVercruesseProcessManager.h"
24
25
26@implementation DeVercruesseProcessManager
27
28static DeVercruesseProcessManager *defaultManager = nil;
29
30+ (id)defaultManager
31{
32 return ( defaultManager ? defaultManager : [[self alloc] init] );
33}
34
35- (id)init
36{
37 if( defaultManager )
38 {
39 [self dealloc];
40 }
41 else if( [super init] )
42 {
43 processes = [[NSMutableSet alloc] initWithCapacity:30];
44 defaultManager = self;
45 }
46
47 return defaultManager;
48}
49
50- (void)dealloc
51{
52 [processes release];
53
54 if( self == defaultManager )
55 defaultManager = nil;
56 [super dealloc];
57}
58
59
60- (DeVercruesseProcess*)currentProcess
61{
62 ProcessSerialNumber sn;
63 DeVercruesseProcess *p, *q;
64
65
66 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
67
68 if( p = [DeVercruesseProcess processWithPSN:&sn] )
69 {
70 if( q = [processes member:p] )
71 p = q;
72// else
73// [processes addObject:p];
74 }
75
76 return p;
77}
78
79- (DeVercruesseProcess*)frontProcess
80{
81 ProcessSerialNumber sn;
82 DeVercruesseProcess *p, *q;
83
84
85 if( CPSGetFrontProcess( (CPSProcessSerNum*) &sn) != noErr )
86 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
87
88 if( p = [DeVercruesseProcess processWithPSN:&sn] )
89 {
90 if( q = [processes member:p] )
91 p = q;
92// else
93// [processes addObject:p];
94 }
95
96 return p;
97}
98
99- (DeVercruesseProcess*)nextToFrontProcess
100{
101 ProcessSerialNumber sn;
102 DeVercruesseProcess *p, *q;
103
104
105 if( CPSGetNextToFrontProcess( (CPSProcessSerNum*) &sn) != noErr )
106 CPSGetCurrentProcess( (CPSProcessSerNum*) &sn);
107
108 if( p = [DeVercruesseProcess processWithPSN:&sn] )
109 {
110 if( q = [processes member:p] )
111 p = q;
112// else
113// [processes addObject:p];
114 }
115
116 return p;
117}
118
119- (DeVercruesseProcess*)anyNoBGOnlyProcess
120{
121 ProcessSerialNumber sn;
122 DeVercruesseProcess *p, *q;
123
124
125 sn.highLongOfPSN = 0;
126 sn.lowLongOfPSN = kNoProcess;
127
128 while( CPSGetNextProcess( (CPSProcessSerNum*) &sn) == noErr )
129 {
130 if( (p = [DeVercruesseProcess processWithPSN:&sn]) && ![p isBackgroundOnly] )
131 {
132 if( q = [processes member:p] )
133 p = q;
134// else
135// [processes addObject:p];
136
137 return p;
138 }
139 }
140
141 return nil;
142}
143
144
145- (NSArray*)processes
146{
147 [self update];
148
149 return [NSArray arrayWithArray:[processes allObjects]];
150}
151
152
153- (void)update
154{
155 ProcessSerialNumber sn;
156 NSMutableSet *temp;
157 DeVercruesseProcess *process, *existingProcess;
158 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
159
160 sn.highLongOfPSN = 0;
161 sn.lowLongOfPSN = kNoProcess;
162
163 temp = [[NSMutableSet alloc] initWithCapacity: 30];
164
165 while( CPSGetNextProcess( (CPSProcessSerNum*) &sn) == noErr )
166 {
167 // njr removed background-only check because we still get process launch notifications for background-only apps...
168 if ( (process = [[DeVercruesseProcess alloc] initWithPSN:&sn]) != nil) {
169 if ( (existingProcess = [processes member: process]) != nil ) {
170 [temp addObject: existingProcess];
171 } else {
172 [temp addObject: process];
173 }
174 [process release];
175 }
176 }
177
178 [processes setSet:[temp autorelease]];
179 [pool release];
180}
181
182
183- (void)showAll
184{
185 ProcessSerialNumber *psn;
186
187
188 psn = [[self frontProcess] psn];
189
190 CPSPostShowAllReq( (CPSProcessSerNum*) psn );
191 CPSPostShowReq( (CPSProcessSerNum*) psn );
192}
193
194- (void)hideOthers
195{
196 [self hideOthers:YES];
197}
198
199- (void)hideOthers:(BOOL)ignoreRules
200{
201 NSArray *p;
202 NSEnumerator *enumerator;
203 DeVercruesseProcess *process;
204
205
206 p = [[ProcessMgr processes] retain];
207
208 enumerator = [p objectEnumerator];
209
210 while( process = [enumerator nextObject] )
211 {
212 if( ![process isHidden] && ![process isEqualToFront] &&
213 (ignoreRules ||
214 ![self checkRule:@"optDontHide" withProcess:process]) )
215 {
216 [process hide];
217 }
218 }
219
220 [p release];
221}
222
223- (void)hideFront
224{
225 [[self frontProcess] hide];
226}
227
228- (void)setFront:(DeVercruesseProcess*)process
229{
230 [process makeFront];
231}
232
233// rules stuff
234
235- (void)setRules:(NSArray*)r
236{
237 NSEnumerator *enumerator;
238 NSDictionary *dict;
239 NSMutableSet *hasRules, *keys;
240 NSMutableDictionary *newRules;
241
242
243 newRules = [[NSMutableDictionary alloc] initWithCapacity:10];
244
245 hasRules = [[NSMutableSet alloc] initWithCapacity:10];
246 [newRules setObject:hasRules forKey:@"_hasRules"];
247 [hasRules release];
248
249 keys = [[NSMutableSet alloc] initWithCapacity:10];
250 [newRules setObject:keys forKey:@"_keys"];
251 [keys release];
252
253 enumerator = [r objectEnumerator];
254 while( dict = [enumerator nextObject] )
255 {
256 NSString *identifier, *key;
257 NSEnumerator *keyEnumerator;
258 NSDictionary *d2;
259
260 identifier = [[NSString alloc] initWithFormat:@"%@%.8X%.8X", [dict objectForKey:@"identifier"], [[dict objectForKey:@"type"] unsignedIntValue], [[dict objectForKey:@"creator"] unsignedIntValue]];
261 [hasRules addObject:identifier];
262 [identifier release];
263
264 d2 = [dict objectForKey:@"rules"];
265 keyEnumerator = [d2 keyEnumerator];
266 while( key = [keyEnumerator nextObject] )
267 {
268 NSMutableDictionary *d3;
269
270 if( !(d3 = [newRules objectForKey:key]) )
271 {
272 [keys addObject:key];
273
274 d3 = [[NSMutableDictionary alloc] initWithCapacity:10];
275 [newRules setObject:d3 forKey:key];
276 [d3 release];
277 }
278
279 [d3 setObject:[d2 objectForKey:key] forKey:identifier];
280 }
281 }
282
283 [rules release];
284 rules = [[NSDictionary alloc] initWithDictionary:newRules];
285
286 [newRules release];
287}
288
289- (BOOL)anyRulesForProcess:(DeVercruesseProcess*)process
290{
291 if( !process || !rules )
292 return NO;
293
294 return [[rules objectForKey:@"_hasRules"] containsObject:[process identifier]];
295}
296
297- (BOOL)checkRule:(NSString*)ruleKey withProcess:(DeVercruesseProcess*)process
298{
299 if( !ruleKey || !process || !rules )
300 return NO;
301
302 return [[rules objectForKey:ruleKey] containsObject:[process identifier]];
303}
304
305- (NSSet*)processIdentifiersForRule:(NSString*)ruleKey
306{
307 return [rules objectForKey:ruleKey];
308}
309
310- (int)optionsForRule:(NSString*)ruleKey withProcess:(DeVercruesseProcess*)process
311{
312 NSDictionary *rule;
313 NSNumber *options;
314
315
316 if( !(rule = [rules objectForKey:ruleKey]) )
317 return 2; // use global setting
318
319 if( !(options = [rule objectForKey:[process identifier]]) )
320 return 2; // use global setting
321
322 return [options intValue];
323}
324
325@end
Note: See TracBrowser for help on using the repository browser.