From 0aaecac6ff2bc89e58a0c8c6d6ad62e02fb2b011 Mon Sep 17 00:00:00 2001 From: dmaclach Date: Tue, 18 Mar 2008 04:02:35 +0000 Subject: Added GTMNSWorkspace+ScreenSaver, and got rid of device colors. --- AppKit/GTMLinearRGBShadingTest.m | 23 +++-- AppKit/GTMNSBezierPath+ShadingTest.m | 11 ++- AppKit/GTMNSColor+Theme.h | 31 +------ AppKit/GTMNSColor+Theme.m | 147 +++----------------------------- AppKit/GTMNSColor+ThemeTest.m | 63 ++------------ AppKit/GTMNSWorkspace+ScreenSaver.h | 33 +++++++ AppKit/GTMNSWorkspace+ScreenSaver.m | 125 +++++++++++++++++++++++++++ AppKit/GTMNSWorkspace+ScreenSaverTest.m | 33 +++++++ GTM.xcodeproj/project.pbxproj | 20 +++++ ReleaseNotes.txt | 1 + 10 files changed, 245 insertions(+), 242 deletions(-) create mode 100644 AppKit/GTMNSWorkspace+ScreenSaver.h create mode 100644 AppKit/GTMNSWorkspace+ScreenSaver.m create mode 100644 AppKit/GTMNSWorkspace+ScreenSaverTest.m diff --git a/AppKit/GTMLinearRGBShadingTest.m b/AppKit/GTMLinearRGBShadingTest.m index 70b67b7..e90d84c 100644 --- a/AppKit/GTMLinearRGBShadingTest.m +++ b/AppKit/GTMLinearRGBShadingTest.m @@ -19,7 +19,6 @@ #import #import "GTMSenTestCase.h" #import "GTMLinearRGBShading.h" -#import "GTMNSColor+Theme.h" @interface GTMLinearRGBShadingTest : SenTestCase @end @@ -27,13 +26,13 @@ @implementation GTMLinearRGBShadingTest - (void)testShadingFrom { // Create a shading from red to blue, and check if 50% is purple - NSColor *red = [NSColor gtm_deviceRedColor]; - NSColor *blue = [NSColor gtm_deviceBlueColor]; - NSColor *purple = [NSColor gtm_devicePurpleColor]; + NSColor *red = [NSColor redColor]; + NSColor *blue = [NSColor blueColor]; + NSColor *purple = [NSColor purpleColor]; GTMLinearRGBShading *theShading = [GTMLinearRGBShading shadingFromColor:red toColor:blue - fromSpaceNamed:NSDeviceRGBColorSpace]; + fromSpaceNamed:NSCalibratedRGBColorSpace]; STAssertNotNil(theShading,nil); STAssertEquals([theShading stopCount], 2U, nil); float *theColor = (float*)[theShading valueAtPosition: 0.5]; @@ -51,14 +50,14 @@ const float kColorIncrement = 1.0f / kColorCount; for (unsigned int i = 0; i < kColorCount; i++) { thePositions[i] = kColorIncrement * i; - theColors[i] = [NSColor colorWithDeviceRed:kColorIncrement * i - green:kColorIncrement * i - blue:kColorIncrement * i - alpha:kColorIncrement * i]; + theColors[i] = [NSColor colorWithCalibratedRed:kColorIncrement * i + green:kColorIncrement * i + blue:kColorIncrement * i + alpha:kColorIncrement * i]; } GTMLinearRGBShading *theShading = [GTMLinearRGBShading shadingWithColors:theColors - fromSpaceNamed:NSDeviceRGBColorSpace + fromSpaceNamed:NSCalibratedRGBColorSpace atPositions:thePositions count:kColorCount]; for (unsigned int i = 0; i < kColorCount; i++) { @@ -73,7 +72,7 @@ - (void)testShadeFunction { GTMLinearRGBShading *theShading = [GTMLinearRGBShading shadingWithColors:nil - fromSpaceNamed:NSDeviceRGBColorSpace + fromSpaceNamed:NSCalibratedRGBColorSpace atPositions:nil count:0]; CGFunctionRef theFunction = [theShading shadeFunction]; @@ -84,7 +83,7 @@ - (void)testColorSpace { GTMLinearRGBShading *theShading = [GTMLinearRGBShading shadingWithColors:nil - fromSpaceNamed:NSDeviceRGBColorSpace + fromSpaceNamed:NSCalibratedRGBColorSpace atPositions:nil count:0]; CGColorSpaceRef theColorSpace = [theShading colorSpace]; diff --git a/AppKit/GTMNSBezierPath+ShadingTest.m b/AppKit/GTMNSBezierPath+ShadingTest.m index 3883356..bed6a4e 100644 --- a/AppKit/GTMNSBezierPath+ShadingTest.m +++ b/AppKit/GTMNSBezierPath+ShadingTest.m @@ -23,7 +23,6 @@ #import "GTMLinearRGBShading.h" #import "GTMNSView+UnitTesting.h" #import "GTMNSBezierPath+Shading.h" -#import "GTMNSColor+Theme.h" @interface GTMNSBezierPath_ShadingTest : SenTestCase @end @@ -37,15 +36,15 @@ - (void)unitTestViewDrawRect:(NSRect)rect contextInfo:(void*)contextInfo{ - NSColor *theColorArray[] = { [NSColor gtm_deviceBlueColor], - [NSColor gtm_deviceRedColor], [NSColor gtm_deviceYellowColor], - [NSColor gtm_deviceBlueColor], [NSColor gtm_deviceGreenColor], - [NSColor gtm_deviceRedColor] }; + NSColor *theColorArray[] = { [NSColor blueColor], + [NSColor redColor], [NSColor yellowColor], + [NSColor blueColor], [NSColor greenColor], + [NSColor redColor] }; float theFloatArray[] = { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.00f }; GTMLinearRGBShading *shading = [GTMLinearRGBShading shadingWithColors:theColorArray - fromSpaceNamed:NSDeviceRGBColorSpace + fromSpaceNamed:NSCalibratedRGBColorSpace atPositions:theFloatArray count:sizeof(theFloatArray)/sizeof(float)]; NSBezierPath *shadedPath; diff --git a/AppKit/GTMNSColor+Theme.h b/AppKit/GTMNSColor+Theme.h index ef121eb..f63a143 100644 --- a/AppKit/GTMNSColor+Theme.h +++ b/AppKit/GTMNSColor+Theme.h @@ -25,38 +25,11 @@ @interface NSColor (GTMColorThemeAdditions) /// Create up an NSColor based on a Theme Text Color. -/// Colors will be in the DeviceRGB color space +/// Colors will be in the CalibratedRGB color space + (id)gtm_colorWithThemeTextColor:(ThemeTextColor)textColor; /// Create up an NSColor based on a Theme Brush -/// Colors will be in the DeviceRGB color space +/// Colors will be in the CalibratedRGB color space + (id)gtm_colorWithThemeBrush:(ThemeBrush)brush; -/// Device colors for drawing UI elements and such -+ (NSColor *)gtm_deviceBlackColor; /* 0.0 white */ -+ (NSColor *)gtm_deviceDarkGrayColor; /* 0.333 white */ -+ (NSColor *)gtm_deviceLightGrayColor; /* 0.667 white */ -+ (NSColor *)gtm_deviceWhiteColor; /* 1.0 white */ -+ (NSColor *)gtm_deviceGrayColor; /* 0.5 white */ -+ (NSColor *)gtm_deviceRedColor; /* 1.0, 0.0, 0.0 RGB */ -+ (NSColor *)gtm_deviceGreenColor; /* 0.0, 1.0, 0.0 RGB */ -+ (NSColor *)gtm_deviceBlueColor; /* 0.0, 0.0, 1.0 RGB */ -+ (NSColor *)gtm_deviceCyanColor; /* 0.0, 1.0, 1.0 RGB */ -+ (NSColor *)gtm_deviceYellowColor; /* 1.0, 1.0, 0.0 RGB */ -+ (NSColor *)gtm_deviceMagentaColor; /* 1.0, 0.0, 1.0 RGB */ -+ (NSColor *)gtm_deviceOrangeColor; /* 1.0, 0.5, 0.0 RGB */ -+ (NSColor *)gtm_devicePurpleColor; /* 0.5, 0.0, 0.5 RGB */ -+ (NSColor *)gtm_deviceBrownColor; /* 0.6, 0.4, 0.2 RGB */ -+ (NSColor *)gtm_deviceClearColor; /* 0.0 white, 0.0 alpha */ - -/// default colorWithAlphaComponent has a bug where it doesn't maintain colorspace -// Radar 5047862 [NSColor colorWithAlphaComponent] does NOT maintain colorspace. -- (NSColor *)gtm_safeColorWithAlphaComponent:(float)alpha; - -// gives us a color for any color space. -// Should never return nil, but will if there is an error (out of memory?) -// converting a color to a different colorspace. -// Radar 5608378 Would like theme brush value for the menu item highlight color -// Radar 5608444 colorUsingColorSpaceName doesn't work for NSDeviceRGBColorSpace and SystemColors -- (NSColor *)gtm_safeColorUsingColorSpaceName:(NSString *)colorSpaceName; @end diff --git a/AppKit/GTMNSColor+Theme.m b/AppKit/GTMNSColor+Theme.m index b3437e7..40326a7 100644 --- a/AppKit/GTMNSColor+Theme.m +++ b/AppKit/GTMNSColor+Theme.m @@ -23,7 +23,7 @@ @implementation NSColor (GTMColorThemeAdditions) /// Create up an NSColor based on a Theme Text Color -/// Colors will be in the device color space +/// Colors will be in the CalibratedRGB color space + (id)gtm_colorWithThemeTextColor:(ThemeTextColor)textColor { NSColor *nsTextColor = nil; RGBColor rgbTextColor; @@ -32,10 +32,10 @@ float red = rgbTextColor.red / 65535.0f; float green = rgbTextColor.green / 65535.0f; float blue = rgbTextColor.blue / 65535.0f; - nsTextColor = [NSColor colorWithDeviceRed:red - green:green - blue:blue - alpha:1.0f]; + nsTextColor = [NSColor colorWithCalibratedRed:red + green:green + blue:blue + alpha:1.0f]; } else { #ifdef DEBUG NSLog(@"Unable to create color for textcolor %d", textColor); @@ -45,16 +45,16 @@ } /// Create up an NSColor based on a Theme Brush -/// Colors will be in the DeviceRGB color space +/// Colors will be in the CalibratedRGB color space + (id)gtm_colorWithThemeBrush:(ThemeBrush)brush { NSColor *nsBrushColor = nil; RGBColor rgbBrushColor; OSStatus status = GetThemeBrushAsColor(brush, 32, true, &rgbBrushColor); if (status == noErr) { - nsBrushColor = [NSColor colorWithDeviceRed:rgbBrushColor.red / 65535.0f - green:rgbBrushColor.green / 65535.0f - blue:rgbBrushColor.blue / 65535.0f - alpha:1.0f]; + nsBrushColor = [NSColor colorWithCalibratedRed:rgbBrushColor.red / 65535.0f + green:rgbBrushColor.green / 65535.0f + blue:rgbBrushColor.blue / 65535.0f + alpha:1.0f]; } else { #ifdef DEBUG NSLog(@"Unable to create color for brushcolor %d", brush); @@ -62,131 +62,4 @@ } return nsBrushColor; } - -+ (NSColor *)gtm_deviceBlackColor { /* 0.0f white */ - return [NSColor colorWithDeviceWhite:0.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceDarkGrayColor { /* 0.333 white */ - return [NSColor colorWithDeviceWhite:1.0f/3.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceLightGrayColor { /* 0.667 white */ - return [NSColor colorWithDeviceWhite:2.0f/3.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceWhiteColor { /* 1.0f white */ - return [NSColor colorWithDeviceWhite:1.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceGrayColor { /* 0.5 white */ - return [NSColor colorWithDeviceWhite:0.5f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceRedColor { /* 1.0f, 0.0f, 0.0f RGB */ - return [NSColor colorWithDeviceRed:1.0f green:0.0f blue: 0.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceGreenColor { /* 0.0f, 1.0f, 0.0f RGB */ -return [NSColor colorWithDeviceRed:0.0f green:1.0f blue: 0.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceBlueColor { /* 0.0f, 0.0f, 1.0f RGB */ -return [NSColor colorWithDeviceRed:0.0f green:0.0f blue: 1.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceCyanColor { /* 0.0f, 1.0f, 1.0f RGB */ -return [NSColor colorWithDeviceRed:0.0f green:1.0f blue: 1.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceYellowColor { /* 1.0f, 1.0f, 0.0f RGB */ -return [NSColor colorWithDeviceRed:1.0f green:1.0f blue: 0.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceMagentaColor { /* 1.0f, 0.0f, 1.0f RGB */ -return [NSColor colorWithDeviceRed:1.0f green:0.0f blue: 1.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceOrangeColor { /* 1.0f, 0.5, 0.0f RGB */ -return [NSColor colorWithDeviceRed:1.0f green:0.5f blue: 0.0f alpha:1.0f]; -} - -+ (NSColor *)gtm_devicePurpleColor { /* 0.5, 0.0f, 0.5 RGB */ -return [NSColor colorWithDeviceRed:0.5f green:0.0f blue: 0.5f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceBrownColor { /* 0.6, 0.4, 0.2 RGB */ -return [NSColor colorWithDeviceRed:0.6f green:0.4f blue: 0.2f alpha:1.0f]; -} - -+ (NSColor *)gtm_deviceClearColor { /* 0.0f white, 0.0f alpha */ - return [NSColor colorWithDeviceWhite:0.0f alpha:0.0f]; -} - -- (NSColor *)gtm_safeColorWithAlphaComponent:(float)alpha { - // This mess is here because of - // Radar 5047862 [NSColor colorWithAlphaComponent] does NOT maintain colorspace. - // As of 10.4.8, colorWithAlphaComponent will return an NSCalibratedRGBColor - // instead of a NSDeviceRGBColor when you call colorWithAlphaComponent on - // a NSDeviceRGBColor even though the docs say "Creates and returns an NSColor - // object that has the same color space and component values as the receiver" - // We must use exceptions in case somebody attempts to put a pattern through - // here. The assumption being made is that alpha is the last color component - // which it is for all current cases. - NSColor *newColor = nil; - -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) - @try { - int componentCount = [self numberOfComponents]; - float *components = (float*)calloc(componentCount, sizeof(float)); - if (!components) { - NSException *exception = [NSException exceptionWithName:NSMallocException - reason:@"Unable to malloc components" - userInfo:nil]; - @throw exception; - } - [self getComponents:components]; - components[componentCount - 1] = alpha; - newColor = [NSColor colorWithColorSpace:[self colorSpace] - components:components count:componentCount]; - free(components); - } - @catch (NSException *ex) { - // Probably passed us a pattern. I'm not even sure how Apple deals with - // changing the alpha of a pattern color. - newColor = [self colorWithAlphaComponent:alpha]; - } -#else - // Radar 5047862 is fixed in Leopard. - newColor = [self colorWithAlphaComponent:alpha]; -#endif - return newColor; -} - -- (NSColor *)gtm_safeColorUsingColorSpaceName:(NSString *)colorSpaceName { - NSColor *outColor = [self colorUsingColorSpaceName:colorSpaceName]; - if (!outColor) { - NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:1 - pixelsHigh:1 - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:colorSpaceName - bytesPerRow:0 - bitsPerPixel:0] autorelease]; - NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep]; - if (context) { - NSRect rect = NSMakeRect(0, 0, 1, 1); - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:context]; - [self setFill]; - NSRectFill(rect); - [NSGraphicsContext restoreGraphicsState]; - outColor = [rep colorAtX:0 y:0]; - } - } - return outColor; -} @end diff --git a/AppKit/GTMNSColor+ThemeTest.m b/AppKit/GTMNSColor+ThemeTest.m index d3c9db1..4115dda 100644 --- a/AppKit/GTMNSColor+ThemeTest.m +++ b/AppKit/GTMNSColor+ThemeTest.m @@ -29,12 +29,6 @@ //METHOD_CHECK(NSWorkspace, themeAppearance); -// utility function for giving random floats between 0.0f and 1.0f -static float Randomf() { - float val = random(); - return val / INT32_MAX; -} - - (void)testColorWithThemeTextColor { float colorValues[][4] = { { 1.000000, 1.000000, 1.000000, 1.000000 }, @@ -103,8 +97,8 @@ static float Randomf() { for(int j = 0; j < 4; j++) { STAssertEqualsWithAccuracy(nsComponents[j], colorValues[i + 2][j], 0.000001, @"Theme Text Color %d is wrong", i); - STAssertEqualObjects([textColor colorSpaceName], NSDeviceRGBColorSpace, - @"Color space must be DeviceRGB"); + STAssertEqualObjects([textColor colorSpaceName], NSCalibratedRGBColorSpace, + @"Color space must be CalibratedRGB"); } } } @@ -193,57 +187,10 @@ static float Randomf() { for(int j = 0; j < 4; j++) { STAssertEqualsWithAccuracy(nsComponents[j], colorValues[i + 2][j], 0.000001, @"Theme Text Brush %d is wrong", i + 2); - STAssertEqualObjects([brushColor colorSpaceName], NSDeviceRGBColorSpace, - @"Color space must be DeviceRGB"); + STAssertEqualObjects([brushColor colorSpaceName], NSCalibratedRGBColorSpace, + @"Color space must be CalibratedRB"); } } -} - -- (void)testSafeColorWithAlphaComponent { - NSColorSpace *testSpace[6]; - testSpace[0] = [NSColorSpace genericRGBColorSpace]; - testSpace[1] = [NSColorSpace genericGrayColorSpace]; - testSpace[2] = [NSColorSpace genericCMYKColorSpace]; - testSpace[3] = [NSColorSpace deviceRGBColorSpace]; - testSpace[4] = [NSColorSpace deviceGrayColorSpace]; - testSpace[5] = [NSColorSpace deviceCMYKColorSpace]; - - float comp[5]; - for (int i = 0; i < sizeof(comp) / sizeof(float); ++i) { - comp[i] = Randomf(); - } - - float alpha = Randomf(); - for (int i = 0; i < sizeof(testSpace) / sizeof(NSColorSpace*); ++i) { - int componentCount = [testSpace[i] numberOfColorComponents]; - NSColor *color = [NSColor colorWithColorSpace:testSpace[i] - components:comp - count:componentCount + 1]; - NSColor *alphaColor = [color gtm_safeColorWithAlphaComponent:alpha]; - - float alphaSwap = comp[componentCount]; - comp[componentCount] = alpha; - NSColor *testColor = [NSColor colorWithColorSpace:testSpace[i] - components:comp - count:componentCount + 1]; - comp[componentCount] = alphaSwap; - STAssertEqualObjects(alphaColor, - testColor, - @"Compare failed with components: %f %f %f %f %f %f alpha: %f", - testSpace[0], testSpace[1], testSpace[2], - testSpace[3], testSpace[4], testSpace[5], - alpha); - } -} - -- (void)testSafeColorUsingColorSpaceName { - - NSColor *brushColor = [[NSColor selectedMenuItemColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - STAssertNil(brushColor, @"This doesn't work on Tiger or Leopard"); - - brushColor = [[NSColor selectedMenuItemColor] gtm_safeColorUsingColorSpaceName:NSDeviceRGBColorSpace]; - STAssertNotNil(brushColor, nil); -} - +} @end diff --git a/AppKit/GTMNSWorkspace+ScreenSaver.h b/AppKit/GTMNSWorkspace+ScreenSaver.h new file mode 100644 index 0000000..adaaf8d --- /dev/null +++ b/AppKit/GTMNSWorkspace+ScreenSaver.h @@ -0,0 +1,33 @@ +// +// GTMNSWorkspace+ScreenSaver.h +// +// Category for seeing if the screen saver is running. +// Requires linkage with the ScreenSaver.framework. Warning, uses some +// undocumented methods in the ScreenSaver.framework. +// +// Copyright 2006-2008 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// + +#import + +@interface NSWorkspace (GTMScreenSaverAddition) + +// Check if the screen saver is running. +// Returns YES if it is running. +// Requires linking to the ScreenSaver.framework. ++ (BOOL)gtm_isScreenSaverActive; + +@end + diff --git a/AppKit/GTMNSWorkspace+ScreenSaver.m b/AppKit/GTMNSWorkspace+ScreenSaver.m new file mode 100644 index 0000000..270f9bc --- /dev/null +++ b/AppKit/GTMNSWorkspace+ScreenSaver.m @@ -0,0 +1,125 @@ +// +// GTMNSWorkspace+ScreenSaver.m +// +// Copyright 2006-2008 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// + +#import +#import +#import "GTMNSWorkspace+ScreenSaver.h" + +// Interesting class descriptions extracted from ScreenSaver.framework using +// class-dump. Note that these are "not documented". + +@protocol ScreenSaverControl + +- (BOOL)screenSaverIsRunning; +- (BOOL)screenSaverCanRun; +- (void)setScreenSaverCanRun:(BOOL)fp8; +- (void)screenSaverStartNow; +- (void)screenSaverStopNow; +- (void)restartForUser:(id)fp8; +- (double)screenSaverTimeRemaining; +- (void)screenSaverDidFade; +- (BOOL)screenSaverIsRunningInBackground; +- (void)screenSaverDidFadeInBackground:(BOOL)fp8 + psnHi:(unsigned int)fp12 + psnLow:(unsigned int)fp16; + +@end + +@interface ScreenSaverController : NSObject { + NSConnection *_connection; + id _daemonProxy; + void *_reserved; +} + ++ (id)controller; ++ (id)monitor; ++ (id)daemonConnectionName; ++ (id)enginePath; +- (void)_connectionClosed:(id)fp8; +- (id)init; +- (void)dealloc; +- (BOOL)screenSaverIsRunning; +- (BOOL)screenSaverCanRun; +- (void)setScreenSaverCanRun:(BOOL)fp8; +- (void)screenSaverStartNow; +- (void)screenSaverStopNow; +- (void)restartForUser:(id)fp8; +- (double)screenSaverTimeRemaining; +- (void)screenSaverDidFade; +- (BOOL)screenSaverIsRunningInBackground; +- (void)screenSaverDidFadeInBackground:(BOOL)fp8 + psnHi:(unsigned int)fp12 + psnLow:(unsigned int)fp16; + +@end + +// end of extraction + +@implementation NSWorkspace (GTMScreenSaverAddition) +// Check if the screen saver is running. ++ (BOOL)gtm_isScreenSaverActive { + BOOL answer = NO; + ScreenSaverController *controller = nil; + // We're calling into an "undocumented" framework here, so we are going to + // step rather carefully. + + Class screenSaverControllerClass = NSClassFromString(@"ScreenSaverController"); + NSAssert(screenSaverControllerClass, + @"Are you linked with ScreenSaver.framework?" + " Can't find ScreenSaverController class."); + if ([screenSaverControllerClass respondsToSelector:@selector(controller)]) { + controller = [ScreenSaverController controller]; + if (controller) { + if ([controller respondsToSelector:@selector(screenSaverIsRunning)]) { + answer = [controller screenSaverIsRunning]; + } else { + NSLog(@"ScreenSaverController no longer supports -screenSaverIsRunning?"); + } + } + } + + if (!controller) { + // If we can't get the controller, chances are we are being run from the + // command line and don't have access to the window server. As such we are + // going to fallback to the older method of figuring out if a screen saver + // is running. + ProcessSerialNumber psn; + // Check if the saver is already running + require_noerr(GetFrontProcess(&psn), CantGetFrontProcess); + + CFDictionaryRef cfProcessInfo + = ProcessInformationCopyDictionary(&psn, + kProcessDictionaryIncludeAllInformationMask); + + require(cfProcessInfo, CantGetFrontProcessInfo); + + NSString *bundlePath = [(NSDictionary*)cfProcessInfo objectForKey:@"BundlePath"]; + + // ScreenSaverEngine is the frontmost app if the screen saver is actually + // running Security Agent is the frontmost app if the "enter password" + // dialog is showing + answer = [bundlePath hasSuffix:@"ScreenSaverEngine.app"] || + [bundlePath hasSuffix:@"SecurityAgent.app"]; + CFRelease(cfProcessInfo); + } +CantGetFrontProcessInfo: +CantGetFrontProcess: + return answer; +} + +@end diff --git a/AppKit/GTMNSWorkspace+ScreenSaverTest.m b/AppKit/GTMNSWorkspace+ScreenSaverTest.m new file mode 100644 index 0000000..2dfcbb9 --- /dev/null +++ b/AppKit/GTMNSWorkspace+ScreenSaverTest.m @@ -0,0 +1,33 @@ +// +// GTMNSWorkspace+ScreenSaverTest.m +// +// Copyright 2006-2008 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// +#import +#import "GTMNSWorkspace+ScreenSaver.h" + +@interface GTMNSWorkspace_ScreenSaverTest : SenTestCase +@end + + +@implementation GTMNSWorkspace_ScreenSaverTest + +- (void)testIsScreenSaverActive { + // Not much of a test, just executes the code. Couldn't think of a + // good way of verifying this one. + [NSWorkspace gtm_isScreenSaverActive]; +} + +@end diff --git a/GTM.xcodeproj/project.pbxproj b/GTM.xcodeproj/project.pbxproj index abb4fef..f941194 100644 --- a/GTM.xcodeproj/project.pbxproj +++ b/GTM.xcodeproj/project.pbxproj @@ -22,6 +22,12 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 8B2A9B200D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B2A9B1D0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m */; }; + 8B2A9B220D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B2A9B1F0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h */; }; + 8B2A9B230D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B2A9B1D0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m */; }; + 8B2A9B240D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B2A9B1E0D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m */; }; + 8B2A9BEC0D82714A00599386 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2A9BEB0D82714A00599386 /* ScreenSaver.framework */; }; + 8B2A9BED0D82714A00599386 /* ScreenSaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2A9BEB0D82714A00599386 /* ScreenSaver.framework */; }; F413908F0D75F63C00F72B31 /* GTMNSFileManager+Path.h in Headers */ = {isa = PBXBuildFile; fileRef = F413908C0D75F63C00F72B31 /* GTMNSFileManager+Path.h */; }; F41390900D75F63C00F72B31 /* GTMNSFileManager+Path.m in Sources */ = {isa = PBXBuildFile; fileRef = F413908D0D75F63C00F72B31 /* GTMNSFileManager+Path.m */; }; F41390920D75F64D00F72B31 /* GTMNSFileManager+PathTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F413908E0D75F63C00F72B31 /* GTMNSFileManager+PathTest.m */; }; @@ -131,6 +137,10 @@ 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 32DBCF5E0370ADEE00C91783 /* GTM_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTM_Prefix.pch; sourceTree = ""; }; + 8B2A9B1D0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSWorkspace+ScreenSaver.m"; sourceTree = ""; }; + 8B2A9B1E0D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSWorkspace+ScreenSaverTest.m"; sourceTree = ""; }; + 8B2A9B1F0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSWorkspace+ScreenSaver.h"; sourceTree = ""; }; + 8B2A9BEB0D82714A00599386 /* ScreenSaver.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScreenSaver.framework; path = /System/Library/Frameworks/ScreenSaver.framework; sourceTree = ""; }; F413908C0D75F63C00F72B31 /* GTMNSFileManager+Path.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSFileManager+Path.h"; sourceTree = ""; }; F413908D0D75F63C00F72B31 /* GTMNSFileManager+Path.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSFileManager+Path.m"; sourceTree = ""; }; F413908E0D75F63C00F72B31 /* GTMNSFileManager+PathTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSFileManager+PathTest.m"; sourceTree = ""; }; @@ -232,6 +242,7 @@ F42E095E0D199BD600D5DDE0 /* Cocoa.framework in Frameworks */, F42E09AE0D19A62F00D5DDE0 /* Carbon.framework in Frameworks */, F43E4F6D0D4E60C50041161F /* libz.dylib in Frameworks */, + 8B2A9BEC0D82714A00599386 /* ScreenSaver.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -242,6 +253,7 @@ F42E08610D199A2B00D5DDE0 /* Cocoa.framework in Frameworks */, F42E087F0D199AB400D5DDE0 /* GTM.framework in Frameworks */, F42E089C0D199B1800D5DDE0 /* SenTestingKit.framework in Frameworks */, + 8B2A9BED0D82714A00599386 /* ScreenSaver.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -279,6 +291,7 @@ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( + 8B2A9BEB0D82714A00599386 /* ScreenSaver.framework */, 0867D6A5FE840307C02AAC07 /* AppKit.framework */, F42E09AD0D19A62F00D5DDE0 /* Carbon.framework */, 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, @@ -333,6 +346,9 @@ F47F1CAD0D4910FD00925B8F /* GTMNSColor+Theme.m */, F47F1CAE0D4910FD00925B8F /* GTMNSColor+ThemeTest.m */, F47F1C740D490E5C00925B8F /* GTMShading.h */, + 8B2A9B1D0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m */, + 8B2A9B1E0D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m */, + 8B2A9B1F0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h */, F42E09A80D19A5E300D5DDE0 /* GTMNSWorkspace+Theme.h */, F42E09A90D19A5E300D5DDE0 /* GTMNSWorkspace+Theme.m */, F42E0B090D19A6FB00D5DDE0 /* GTMNSWorkspace+ThemeTest.m */, @@ -416,6 +432,7 @@ F437F55D0D50BC0A00F5C3A4 /* GTMRegex.h in Headers */, F47A79880D746EE9002302AB /* GTMScriptRunner.h in Headers */, F413908F0D75F63C00F72B31 /* GTMNSFileManager+Path.h in Headers */, + 8B2A9B220D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -594,6 +611,7 @@ F437F55E0D50BC0A00F5C3A4 /* GTMRegex.m in Sources */, F47A79890D746EE9002302AB /* GTMScriptRunner.m in Sources */, F41390900D75F63C00F72B31 /* GTMNSFileManager+Path.m in Sources */, + 8B2A9B200D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -612,6 +630,8 @@ F47F1CB60D49110900925B8F /* GTMNSColor+ThemeTest.m in Sources */, F43E447F0D4918BC0041161F /* GTMLinearRGBShadingTest.m in Sources */, F43E4E660D4E5ED40041161F /* GTMNSData+zlibTest.m in Sources */, + 8B2A9B230D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m in Sources */, + 8B2A9B240D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 369ac3b..8adc4e0 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -24,6 +24,7 @@ Changes since 1.0.0 - Added GTMNSFileManager+Path for two small helpers. +- Added GTMNSWorkspace+ScreenSaver Release 1.0.0 14-January-2008 -- cgit v1.2.3