Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tools scons; Support osx idle on screensaver, screenlock #163

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*.app

# Build byproducts
/bin
/build
/package.txt
/package-description.txt
Expand Down
17 changes: 13 additions & 4 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ if env['PLATFORM'] == 'win32' or int(env.get('cross_mingw', 0)):
duplicate = 0)
Default(hide_console)

tools = SConscript('src/tools.scons', variant_dir = 'build', duplicate = 0)
Default(tools)
Depends(tools, client)
# Clean
Clean(client, ['build', 'config.log'])
Clean(client, ['bin', 'build', 'config.log'])

# Dist
docs = ['README.md', 'CHANGELOG.md', 'LICENSE']
distfiles = docs + [client, 'images/fahlogo.png']
distfiles = docs + client + tools + ['images/fahlogo.png']
if env['PLATFORM'] == 'posix':
distfiles.append('install/lin/fah-client.service')
if hide_console is not None: distfiles.append(hide_console)
Expand Down Expand Up @@ -116,27 +119,33 @@ if 'package' in COMMAND_LINE_TARGETS:
home = '.', # abs path or relative to PWD
pkg_scripts = 'build/install/osx/scripts', # relative to home
root = './build/pkg/root', # abs path or relative to PWD
sign_tools = ['usr/local/bin/fah-client'], # relative to root
sign_tools = ['usr/local/bin/fah-*'], # relative to root
must_close_apps = [
'org.foldingathome.fahviewer',
'org.foldingathome.fahcontrol',
'edu.stanford.folding.fahviewer',
'edu.stanford.folding.fahcontrol',
],
pkg_files = [
[str(client[0]), 'usr/local/bin/', 0o755],
['scripts/fahctl', 'usr/local/bin/', 0o755],
['build/install/osx/fahclient.url',
'Applications/Folding@home/[email protected]', 0o644],
['build/install/osx/uninstall.url',
'Applications/Folding@home/uninstall.url', 0o644],
['build/install/osx/fah-screen-agent.plist',
'Library/LaunchAgents/' +
'org.foldingathome.fah-screen-agent.plist', 0o644],
['build/install/osx/launchd.plist',
'Library/LaunchDaemons/' +
'org.foldingathome.fahclient.plist', 0o644]
],
pre_sign_callback = seticon,
)]

pkg_files = pkg_components[0]['pkg_files']
for tool in client + tools:
pkg_files += [[str(tool), 'usr/local/bin/', 0o755]]

# min pkg target macos 10.13
pkg_target = env.get('osx_min_ver', '10.13')
ver = tuple([int(x) for x in pkg_target.split('.')])
Expand Down
25 changes: 25 additions & 0 deletions install/osx/fah-screen-agent.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>Label</key>
<string>org.foldingathome.fah-screen-agent</string>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>LowPriorityIO</key>
<true/>
<key>Program</key>
<string>/usr/local/bin/fah-screen-agent</string>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/dev/null</string>
<key>Umask</key>
<integer>18</integer>
</dict>
</plist>
14 changes: 13 additions & 1 deletion install/osx/scripts/postinstall
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,24 @@ chmod -R u+rwX,go-w "$RUN_DIR"
chown -R nobody:nobody "$RUN_DIR"

PLIST=/Library/LaunchDaemons/org.foldingathome.fahclient.plist
AGENT_PLIST="/Library/LaunchAgents/org.foldingathome.fah-screen-agent.plist"

"$SCRIPTS"/organize-credits.sh &

# Start service
chmod 0644 "$PLIST"
chmod 0644 "$PLIST" "$AGENT_PLIST"
launchctl load -w "$PLIST"

# start, in case RunAtLoad is false
launchctl start org.foldingathome.fahclient || true

# restart any running agents in other sessions
# note that this does not reload their launchd jobs
killall -HUP fah-screen-agent || true

