CFRelease the duration preference value if we get one. Found by the clang static analyzer.
2 // GrowlSmokeWindowController.m
5 // Created by Matthew Walton on 11/09/2004.
6 // Copyright 2004-2006 The Growl Project. All rights reserved.
8 // Most of this is lifted from KABubbleWindowController in the Growl source
10 #import "GrowlSmokeWindowController.h"
11 #import "GrowlSmokeWindowView.h"
12 #import "GrowlSmokeDefines.h"
13 #import "GrowlDefinesInternal.h"
14 #import "NSWindow+Transforms.h"
15 #import "GrowlApplicationNotification.h"
16 #import "GrowlWindowTransition.h"
17 #import "GrowlFadingWindowTransition.h"
18 #include "CFDictionaryAdditions.h"
20 @implementation GrowlSmokeWindowController
22 //static const double gAdditionalLinesDisplayTime = 0.5;
23 //static const double gMaxDisplayTime = 10.0;
27 READ_GROWL_PREF_INT(GrowlSmokeScreenPref, GrowlSmokePrefDomain, &screenNumber);
28 NSArray *screens = [NSScreen screens];
29 unsigned screensCount = [screens count];
31 [self setScreen:((screensCount >= (screenNumber + 1)) ? [screens objectAtIndex:screenNumber] : [screens objectAtIndex:0])];
34 CFNumberRef prefsDuration = NULL;
35 READ_GROWL_PREF_VALUE(GrowlSmokeDurationPref, GrowlSmokePrefDomain, CFNumberRef, &prefsDuration);
36 [self setDisplayDuration:(prefsDuration ?
37 [(NSNumber *)prefsDuration doubleValue] :
38 GrowlSmokeDurationPrefDefault)];
39 if (prefsDuration) CFRelease(prefsDuration);
41 NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0.0f, 0.0f, GrowlSmokeNotificationWidth, 65.0f)
42 styleMask:NSBorderlessWindowMask | NSNonactivatingPanelMask
43 backing:NSBackingStoreBuffered
45 NSRect panelFrame = [panel frame];
46 [panel setBecomesKeyOnlyIfNeeded:YES];
47 [panel setHidesOnDeactivate:NO];
48 [panel setBackgroundColor:[NSColor clearColor]];
49 [panel setLevel:NSStatusWindowLevel];
50 [panel setSticky:YES];
51 [panel setAlphaValue:0.0f];
53 [panel setHasShadow:YES];
54 [panel setCanHide:NO];
55 [panel setOneShot:YES];
56 [panel useOptimizedDrawing:YES];
58 GrowlSmokeWindowView *view = [[GrowlSmokeWindowView alloc] initWithFrame:panelFrame];
59 [view setTarget:self];
60 [view setAction:@selector(notificationClicked:)];
61 [panel setContentView:view];
64 // call super so everything else is set up...
65 if ((self = [super initWithWindow:panel])) {
66 // set up the transitions...
67 GrowlFadingWindowTransition *fader = [[GrowlFadingWindowTransition alloc] initWithWindow:panel];
68 [self addTransition:fader];
69 [self setStartPercentage:0 endPercentage:100 forTransition:fader];
70 [fader setAutoReverses:YES];
79 - (void) setNotification:(GrowlApplicationNotification *)theNotification {
80 [super setNotification:theNotification];
84 NSDictionary *noteDict = [notification dictionaryRepresentation];
85 NSString *title = [notification title];
86 NSString *text = [notification notificationDescription];
87 NSImage *icon = getObjectForKey(noteDict, GROWL_NOTIFICATION_ICON);
88 int priority = getIntegerForKey(noteDict, GROWL_NOTIFICATION_PRIORITY);
90 GrowlSmokeWindowView *view = [[self window] contentView];
91 [view setPriority:priority];
92 [view setTitle:title];
99 #pragma mark positioning methods
101 - (NSPoint) idealOriginInRect:(NSRect)rect {
102 NSRect viewFrame = [[[self window] contentView] frame];
103 enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
106 switch(originatingPosition){
107 case GrowlTopRightPosition:
108 idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowlSmokePadding,
109 NSMaxY(rect) - GrowlSmokePadding - NSHeight(viewFrame));
111 case GrowlTopLeftPosition:
112 idealOrigin = NSMakePoint(NSMinX(rect) + GrowlSmokePadding,
113 NSMaxY(rect) - GrowlSmokePadding - NSHeight(viewFrame));
115 case GrowlBottomLeftPosition:
116 idealOrigin = NSMakePoint(NSMinX(rect) + GrowlSmokePadding,
117 NSMinY(rect) + GrowlSmokePadding);
119 case GrowlBottomRightPosition:
120 idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowlSmokePadding,
121 NSMinY(rect) + GrowlSmokePadding);
124 idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowlSmokePadding,
125 NSMaxY(rect) - GrowlSmokePadding - NSHeight(viewFrame));
132 - (enum GrowlExpansionDirection) primaryExpansionDirection {
133 enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
134 enum GrowlExpansionDirection directionToExpand;
136 switch(originatingPosition){
137 case GrowlTopLeftPosition:
138 directionToExpand = GrowlDownExpansionDirection;
140 case GrowlTopRightPosition:
141 directionToExpand = GrowlDownExpansionDirection;
143 case GrowlBottomLeftPosition:
144 directionToExpand = GrowlUpExpansionDirection;
146 case GrowlBottomRightPosition:
147 directionToExpand = GrowlUpExpansionDirection;
150 directionToExpand = GrowlDownExpansionDirection;
154 return directionToExpand;
157 - (enum GrowlExpansionDirection) secondaryExpansionDirection {
158 enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
159 enum GrowlExpansionDirection directionToExpand;
161 switch(originatingPosition){
162 case GrowlTopLeftPosition:
163 directionToExpand = GrowlRightExpansionDirection;
165 case GrowlTopRightPosition:
166 directionToExpand = GrowlLeftExpansionDirection;
168 case GrowlBottomLeftPosition:
169 directionToExpand = GrowlRightExpansionDirection;
171 case GrowlBottomRightPosition:
172 directionToExpand = GrowlLeftExpansionDirection;
175 directionToExpand = GrowlRightExpansionDirection;
179 return directionToExpand;
182 - (float) requiredDistanceFromExistingDisplays {
183 return GrowlSmokePadding;