CFRelease the duration preference value if we get one. Found by the clang static analyzer.
2 // GrowlBezelWindowController.m
5 // Created by Jorge Salvador Caffarena on 09/09/04.
6 // Copyright 2004 Jorge Salvador Caffarena. All rights reserved.
9 #import "GrowlBezelWindowController.h"
10 #import "GrowlBezelWindowView.h"
11 #import "GrowlBezelPrefs.h"
12 #import "NSWindow+Transforms.h"
13 #include "CFDictionaryAdditions.h"
14 #import "GrowlFadingWindowTransition.h"
15 #import "GrowlFlippingWindowTransition.h"
16 #import "GrowlShrinkingWindowTransition.h"
17 #import "GrowlRipplingWindowTransition.h"
18 #import "GrowlWindowTransition.h"
19 #import "GrowlApplicationNotification.h"
21 @implementation GrowlBezelWindowController
23 #define MIN_DISPLAY_TIME 3.0
24 #define GrowlBezelPadding 10.0f
32 CFNumberRef prefsDuration = NULL;
33 READ_GROWL_PREF_VALUE(GrowlBezelDuration, GrowlBezelPrefDomain, CFNumberRef, &prefsDuration);
34 [self setDisplayDuration:(prefsDuration ?
35 [(NSNumber *)prefsDuration doubleValue] :
37 if (prefsDuration) CFRelease(prefsDuration);
39 READ_GROWL_PREF_INT(BEZEL_SCREEN_PREF, GrowlBezelPrefDomain, &screenNumber);
40 NSArray *screens = [NSScreen screens];
41 unsigned screensCount = [screens count];
43 [self setScreen:((screensCount >= (screenNumber + 1)) ? [screens objectAtIndex:screenNumber] : [screens objectAtIndex:0])];
46 READ_GROWL_PREF_INT(BEZEL_SIZE_PREF, GrowlBezelPrefDomain, &sizePref);
47 READ_GROWL_PREF_BOOL(BEZEL_SHRINK_PREF, GrowlBezelPrefDomain, &shrinkEnabled);
48 READ_GROWL_PREF_BOOL(BEZEL_FLIP_PREF, GrowlBezelPrefDomain, &flipEnabled);
51 sizeRect.origin.x = 0.0f;
52 sizeRect.origin.y = 0.0f;
54 if (sizePref == BEZEL_SIZE_NORMAL) {
55 sizeRect.size.width = 211.0f;
56 sizeRect.size.height = 206.0f;
58 sizeRect.size.width = 160.0f;
59 sizeRect.size.height = 160.0f;
61 NSPanel *panel = [[NSPanel alloc] initWithContentRect:sizeRect
62 styleMask:NSBorderlessWindowMask
63 backing:NSBackingStoreBuffered
65 NSRect panelFrame = [panel frame];
66 [panel setBecomesKeyOnlyIfNeeded:YES];
67 [panel setHidesOnDeactivate:NO];
68 [panel setBackgroundColor:[NSColor clearColor]];
69 [panel setLevel:NSStatusWindowLevel];
70 [panel setIgnoresMouseEvents:YES];
71 [panel setSticky:YES];
73 [panel setHasShadow:NO];
74 [panel setCanHide:NO];
75 [panel setOneShot:YES];
76 [panel useOptimizedDrawing:YES];
77 [panel setAlphaValue:0.0f];
78 [panel setDelegate:self];
80 GrowlBezelWindowView *view = [[GrowlBezelWindowView alloc] initWithFrame:panelFrame];
81 [view setTarget:self];
82 [view setAction:@selector(notificationClicked:)];
83 [panel setContentView:view];
86 panelFrame = [[panel contentView] frame];
87 [panel setFrame:panelFrame display:NO];
89 // call super so everything else is set up...
90 if ((self = [super initWithWindow:panel])) {
91 // set up the transitions...
92 /*GrowlRipplingWindowTransition *ripple = [[GrowlRipplingWindowTransition alloc] initWithWindow:panel];
93 [self addTransition:ripple];
94 [self setStartPercentage:0 endPercentage:100 forTransition:ripple];
95 [ripple setAutoReverses:NO];
97 [panel setAlphaValue:1.0f];
99 GrowlFadingWindowTransition *fader = [[GrowlFadingWindowTransition alloc] initWithWindow:panel];
100 [self addTransition:fader];
101 [self setStartPercentage:0 endPercentage:100 forTransition:fader];
102 [fader setAutoReverses:YES];
106 GrowlShrinkingWindowTransition *shrinker = [[GrowlShrinkingWindowTransition alloc] initWithWindow:panel];
107 [self addTransition:shrinker];
108 [self setStartPercentage:0 endPercentage:80 forTransition:shrinker];
109 [shrinker setAutoReverses:YES];
113 GrowlFlippingWindowTransition *flipper = [[GrowlFlippingWindowTransition alloc] initWithWindow:panel];
114 [self addTransition:flipper];
115 [self setStartPercentage:0 endPercentage:100 forTransition:flipper];
116 [flipper setFlipsX:YES];
117 [flipper setAutoReverses:YES];
128 - (void) setNotification: (GrowlApplicationNotification *) theNotification {
129 [super setNotification:theNotification];
130 if (!theNotification)
133 NSDictionary *noteDict = [notification dictionaryRepresentation];
134 NSString *title = [notification title];
135 NSString *text = [notification notificationDescription];
136 NSImage *icon = getObjectForKey(noteDict, GROWL_NOTIFICATION_ICON);
137 int myPriority = getIntegerForKey(noteDict, GROWL_NOTIFICATION_PRIORITY);
139 GrowlBezelWindowView *view = [[self window] contentView];
140 [view setPriority:myPriority];
141 [view setTitle:title];
147 #pragma mark positioning methods
149 - (NSPoint) idealOriginInRect:(NSRect)rect {
150 NSRect viewFrame = [[[self window] contentView] frame];
153 int positionPref = BEZEL_POSITION_DEFAULT;
154 READ_GROWL_PREF_INT(BEZEL_POSITION_PREF, GrowlBezelPrefDomain, &positionPref);
155 switch (positionPref) {
157 case BEZEL_POSITION_DEFAULT:
158 result.x = rect.origin.x + ceilf((NSWidth(rect) - NSWidth(viewFrame)) * 0.5f);
159 result.y = rect.origin.y + 140.0f;
161 case BEZEL_POSITION_TOPRIGHT:
162 result.x = NSMaxX(rect) - NSWidth(viewFrame) - GrowlBezelPadding;
163 result.y = NSMaxY(rect) - GrowlBezelPadding - NSHeight(viewFrame);
165 case BEZEL_POSITION_BOTTOMRIGHT:
166 result.x = NSMaxX(rect) - NSWidth(viewFrame) - GrowlBezelPadding;
167 result.y = rect.origin.y + GrowlBezelPadding;
169 case BEZEL_POSITION_BOTTOMLEFT:
170 result.x = rect.origin.x + GrowlBezelPadding;
171 result.y = rect.origin.y + GrowlBezelPadding;
173 case BEZEL_POSITION_TOPLEFT:
174 result.x = rect.origin.x + GrowlBezelPadding;
175 result.y = NSMaxY(rect) - GrowlBezelPadding - NSHeight(viewFrame);
181 - (enum GrowlExpansionDirection) primaryExpansionDirection {
182 return GrowlNoExpansionDirection;
185 - (enum GrowlExpansionDirection) secondaryExpansionDirection {
186 return GrowlNoExpansionDirection;
189 - (float) requiredDistanceFromExistingDisplays {
190 return GrowlBezelPadding;
193 - (BOOL) requiresPositioning {