source: trunk/Cocoa/Pester/Source/PSAlarmAlertController.m @ 597

Last change on this file since 597 was 597, checked in by Nicholas Riley, 10 years ago

Don't bring all windows of the frontmost application to the front when dismissing an alert.

File size: 3.3 KB
Line 
1//
2//  PSAlarmAlertController.m
3//  Pester
4//
5//  Created by Nicholas Riley on Sat Oct 26 2002.
6//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "PSAlarmAlertController.h"
10#import "PSAlert.h"
11#import "PSAlerts.h"
12
13NSString * const PSAlarmAlertStopNotification = @"PSAlarmAlertStopNotification";
14
15@implementation PSAlarmAlertController
16
17+ (PSAlarmAlertController *)controllerWithTimerExpiredNotification:(NSNotification *)notification;
18{
19    return [[[self alloc] initWithAlarm: [notification object]] autorelease];
20}
21
22+ (IBAction)stopAlerts:(id)sender;
23{
24    [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmAlertStopNotification object: nil];
25}
26
27- (void)_resumeAlarm:(PSAlarm *)alarm;
28{
29    [[NSNotificationCenter defaultCenter] removeObserver: self];
30    [alarm setTimer]; // if snooze not set and not repeating, alarm will die
31    if (frontmostApp.highLongOfPSN != 0 || frontmostApp.lowLongOfPSN != 0) {
32        SetFrontProcessWithOptions(&frontmostApp, kSetFrontProcessFrontWindowOnly);
33        if (appWasHidden)
34            [NSApp hide: self];
35    }
36}
37
38- (void)_alertCompleted:(NSNotification *)notification;
39{
40    PSAlert *alert = [[notification userInfo] objectForKey: @"alert"];
41    unsigned count = [pendingAlerts count];
42    [pendingAlerts removeObject: alert];
43    NSLog(@"removed: %@; still pending: %@", alert, [pendingAlerts description]);
44    NSLog(@"alarm: %@ retainCount %d", [notification object], [[notification object] retainCount]);
45    NSAssert2([pendingAlerts count] == count - 1, @"alert not in set: %@\n%@", alert, notification);
46    if ([pendingAlerts count] == 0) {
47        [self _resumeAlarm: [notification object]];
48        [self release];
49    }
50}
51
52- (void)performAlertsForAlarm:(PSAlarm *)alarm;
53{
54    PSAlerts *alerts = [alarm alerts];
55    NSArray *allAlerts = [alerts allAlerts];
56    if ([allAlerts count] == 0) {
57        [self _resumeAlarm: alarm];
58    } else {
59        pendingAlerts = [[NSMutableSet alloc] init];
60        [pendingAlerts addObjectsFromArray: allAlerts];
61        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_alertCompleted:)
62                                                     name: PSAlarmAlertCompletedNotification object: alarm];
63        [self retain]; // release in _alertCompleted:
64    }
65    [alerts triggerForAlarm: alarm];
66    if ([alerts requirePesterFrontmost] && ![NSApp isActive]) { // restore frontmost process afterward
67        NSDictionary *activeProcessInfo = [[NSWorkspace sharedWorkspace] activeApplication];
68        frontmostApp.highLongOfPSN = [[activeProcessInfo objectForKey: @"NSApplicationProcessSerialNumberHigh"] longValue];
69        frontmostApp.lowLongOfPSN = [[activeProcessInfo objectForKey: @"NSApplicationProcessSerialNumberLow"] longValue];
70        appWasHidden = [NSApp isHidden];
71        [NSApp activateIgnoringOtherApps: YES];
72    }
73}
74
75- (id)initWithAlarm:(PSAlarm *)alarm;
76{
77    if ( (self = [super init]) != nil) {
78        // because we're called within a notification, and alerts may deliver further notifications, make sure the rest of the notification clients are able to execute first
79        [self performSelector: @selector(performAlertsForAlarm:) withObject: alarm afterDelay: 0];
80    }
81    return self;
82}
83
84- (void)dealloc;
85{
86    NSLog(@"%@ dealloc", self);
87    [pendingAlerts release];
88    [super dealloc];
89}
90
91@end
Note: See TracBrowser for help on using the repository browser.