# start agent in user's gui session
conuser=$(/usr/bin/stat -f "%Su" /dev/console) || conuser="root"
conuid=$(/usr/bin/id -u "$conuser") || conuid=0
if [[ $conuid != 0 ]]; then
launchctl bootstrap gui/$conuid "$AGENT_PLIST" || true
fi
10 changes: 10 additions & 0 deletions install/osx/scripts/preinstall
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SCRIPTS="$(dirname "$0")"
OLD_LAUNCHD="/Library/LaunchDaemons/FAHClient.plist"
OLD_LAUNCHD2="/Library/LaunchDaemons/edu.stanford.folding.fahclient.plist"
NEW_LAUNCHD="/Library/LaunchDaemons/org.foldingathome.fahclient.plist"
AGENT_PLIST="/Library/LaunchAgents/org.foldingathome.fah-screen-agent.plist"

if [ -f "$NEW_LAUNCHD" ]; then
launchctl unload -w "$NEW_LAUNCHD" || true
Expand All @@ -23,6 +24,15 @@ if [ -f "$OLD_LAUNCHD" ]; then
rm -f "$OLD_LAUNCHD" || true
fi

if [ -f "$AGENT_PLIST" ]; then
# stop agent running in console user's session and unload job
conuser=$(/usr/bin/stat -f "%Su" /dev/console) || conuser="root"
conuid=$(/usr/bin/id -u "$conuser") || conuid=0
if [[ $conuid != 0 ]]; then
launchctl bootout gui/$conuid "$AGENT_PLIST" || true
fi
fi

# Assuming upgrade, remove old stuff
F1="/Applications/FAHClient.url"
F2="/Applications/Folding@home/Web Control.url"
Expand Down
73 changes: 70 additions & 3 deletions src/fah/client/osx/OSXOSImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include <pwd.h>
#include <unistd.h>

#include <fah/screen-agent/defines.h>

