diff --git a/checkin_notes b/checkin_notes index d45a288392..6ce5be377c 100644 --- a/checkin_notes +++ b/checkin_notes @@ -1390,8 +1390,7 @@ Charlie Feb 14 2008 clientscr/ mac_saver_module.cpp Mac_Saver_Module.h - Mac_Saver_ModuleView.m - Mac_Saver_ModuleView.h + Mac_Saver_ModuleView.m,h screensaver.cpp res/ boinc_ss_logo.png (new) @@ -1466,9 +1465,8 @@ Charlie Feb 19 2008 clientscr/ mac_saver_module.cpp Mac_Saver_Module.h - Mac_Saver_ModuleView.m - Mac_Saver_ModuleView.h - screensaver.cpp + Mac_Saver_ModuleView.m,h + screensaver.cpp screensaver_win.cpp Charlie Feb 20 2008 @@ -1640,7 +1638,7 @@ Charlie Feb 25 2008 Charlie Feb 25 2008 - Mac SCR: Display "Starting screensaver graphics. Please wait ..." for 45 seconds each time we start graphics from a different application. - The application graphics window will hode this when it opens, so we + The application graphics window will hide this when it opens, so we stop showing it after 45 seconds to avoid wasting CPU cycles. clientscr/ @@ -1671,3 +1669,13 @@ Charlie Feb 26 2008 mac_build/ Mac_SA_Secure.sh + +Charlie Feb 25 2008 + - Mac SCR: Add a test to directly determine when a graphics application window + obscures our moving logo animation; if so, stop showing moving logo to avoid + wasting CPU cycles. + + clientscr/ + mac_saver_module.cpp + Mac_Saver_Module.h + Mac_Saver_ModuleView.m,h diff --git a/clientscr/Mac_Saver_Module.h b/clientscr/Mac_Saver_Module.h index 2f5db12549..f0cc13cded 100644 --- a/clientscr/Mac_Saver_Module.h +++ b/clientscr/Mac_Saver_Module.h @@ -33,7 +33,7 @@ extern "C" { #endif int initBOINCSaver(Boolean ispreview); -int getSSMessage(char **theMessage); +int getSSMessage(char **theMessage, int* coveredFreq); void drawPreview(CGContextRef myContext); void closeBOINCSaver(void); void print_to_log_file(const char *format, ...); @@ -132,7 +132,7 @@ protected: char* m_CurrentBannerMessage; char* m_BrandText; public: - int getSSMessage(char **theMessage); + int getSSMessage(char **theMessage, int* coveredFreq); void drawPreview(CGContextRef myContext); void ShutdownSaver(); diff --git a/clientscr/Mac_Saver_ModuleView.h b/clientscr/Mac_Saver_ModuleView.h index 74ce0e6284..0c47c98b61 100644 --- a/clientscr/Mac_Saver_ModuleView.h +++ b/clientscr/Mac_Saver_ModuleView.h @@ -42,7 +42,7 @@ @end int initBOINCSaver(Boolean ispreview); -int getSSMessage(char **theMessage); +int getSSMessage(char **theMessage, int* coveredFreq); void drawPreview(CGContextRef myContext); void closeBOINCSaver(void); extern void print_to_log_file(const char *format, ...); diff --git a/clientscr/Mac_Saver_ModuleView.m b/clientscr/Mac_Saver_ModuleView.m index 326cfe76a7..a8ec01c8c5 100644 --- a/clientscr/Mac_Saver_ModuleView.m +++ b/clientscr/Mac_Saver_ModuleView.m @@ -24,6 +24,7 @@ #import "Mac_Saver_ModuleView.h" #include +#include void print_to_log_file(const char *format, ...); void strip_cr(char *buf); @@ -161,7 +162,6 @@ int signof(float x) { if ( [ self isPreview ] ) return; - closeBOINCSaver(); } @@ -173,7 +173,10 @@ int signof(float x) { - (void)animateOneFrame { int newFrequency = 0; + int coveredFreq = 0; NSRect theFrame = [ self frame ]; + int myWindowNumber; + int windowList[1]; NSRect currentDrawingRect, eraseRect; NSPoint imagePosition; Rect r; @@ -214,7 +217,32 @@ int signof(float x) { NSRect viewBounds = [self bounds]; - newFrequency = getSSMessage(&msg); + newFrequency = getSSMessage(&msg, &coveredFreq); + + // NOTE: My tests seem to confirm that the first window returned by NSWindowList + // is always the top window. However, Apple's documentation is unclear whether + // we can depend on this. So I am adding some safety by doing two things: + // [1] Only use the NSWindowList test when we have started project graphics. + // [2] Assume that our window is covered 45 seconds after starting project + // graphics even if the NSWindowList test did not indicate that is so. + // + // getSSMessage() returns a non-zero value for coveredFreq only if we have started + // project graphics. + // + // If we should use a different frequency when our window is covered by another + // window, then check whether there is a window at a higher z-level than ours. + if (coveredFreq) { + myWindowNumber = [ myWindow windowNumber ]; + + windowList[0] = 0; + NSWindowList(1, windowList); + if (windowList[0] != myWindowNumber) { + // Project graphics application has a window open above ours + // Don't waste CPU cycles since our window is obscured by application graphics + newFrequency = coveredFreq; + msg = NULL; + } + } // Clear the previous drawing area currentDrawingRect = gMovingRect; diff --git a/clientscr/mac_saver_module.cpp b/clientscr/mac_saver_module.cpp index f1e9e857c0..893f809fd0 100644 --- a/clientscr/mac_saver_module.cpp +++ b/clientscr/mac_saver_module.cpp @@ -89,7 +89,7 @@ const char * BOINCNoGraphicAppsExecutingMsg = "Project does not support graphic const char * BOINCUnrecoverableErrorMsg = "Sorry, an unrecoverable error occurred"; const char * BOINCTestmodeMsg = "BOINC screensaver test: success."; const char * BOINCV5GFXDaemonMsg = "BOINC can't display graphics from older applications when running as a daemon."; -const char * ScreenSaverAppStartingMsg = "Starting screensaver graphics. Please wait ..."; +const char * ScreenSaverAppStartingMsg = "Starting screensaver graphics.\nPlease wait ..."; //const char * BOINCExitedSaverMode = "BOINC is no longer in screensaver mode."; @@ -104,8 +104,8 @@ int initBOINCSaver(Boolean ispreview) { return gspScreensaver->Create(); } -int getSSMessage(char **theMessage) { - return gspScreensaver->getSSMessage(theMessage); +int getSSMessage(char **theMessage, int* coveredFreq) { + return gspScreensaver->getSSMessage(theMessage, coveredFreq); }; @@ -277,8 +277,9 @@ OSStatus CScreensaver::initBOINCApp() { // Returns new desired Animation Frequency (per second) or 0 for no change -int CScreensaver::getSSMessage(char **theMessage) { +int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) { int newFrequency = TEXTLOGOFREQUENCY; + *coveredFreq = 0; pid_t myPid; OSStatus err; @@ -340,8 +341,22 @@ int CScreensaver::getSSMessage(char **theMessage) { case SCRAPPERR_BOINCAPPFOUNDGRAPHICSLOADING: case SCRAPPERR_SCREENSAVERRUNNING: #if ! ALWAYS_DISPLAY_PROGRESS_TEXT + // NOTE: My tests seem to confirm that the first window returned by NSWindowList + // is always the top window. However, Apple's documentation is unclear whether + // we can depend on this. So I am adding some safety by doing two things: + // [1] Only use the NSWindowList test when we have started project graphics. + // [2] Assume that our window is covered 45 seconds after starting project + // graphics even if the NSWindowList test did not indicate that is so. + // + // The -animateOneFrame method in Mac_SaverModuleView.m does the NSWindowList test + // only if we return a non-zero value for coveredFreq. + // + // Tell the calling routine to set the frame rate to NOTEXTLOGOFREQUENCY if + // NSWindowList indicates that science app graphics window has covered our window. + *coveredFreq = NOTEXTLOGOFREQUENCY; if (m_iGraphicsStartingMsgCounter > 0) { - // Show ScreenSaverAppStartingMsg for GFX_STARTING_MSG_DURATION seconds + // Show ScreenSaverAppStartingMsg for GFX_STARTING_MSG_DURATION seconds or until + // NSWindowList indicates that science app graphics window has covered our window setSSMessageText(ScreenSaverAppStartingMsg); m_iGraphicsStartingMsgCounter--; } else { @@ -389,8 +404,9 @@ int CScreensaver::getSSMessage(char **theMessage) { if (m_MessageText[0]) { newFrequency = TEXTLOGOFREQUENCY; - } else + } else { newFrequency = NOTEXTLOGOFREQUENCY; + } *theMessage = m_MessageText; return newFrequency;