Merge pull request #5411 from BOINC/mac_Os14_SS_hotfix

Mac screensaver: update for MacOS 14.0 Sonoma
This commit is contained in:
Vitalii Koshura 2023-10-28 15:24:40 +02:00 committed by GitHub
commit e08cbf08f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 204 additions and 104 deletions

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2020 University of California
// Copyright (C) 2023 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -40,6 +40,7 @@ int startBOINCSaver(void);
int getSSMessage(char **theMessage, int* coveredFreq);
void windowIsCovered();
void drawPreview(CGContextRef myContext);
void stopAllGFXApps(void);
void closeBOINCSaver(void);
void setDefaultDisplayPeriods(void);
bool getShow_default_ss_first();
@ -61,6 +62,8 @@ extern char gUserName[64];
extern bool gIsMojave;
extern bool gIsCatalina;
extern bool gIsHighSierra;
extern bool gIsSonoma;
extern bool gCant_Use_Shared_Offscreen_Buffer;
#ifdef __cplusplus
} // extern "C"
@ -164,6 +167,7 @@ public:
int getSSMessage(char **theMessage, int* coveredFreq);
void windowIsCovered(void);
void drawPreview(CGContextRef myContext);
void Shared_Offscreen_Buffer_Unavailable(void);
void ShutdownSaver();
void markAsIncompatible(char *gfxAppName);
bool isIncompatible(char *appName);

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2020 University of California
// Copyright (C) 2023 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -77,6 +77,7 @@ int startBOINCSaver(void);
int getSSMessage(char **theMessage, int* coveredFreq);
void windowIsCovered();
void drawPreview(CGContextRef myContext);
void stopAllGFXApps(void);
void closeBOINCSaver(void);
void setDefaultDisplayPeriods(void);
bool getShow_default_ss_first();
@ -98,6 +99,8 @@ void PrintBacktrace(void);
extern bool gIsCatalina;
extern bool gIsHighSierra;
extern bool gIsMojave;
extern bool gIsSonoma;
extern bool gCant_Use_Shared_Offscreen_Buffer;
#ifdef __cplusplus
} // extern "C"

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2022 University of California
// Copyright (C) 2023 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -136,7 +136,6 @@ NSInteger myWindowNumber;
NSRect gMovingRect;
float gImageXIndent;
float gTextBoxHeight;
CGFloat gActualTextBoxHeight;
NSPoint gCurrentPosition;
NSPoint gCurrentDelta;
@ -196,6 +195,10 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
imageView = nil;
}
}
} else {
if (gCant_Use_Shared_Offscreen_Buffer) {
stopAllGFXApps();
}
}
}
@ -214,6 +217,7 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
gIsMojave = (compareOSVersionTo(10, 14) >= 0);
gIsCatalina = (compareOSVersionTo(10, 15) >= 0);
gIsBigSur = (compareOSVersionTo(11, 0) >= 0);
gIsSonoma = (compareOSVersionTo(14, 0) >= 0);
if (gIsCatalina) {
// Under OS 10.15, isPreview is often true even when it shouldn't be
@ -354,8 +358,6 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
gCurrentDelta.x = 1.0;
gCurrentDelta.y = 1.0;
gActualTextBoxHeight = MINTEXTBOXHEIGHT;
[ self setAnimationTimeInterval:1/8.0 ];
}
@ -447,12 +449,32 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
NSUInteger n;
double maxWaitTime;
NSRect currentDrawingRect, eraseRect;
CGFloat actualTextBoxHeight = MINTEXTBOXHEIGHT;
NSPoint imagePosition;
char *msg;
CFStringRef cf_msg;
double timeToBlock, frameStartTime = getDTime();
HIThemeTextInfo textInfo;
NSWindow *myWindow = [ self window ];
NSRect windowFrame = [ myWindow frame ];
if (gIsSonoma) {
// Under MacOS 14 Sonoma, screensavers continue to run and "draw" invisibly
// after they are dismissed by user activity, to allow them to be used as
// wallpaper. Since we don't want the BOINC screensaver to be used as wallpaper,
// this would waste system resources.
// The only way I've found to determine that the screensaver has been dismissed
// by the user is this test of the window level.
if ((windowFrame.size.width > 500.) && (windowFrame.size.height > 500.)) {
if ([ [ self window ] level ] == 0) {
//TODO: more cleanup as in stopAnimation ??
closeBOINCSaver();
return;
}
}
}
if (myIsPreview) {
#if 1 // Currently drawRect just draws our logo in the preview window
if (gPreview_Image == NULL) {
@ -474,8 +496,6 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
return;
}
NSWindow *myWindow = [ self window ];
#if ! DEBUG_UNDER_XCODE
// For unkown reasons, OS 10.7 Lion screensaver and later delay several seconds
// after user activity before calling stopAnimation, so we check user activity here
@ -489,7 +509,6 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
}
}
NSRect windowFrame = [ myWindow frame ];
if ( (windowFrame.origin.x != 0) || (windowFrame.origin.y != 0) ) {
// Hide window on second display to aid in debugging
#ifdef _DEBUG
@ -688,30 +707,18 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
if ( (msg != NULL) && (msg[0] != '\0') ) {
// Set direction of motion to "bounce" off edges of screen
if (currentDrawingRect.origin.x <= SAFETYBORDER) {
gCurrentDelta.x = (float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.y = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.y)) / 16.;
}
if ( (currentDrawingRect.origin.x + currentDrawingRect.size.width) >=
(viewBounds.origin.x + viewBounds.size.width - SAFETYBORDER) ) {
gCurrentDelta.x = -(float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.y = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.y)) / 16.;
}
if (currentDrawingRect.origin.y + gTextBoxHeight - gActualTextBoxHeight <= SAFETYBORDER) {
gCurrentDelta.y = (float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.x = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.x)) / 16.;
}
if ( (currentDrawingRect.origin.y + currentDrawingRect.size.height) >=
(viewBounds.origin.y + viewBounds.size.height - SAFETYBORDER) ) {
gCurrentDelta.y = -(float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.x = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.x)) / 16.;
}
#if 0
// For testing
gCurrentDelta.x = 0;
gCurrentDelta.y = 0;
#endif
cf_msg = CFStringCreateWithCString(NULL, msg, kCFStringEncodingMacRoman);
CTFontRef myFont = CTFontCreateWithName(CFSTR("Helvetica"), 20, NULL);
HIThemeTextInfo theTextInfo = {kHIThemeTextInfoVersionOne, kThemeStateActive, kThemeSpecifiedFont,
kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop,
kHIThemeTextBoxOptionNone, kHIThemeTextTruncationNone, 0, false,
0, myFont
};
textInfo = theTextInfo;
HIThemeGetTextDimensions(cf_msg, (float)gMovingRect.size.width, &textInfo, NULL, &actualTextBoxHeight, NULL);
gTextBoxHeight = actualTextBoxHeight + TEXTBOXTOPBORDER;
if (!isErased) {
[[NSColor blackColor] set];
@ -751,7 +758,34 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
eraseRect = NSInsetRect(eraseRect, -1, -1);
NSRectFill(eraseRect);
isErased = true;
isErased = true;
// If text has changed and it now goes below bottom of screen, jump up to show it all.
if ((gCurrentPosition.y - gTextBoxHeight) <= SAFETYBORDER) {
gCurrentPosition.y = SAFETYBORDER + 1 + gTextBoxHeight;
if (gCurrentDelta.y < 0) {
gCurrentDelta.y = (float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
}
}
// Set direction of motion to "bounce" off edges of screen
if ( (gCurrentDelta.x < 0) && (gCurrentPosition.x <= SAFETYBORDER) ) {
gCurrentDelta.x = (float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.y = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.y)) / 16.;
}
if ( (gCurrentDelta.x > 0) && ( (gCurrentPosition.x + gMovingRect.size.width) >=
(viewBounds.origin.x + viewBounds.size.width - SAFETYBORDER) ) ){
gCurrentDelta.x = -(float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.y = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.y)) / 16.;
}
if ( (gCurrentDelta.y < 0) && (gCurrentPosition.y - gTextBoxHeight <= SAFETYBORDER) ) {
gCurrentDelta.y = (float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.x = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.x)) / 16.;
}
if ( (gCurrentDelta.y > 0) && ( (gCurrentPosition.y + gMovingRect.size.height) >=
(viewBounds.origin.y + viewBounds.size.height - SAFETYBORDER) ) ) {
gCurrentDelta.y = -(float)SSRandomIntBetween(MINDELTA, MAXDELTA) / 16.;
gCurrentDelta.x = (float)(SSRandomIntBetween(MINDELTA, MAXDELTA) * signof(gCurrentDelta.x)) / 16.;
}
}
// Get the new drawing area
@ -762,48 +796,33 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
imagePosition.y = (float) (int)gCurrentPosition.y;
[ gBOINC_Logo drawAtPoint:imagePosition fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0 ];
#if 0
// For testing
gCurrentDelta.x = 0;
gCurrentDelta.y = 0;
#endif
CGRect bounds = CGRectMake((float) ((int)gCurrentPosition.x),
viewBounds.size.height - imagePosition.y + TEXTBOXTOPBORDER,
gMovingRect.size.width,
MAXTEXTBOXHEIGHT
);
if ( (msg != NULL) && (msg[0] != '\0') ) {
cf_msg = CFStringCreateWithCString(NULL, msg, kCFStringEncodingMacRoman);
CGContextSaveGState (myContext);
CGContextTranslateCTM (myContext, 0, viewBounds.origin.y + viewBounds.size.height);
CGContextScaleCTM (myContext, 1.0f, -1.0f);
CGRect bounds = CGRectMake((float) ((int)gCurrentPosition.x),
viewBounds.size.height - imagePosition.y + TEXTBOXTOPBORDER,
gMovingRect.size.width,
MAXTEXTBOXHEIGHT
);
CGFloat myWhiteComponents[] = {1.0, 1.0, 1.0, 1.0};
CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB ();
CGColorRef myTextColor = CGColorCreate(myColorSpace, myWhiteComponents);
CGContextSaveGState (myContext);
CGContextTranslateCTM (myContext, 0, viewBounds.origin.y + viewBounds.size.height);
CGContextScaleCTM (myContext, 1.0f, -1.0f);
CGContextSetFillColorWithColor(myContext, myTextColor);
CTFontRef myFont = CTFontCreateWithName(CFSTR("Helvetica"), 20, NULL);
HIThemeDrawTextBox(cf_msg, &bounds, &textInfo, myContext, kHIThemeOrientationNormal);
HIThemeTextInfo theTextInfo = {kHIThemeTextInfoVersionOne, kThemeStateActive, kThemeSpecifiedFont,
kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop,
kHIThemeTextBoxOptionNone, kHIThemeTextTruncationNone, 0, false,
0, myFont
};
textInfo = theTextInfo;
HIThemeGetTextDimensions(cf_msg, (float)gMovingRect.size.width, &textInfo, NULL, &gActualTextBoxHeight, NULL);
gActualTextBoxHeight += TEXTBOXTOPBORDER;
CGFloat myWhiteComponents[] = {1.0, 1.0, 1.0, 1.0};
CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB ();
CGColorRef myTextColor = CGColorCreate(myColorSpace, myWhiteComponents);
CGContextSetFillColorWithColor(myContext, myTextColor);
HIThemeDrawTextBox(cf_msg, &bounds, &textInfo, myContext, kHIThemeOrientationNormal);
CGColorRelease(myTextColor);
CGColorSpaceRelease(myColorSpace);
CGContextRestoreGState (myContext);
CFRelease(cf_msg);
}
gTextBoxHeight = MAXTEXTBOXHEIGHT + TEXTBOXTOPBORDER;
gMovingRect.size.height = [gBOINC_Logo size].height + gTextBoxHeight;
CGColorRelease(myTextColor);
CGColorSpaceRelease(myColorSpace);
CGContextRestoreGState (myContext);
CFRelease(cf_msg);
isErased = false;
@ -813,7 +832,6 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
[[NSColor blackColor] set];
isErased = true;
NSRectFill(eraseRect);
gTextBoxHeight = MAXTEXTBOXHEIGHT;
gMovingRect.size.height = [gBOINC_Logo size].height + gTextBoxHeight;
}
}
@ -831,7 +849,10 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) {
// Check for a new graphics app sending us data
if (UseSharedOffscreenBuffer() && gfxAppStartTime) {
if (mySharedGraphicsController) {
[mySharedGraphicsController testConnection];
if (!runningSharedGraphics) {
// wait for a connection from a gfx app
[mySharedGraphicsController testConnection];
}
}
}
}
@ -1089,10 +1110,17 @@ static bool okToDraw;
if (machErr == KERN_SUCCESS) {
serverPort = (NSMachPort*)[NSMachPort portWithMachPort:servicePortNum];
} else {
if (machErr == BOOTSTRAP_NOT_PRIVILEGED) {
// As of MacOS 14.0, the legacyScreenSave sandbox prevents using
// IOSurfaceLookupFromMachPort. I have filed bug report FB13300491
// with Apple and hope they will change this in future MacOS.
gCant_Use_Shared_Offscreen_Buffer = true;
stopAllGFXApps();
}
serverPort = MACH_PORT_NULL;
}
if(serverPort != MACH_PORT_NULL)
if ((serverPort != MACH_PORT_NULL) && (localPort == MACH_PORT_NULL))
{
// Create our own local port.
localPort = [[NSMachPort alloc] init];
@ -1132,14 +1160,14 @@ static bool okToDraw;
[serverPort invalidate];
// [serverPort release];
}
serverPort = nil;
serverPort = MACH_PORT_NULL;
[localPort removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
if ([localPort isValid]) {
[localPort invalidate];
}
// [localPort release];
localPort = nil;
localPort = MACH_PORT_NULL;
int i;
for(i = 0; i < NUM_IOSURFACE_BUFFERS; i++) {
@ -1159,13 +1187,14 @@ static bool okToDraw;
}
}
if ((serverPort == nil) && (localPort == nil)) {
if ((serverPort == MACH_PORT_NULL) && (localPort == MACH_PORT_NULL)) {
runningSharedGraphics = false;
[openGLView removeFromSuperview]; // Releases openGLView
openGLView = nil;
}
}
}
- (void)handleMachMessage:(void *)msg
{
union __ReplyUnion___MGCMGSServer_subsystem reply;
@ -1402,6 +1431,12 @@ static bool UseSharedOffscreenBuffer() {
static bool needSharedGfxBuffer = false;
//return true; // FOR TESTING ONLY
// As of MacOS 14.0, the legacyScreenSaver sandbox prevents using
// IOSurfaceLookupFromMachPort. I have filed bug report FB13300491
// with Apple and hope they will change this in future MacOS.
if (gCant_Use_Shared_Offscreen_Buffer) {
return false;
}
if (alreadyTested) {
return needSharedGfxBuffer;
}

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2022 University of California
// Copyright (C) 2023 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -207,7 +207,13 @@ int main(int argc, char* argv[]) {
#endif
parentPid = getppid();
bool cover_gfx_window = (compareOSVersionTo(10, 13) >= 0);
// Under MacOS 14.0, the legacyScreenSaver continues to run after the
// screensaver is dismissed. Our code elsewhere now kills it, but if
// that were to fail this black cover would block the user from
// accessing the desktop, so don't use the cover in MacOS 14 for now.
bool cover_gfx_window = (compareOSVersionTo(10, 13) >= 0) &&
(compareOSVersionTo(10, 14) < 0);
// Create shared app instance
[NSApplication sharedApplication];

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2022 University of California
// Copyright (C) 2023 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -18,9 +18,9 @@
// gfx_switcher.C
//
// Used by screensaver to:
// - launch graphics application at given slot number as user & group boinc_project
// - launch default graphics application as user & group boinc_project
// - kill graphics application with given process ID as user & group boinc_project
// - launch graphics application at given slot number
// - launch default graphics application
// - kill graphics application with given process ID
//
// Special logic used only under OS 10.15 Catalina and later:
@ -35,11 +35,11 @@
// app. This script then launches gfx_switcher, which uses fork and execv to
// launch the project graphics app. gfx_switcher writes the graphics app's
// process ID to shared memory, to be read by the Screensaver Coordinator.
// gfx_switcher waits for the graphics app to exit and notifies then notifies
// the Screensaver Coordinator by writing 0 to the shared memory.
// gfx_switcher waits for the graphics app to exit and then notifies the
// Screensaver Coordinator by writing 0 to the shared memory.
//
// This Rube Goldberg process is necessary due to limitations on screensavers
// introduced in OS 10.15 Catalina.
// introduced in OS 10.15 Catalina and OS 14.0 Sonoma.
//
@ -106,7 +106,7 @@ int main(int argc, char** argv) {
CFStringRef cf_gUserName = SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL);
CFStringGetCString(cf_gUserName, user_name, sizeof(user_name), kCFStringEncodingUTF8);
// strlcpy(user_name, getlogin(), sizeof(user_name));
// strlcpy(user_name, getenv("USER"), sizeof(user_name));
strlcpy(group_name, "boinc_project", sizeof(group_name));
// Under fast user switching, the BOINC client may be running under a
@ -319,6 +319,10 @@ void * MonitorScreenSaverEngine(void* param) {
print_to_log_file("MonitorScreenSaverEngine: ScreenSaverEngine_Pid=%d", ScreenSaverEngine_Pid);
#endif
if (ScreenSaverEngine_Pid == 0) {
// legacyScreenSaver name under MacOS 14 Sonoma
ScreenSaverEngine_Pid = getPidIfRunning("com.apple.ScreenSaver.Engine.legacyScreenSaver");
}
if (ScreenSaverEngine_Pid == 0) {
#ifdef __x86_64__
ScreenSaverEngine_Pid = getPidIfRunning("com.apple.ScreenSaver.Engine.legacyScreenSaver.x86_64");
#elif defined(__arm64__)

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2022 University of California
// Copyright (C) 2023 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -106,9 +106,14 @@ static pthread_mutexattr_t saver_mutex_attr;
pthread_mutex_t saver_mutex;
static char passwd_buf[256];
char gUserName[64];
bool gIsHighSierra = false; // OS 10.13 or later
bool gIsHighSierra = false; // OS 10.13 or later
bool gIsMojave = false; // OS 10.14 or later
bool gIsCatalina = false; // OS 10.15 or later
bool gIsSonoma = false; // OS 14.0 or later
// As of MacOS 14.0, the legacyScreenSave sandbox
// prevents using IOSurfaceLookupFromMachPort.
bool gCant_Use_Shared_Offscreen_Buffer = false;
const char * CantLaunchCCMsg = "Unable to launch BOINC application.";
const char * LaunchingCCMsg = "Launching BOINC application.";
@ -123,6 +128,7 @@ const char * DefaultGFXAppCrashedMsg = "Default screensaver module had an unrec
const char * RunningOnBatteryMsg = "Computing and screensaver disabled while running on battery power.";
const char * IncompatibleMsg = "Could not connect to screensaver ";
const char * CCNotRunningMsg = "BOINC is not running.";
const char * NoScreenSaverGraphicsThisMacOS = "BOINC can't show screensaver graphics on this version of MacOS";
//const char * BOINCExitedSaverMode = "BOINC is no longer in screensaver mode.";
@ -182,6 +188,13 @@ void drawPreview(CGContextRef myContext) {
};
void stopAllGFXApps() {
if (gspScreensaver) {
gspScreensaver->Shared_Offscreen_Buffer_Unavailable();
}
}
// If there are multiple displays, this may get called
// multiple times (once for each display), so we need to guard
// against any problems that may cause.
@ -400,7 +413,7 @@ int CScreensaver::Create() {
strlcpy(m_gfx_Cleanup_Path, "\"", sizeof(m_gfx_Cleanup_Path));
strlcat(m_gfx_Cleanup_Path, m_gfx_Switcher_Path, sizeof(m_gfx_Cleanup_Path));
strlcat(m_gfx_Switcher_Path, "/gfx_switcher", sizeof(m_gfx_Switcher_Path));
strlcat(m_gfx_Cleanup_Path, "/gfx_cleanup\"", sizeof(m_gfx_Switcher_Path));
strlcat(m_gfx_Cleanup_Path, "/gfx_cleanup\"", sizeof(m_gfx_Cleanup_Path));
// Launch helper app to work around a bug in OS 10.15 Catalina to
// kill current graphics app if ScreensaverEngine exits without
@ -466,6 +479,11 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) {
return NOTEXTLOGOFREQUENCY;
}
if (gCant_Use_Shared_Offscreen_Buffer) {
gspScreensaver->setSSMessageText(NoScreenSaverGraphicsThisMacOS);
goto msgIsSet;
}
CheckDualGPUPowerSource();
switch (saverState) {
@ -636,6 +654,7 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) {
}
}
msgIsSet:
if (m_MessageText[0]) {
newFrequency = TEXTLOGOFREQUENCY;
} else {
@ -657,6 +676,11 @@ void CScreensaver::drawPreview(CGContextRef myContext) {
}
void CScreensaver::Shared_Offscreen_Buffer_Unavailable() {
DestroyDataManagementThread(); // Kills current GFX app
}
void CScreensaver::ShutdownSaver() {
DestroyDataManagementThread();
@ -689,6 +713,14 @@ void CScreensaver::ShutdownSaver() {
fflush(m_gfx_Cleanup_IPC);
pclose(m_gfx_Cleanup_IPC);
}
// Under MacOS 14.0 Sonoma, screensavers continue to run and "draw" invisibly
// after they are dismissed by user activity, to allow them to be used as
// wallpaper. Since we don't want the BOINC screensaver to be used as wallpaper,
// this would waste system resources.
if (gIsSonoma) {
KillScreenSaver();
}
}
@ -1014,9 +1046,8 @@ void print_to_log_file(const char *format, ...) {
char buf[256];
time_t t;
#if USE_SPECIAL_LOG_FILE
safe_strcpy(buf, "/Users/");
safe_strcat(buf, getlogin());
safe_strcat(buf, "/Documents/test_log.txt");
safe_strcat(buf, getenv("HOME"));
safe_strcat(buf, "/Documents/ss_test_log.txt");
FILE *f;
f = fopen(buf, "a");
if (!f) return;

View File

@ -6,3 +6,5 @@
(deny file-write* (subpath "/Library/Application Support") )
(allow file-write* (subpath "/Library/Application Support/BOINC Data") (subpath "/private/tmp") )
(allow file-read* (subpath "/Library/Application Support/BOINC Data") (subpath "/private/tmp") )
(allow file-read* (subpath "/private/var/select/sh") )
(allow mach-lookup mach-register)

View File

@ -1678,19 +1678,27 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
}
}
if (! saverAlreadySetForAll) {
if (gCommandLineInstall) {
err = stat("/tmp/setboincsaver.txt", &sbuf);
if (err == noErr) {
puts("setboincsaver.txt file detected\n");
fflush(stdout);
unlink("/tmp/setboincsaver.txt");
setSaverForAllUsers = true;
}
} else {
setSaverForAllUsers = ShowMessage(true,
// As of MacOS 14.0, the legacyScreenSaver sandbox prevents using
// IOSurfaceLookupFromMachPort. I have filed bug report FB13300491
// with Apple and hope they will change this in a future MacOS.
// Also as of MacOS 14.0 Sonoma, we can't set the screensaver
//automatically. I have filed bug report FB13270885 about this.
// See a;so the comment at top of SetScreenSaverSelection().
if (compareOSVersionTo(14, 0) < 0) {
if (! saverAlreadySetForAll) {
if (gCommandLineInstall) {
err = stat("/tmp/setboincsaver.txt", &sbuf);
if (err == noErr) {
puts("setboincsaver.txt file detected\n");
fflush(stdout);
unlink("/tmp/setboincsaver.txt");
setSaverForAllUsers = true;
}
} else {
setSaverForAllUsers = ShowMessage(true,
(char *)_("Do you want to set %s as the screensaver for all %s users on this Mac?"),
brandName[brandID], brandName[brandID]);
}
}
}
@ -2008,6 +2016,8 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
}
// As of MacOS 14.0 Sonoma, this code no longer will detect the current screensaver,
// and will need to be rewritten. See the comment at top of SetScreenSaverSelection().
OSErr GetCurrentScreenSaverSelection(passwd *pw, char *moduleName, size_t maxLen) {
char buf[1024];
FILE *f;
@ -2047,6 +2057,11 @@ OSErr GetCurrentScreenSaverSelection(passwd *pw, char *moduleName, size_t maxLen
}
// As of MacOS 14.0 Sonoma, we can't set the screensaver automatically.
// I have filed bug report FB13270885 about this. After this is fixed,
// probably need to put an AppleScript to do this in the launch agent
// we add for each user. See also:
// https://forum.iscreensaver.com/t/understanding-the-macos-sonoma-screensaver-plist/718
OSErr SetScreenSaverSelection(char *moduleName, char *modulePath, int type) {
OSErr err = noErr;
CFStringRef preferenceName = CFSTR("com.apple.screensaver");