AppNapもどき、結構いい感じです。
いくつか、改善しました。
AppNapライクにWebProcessをコントロール(cputhrottle & applescript)のバージョンアップ版です。
改善ポイント
- with administrator privilegesでのパスワード確認ダイアログを表示させない
- 終了時に起動しているcputhrottleを終了する対応
- Firefox、Safariが起動していない場合にログがわんさか出力される不具合の対応
未解決事項
- macがスリープ、復帰後、appnap-browser.appの配列操作に起因するエラーが発生し、appが終了する
appnap-webbrowser.app(applescript) v2.0
前提
- cputhrottleコマンドがインストールされている。/tmp/cputhrottleに存在している
- スクリプトを実行するユーザは管理者権限を持っている
cputhrottleは、こちら(AppNapライクにWebProcessをコントロール(cputhrottle & applescript))を参考にしてください。
ソース
以下ソースをAppleScriptエディタにコピペします。
myPasswordを自分のパスワードに書き換えてください。
ファイルフォーマット:アプリケーション、オプションとして「ハンドラの実行時に終了しない」を選んで、書き出します。
(ここではファイル名:appnap-browser.appを想定しています)
global CPU_SLOW_PERCENTAGE global myProcessDataList global myPassword set myPassword to "-- 管理者パスワードに置き換えてください --" set CPU_SLOW_PERCENTAGE to "5" set myProcessDataList to {} script ProcessData property pid : -1 property procName : "" on new(thePid, theProcName) copy me to theData set_pid(thePid) of theData set_procName(theProcName) of theData theData end new on set_pid(value) set pid to value end set_pid on set_procName(value) set procName to value end set_procName end script on FindProcessDataList(theList, theProcName, retList) repeat with v in theList if procName of v is equal to theProcName then set end of retList to v end if end repeat return retList end FindProcessDataList on DeleteProcessDataList(theList, theProcName) set retList to {} repeat with v in theList if procName of v is not equal to theProcName then set end of retList to v end if end repeat return retList end DeleteProcessDataList on StartBackgroundCpuControl(theProcName, theControledList) tell application "System Events" set pList to (unix id of every process whose name contains theProcName) if pList is not equal to {} then syslog("StartBackgroundCpuControl " & theProcName & "") of me repeat with unixID in pList syslog("cputhrottle " & (unixID as string) & " " & CPU_SLOW_PERCENTAGE) of me do shell script "/tmp/cputhrottle " & (unixID as string) & " " & CPU_SLOW_PERCENTAGE & " >/dev/null 2>&1 & echo $!" password myPassword with administrator privileges set pid to result set end of theControledList to new(pid, theProcName) of ProcessData end repeat end if end tell end StartBackgroundCpuControl on StopBackgroundCpuControl(theControledList) syslog("StopBackgroundCpuControl targetCount=" & (length of theControledList as string) & "") of me tell application "System Events" repeat with v in theControledList do shell script "kill -INT " & (pid of v as string) password myPassword with administrator privileges end repeat end tell end StopBackgroundCpuControl on idle try tell application "System Events" set activeProcs to every process whose frontmost is true set activeProc to item 1 of activeProcs tell activeProc set activeProcName to name end tell end tell if activeProcName is equal to "Safari" then set targetProcess to {} set targetProcess to FindProcessDataList(myProcessDataList, "WebProcess", targetProcess) if length of targetProcess is not equal to 0 then StopBackgroundCpuControl(targetProcess) set myProcessDataList to DeleteProcessDataList(myProcessDataList, "WebProcess") end if else if activeProcName is equal to "Firefox" then set targetProcess to {} set targetProcess to FindProcessDataList(myProcessDataList, "Firefox", targetProcess) if length of targetProcess is not equal to 0 then StopBackgroundCpuControl(targetProcess) set myProcessDataList to DeleteProcessDataList(myProcessDataList, "Firefox") end if else set targetProcess to {} set targetProcess to FindProcessDataList(myProcessDataList, "WebProcess", targetProcess) if length of targetProcess is equal to 0 then -- 制御中は、再実行しない StartBackgroundCpuControl("WebProcess", myProcessDataList) end if set targetProcess to {} set targetProcess to FindProcessDataList(myProcessDataList, "Firefox", targetProcess) if length of targetProcess is equal to 0 then -- 制御中は、再実行しない StartBackgroundCpuControl("Firefox", myProcessDataList) end if end if return 1 on error errorMessage number errorNumber syslog("errorMessage: " & errorMessage & ", errorNumber: " & errorNumber) error end try end idle on quit set targetProcess to {} set targetProcess to FindProcessDataList(myProcessDataList, "WebProcess", targetProcess) set targetProcess to FindProcessDataList(myProcessDataList, "Firefox", targetProcess) if length of targetProcess is not equal to 0 then StopBackgroundCpuControl(targetProcess) set myProcessDataList to {} end if syslog("appnap-browser closed.") continue quit end quit on syslog(logmsg) do shell script "logger -t appnap-browser -i " & logmsg end syslog
終了方法
起動すると
dockにappnap-browserアイコンが存在しています。
appnap-browserアイコンを選択後、
メニューから終了を選んでください。
(appnap-browser -> appnap-browserを終了)
新しいバージョンのスクリプトがあります。
AppNapライクにSafari,Firefoxをコントロール(cputhrottle & applescript)v3.0