using namespace FAH::Client;
using namespace cb;
using namespace std;
Expand All @@ -60,6 +62,9 @@ enum {


namespace {
CFStringRef kScreenIdle = CFSTR(SCREEN_IDLE_NOTIFICATION);
CFStringRef kScreenNotIdle = CFSTR(SCREEN_NOT_IDLE_NOTIFICATION);

#pragma mark c callbacks
void consoleUserCB(SCDynamicStoreRef s, CFArrayRef keys, void *info) {
OSXOSImpl::instance().consoleUserChanged(s, keys, info);
Expand All @@ -85,6 +90,20 @@ namespace {
<< CFStringGetCStringPtr(name, kCFStringEncodingUTF8));
OSXOSImpl::instance().requestExit();
}


void screenIdleCB(CFNotificationCenterRef center, void *observer,
CFNotificationName name, const void *object,
CFDictionaryRef info) {
OSXOSImpl::instance().noteScreenIdle();
}


void screenNotIdleCB(CFNotificationCenterRef center, void *observer,
CFNotificationName name, const void *object,
CFDictionaryRef info) {
OSXOSImpl::instance().noteScreenNotIdle();
}
}


Expand Down Expand Up @@ -187,9 +206,10 @@ void OSXOSImpl::finishInit() {


void OSXOSImpl::updateSystemIdle() {
bool shouldBeIdle = displayPower == kDisplayPowerOff || loginwindowIsActive ||
screensaverIsActive || screenIsLocked;

bool shouldBeIdle;
if (gotScreenNotIdleRecently()) shouldBeIdle = false;
else shouldBeIdle = displayPower == kDisplayPowerOff || loginwindowIsActive ||
gotScreenIdleRecently();
if (shouldBeIdle == systemIsIdle) return;
systemIsIdle = shouldBeIdle;

Expand Down Expand Up @@ -415,10 +435,57 @@ bool OSXOSImpl::registerForConsoleUserNotifications() {
}


void OSXOSImpl::noteScreenIdle() {
screenIdleExpiry =
dispatch_time(DISPATCH_TIME_NOW, SCREEN_NOTIFICATION_EXPIRES * NSEC_PER_SEC);
bool wasIdle = screenIdle;
screenIdle = true;
dispatch_after(screenIdleExpiry + NSEC_PER_SEC, dispatch_get_main_queue(), ^{
updateSystemIdle();
});
if (!wasIdle) delayedUpdateSystemIdle(5);
}


void OSXOSImpl::noteScreenNotIdle() {
screenNotIdleExpiry =
dispatch_time(DISPATCH_TIME_NOW, SCREEN_NOTIFICATION_EXPIRES * NSEC_PER_SEC);
screenNotIdle = true;
dispatch_after(screenNotIdleExpiry + NSEC_PER_SEC,dispatch_get_main_queue(),^{
updateSystemIdle();
});
updateSystemIdle();
}


bool OSXOSImpl::gotScreenIdleRecently() {
if (!screenIdle) return false;
if (dispatch_time(DISPATCH_TIME_NOW, 0) < screenIdleExpiry) return true;
screenIdle = false;
return false;
}


bool OSXOSImpl::gotScreenNotIdleRecently() {
if (!screenNotIdle) return false;
if (dispatch_time(DISPATCH_TIME_NOW, 0) < screenNotIdleExpiry) return true;
screenNotIdle = false;
return false;
}


bool OSXOSImpl::registerForDarwinNotifications() {
CFNotificationCenterRef nc = CFNotificationCenterGetDarwinNotifyCenter();
if (!nc) return false;

CFNotificationCenterAddObserver(
nc, (void *)this, &screenIdleCB, kScreenIdle, 0,
CFNotificationSuspensionBehaviorCoalesce);

CFNotificationCenterAddObserver(
nc, (void *)this, &screenNotIdleCB, kScreenNotIdle, 0,
CFNotificationSuspensionBehaviorCoalesce);

string user = "nobody";
struct passwd *pwent = getpwuid(getuid());
if (pwent && pwent->pw_name) user = pwent->pw_name;
Expand Down
12 changes: 10 additions & 2 deletions src/fah/client/osx/OSXOSImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ namespace FAH {
static OSXOSImpl *singleton;

std::atomic<bool> systemIsIdle = false;
bool screensaverIsActive = false;
bool screenIsLocked = false;
bool loginwindowIsActive = false;

io_service_t displayWrangler = 0;
Expand All @@ -62,6 +60,12 @@ namespace FAH {

int displayPower = 0;

// these are notification received bools; both are needed
bool screenIdle = false;
bool screenNotIdle = false;
dispatch_time_t screenIdleExpiry = 0;
dispatch_time_t screenNotIdleExpiry = 0;

public:
OSXOSImpl(App &app);
~OSXOSImpl();
Expand All @@ -82,12 +86,16 @@ namespace FAH {
void displayPowerChanged
(void *context, io_service_t service, natural_t mtype, void *marg);
void finishInit();
void noteScreenIdle();
void noteScreenNotIdle();

protected:
void initialize();
void addHeartbeatTimerToRunLoop(CFRunLoopRef loop);
void deregisterForConsoleUserNotifications();
bool registerForConsoleUserNotifications();
bool gotScreenIdleRecently();
bool gotScreenNotIdleRecently();
bool registerForDarwinNotifications();
void deregisterForDisplayPowerNotifications();
bool registerForDisplayPowerNotifications();
Expand Down
39 changes: 39 additions & 0 deletions src/fah/screen-agent/defines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/******************************************************************************\

This file is part of the Folding@home Client.

The fah-client runs Folding@home protein folding simulations.
Copyright (c) 2001-2023, foldingathome.org
All rights reserved.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

For information regarding this software email:
Joseph Coffland
[email protected]

\******************************************************************************/

#pragma once

// Defines shared with fah-client

#define SCREEN_IDLE_NOTIFICATION "org.foldingathome.screen.idle"
#define SCREEN_NOT_IDLE_NOTIFICATION "org.foldingathome.screen.notidle"

#define SCREEN_NOTIFICATION_INTERVAL 60
#define SCREEN_NOTIFICATION_LEEWAY 2
#define SCREEN_NOTIFICATION_EXPIRES (\
SCREEN_NOTIFICATION_INTERVAL + 2 * SCREEN_NOTIFICATION_LEEWAY + 1)
Loading