9 Replies Latest reply: Feb 4, 2013 6:01 AM by Frank Caggiano
MacMan240 Level 1 Level 1 (80 points)

In a cocoa-application I am making, I would like to create buttons to enable and disable the computer from going to sleep. The following code is not working:

 

on disableSleep_(applescript)

        do shell script "caffeinate &> /dev/null & echo $!"

end disableSleep_

on enableSleep_(applescript)

        do shell script "kill -INT " & thePID

end enableSleep_

 

any suggestions?


MacBook Pro, OS X Mountain Lion (10.8.2), 2.3 GHz i5, 4GB RAM, OCZ 120GB SSD
  • 1. Re: enable/disable screen saver/computer sleep?
    red_menace Level 6 Level 6 (14,615 points)

    You need to describe these things in excruciating detail - what is "not working"?  Since this seemed to be working in earlier topics, I am going to make a guess that it has to do with your handler declaration - since you declared that your handler takes a parameter (applescript), if you are not passing something to put into that parameter you will get an error.  If these handlers are button actions, make sure they are connected to the UI objects (the sender will be passed to the action).

  • 2. Re: enable/disable screen saver/computer sleep?
    MacMan240 Level 1 Level 1 (80 points)

    Sorry, the shell script isnt working, even the plain old apple scripts running in applescript editor.

    do shell script "caffeinate &> /dev/null & echo $!"(correctly attached to a button) disables successfully, but

    do shell script "kill -INT " & thePID (also correctly attached to a button) wont enable sleeping again

  • 3. Re: enable/disable screen saver/computer sleep?
    red_menace Level 6 Level 6 (14,615 points)

    OK, now I remember - when starting the caffeinate utility, it returns the process identifier, which you don't appear to be keeping anywhere.  You should have a property with the rest of your property declarations for the process ID, for example:

     

    property thePID : missing value


    ...then, in your handlers, update the property as needed, for example:

     

    on disableSleep_(sender)

      set thePID to (do shell script "caffeinate &> /dev/null & echo $!")

    end disableSleep_

     

    on enableSleep_(sender)

      if thePID is missing value then return -- no process

      do shell script "kill -INT " & thePID

      set thePID to missing value -- reset for next time

    end enableSleep_


  • 4. Re: enable/disable screen saver/computer sleep?
    MrHoffman Level 6 Level 6 (12,465 points)

    Your text indicates a Cocoa application, but your code looks like AppleScript.

     

    If you are using Objective C and Cocoa here, then see this discussion for some details of using IOKit.   More direct access to the (temporary) settings.

     

    The shell script would usually be a direct call to caffeinate, with whatever command you want to "protect" specified as an argument.   That'll avoid having to pop up a dialog box, or whatever else.  It'll just work.  Or yes, aim the kill at the specified PID.

     

    If you want to disable or enable this stuff somewhat more "permanently", then see the pmset command.  That'll do directly what you seem to be doing here, and without messing around with caffienate.

  • 5. Re: enable/disable screen saver/computer sleep?
    MacMan240 Level 1 Level 1 (80 points)

    not working, do I need to attach thePID to something in the Outlets?

  • 6. Re: enable/disable screen saver/computer sleep?
    red_menace Level 6 Level 6 (14,615 points)

    No, in this case the property is just a global variable.  You might try adding some log statements to your handlers to see what the results are (the log output goes to the debug console), and maybe use the Activity Monitor to see if the process shows up.

  • 7. Re: enable/disable screen saver/computer sleep?
    MacMan240 Level 1 Level 1 (80 points)

    Would it be possible to find the process and kill it this way?(tried that exact code and didnt work)

     

    Screen Shot 2013-02-03 at 8.28.34 PM.png

     

    tell application "System Events"

              set caffeinate to exists process "caffeinate"

    end tell

    if caffeinate then

              tell caffeinate to quit

    else

              display alert "Screen saver is already enabled."

    end if

  • 8. Re: enable/disable screen saver/computer sleep?
    red_menace Level 6 Level 6 (14,615 points)

    It looks like System Events doesn't see the process name, probably because it is running in another shell.

     

    Try removing the options from the kill command - I don't see anything that is needed (not sure if the command is getting mixed up with the built-in), and it works without any options in my test project.  Also, you should add a test to see if the process has been started, otherwise you will get multiple instances:

     

        on disableSleep_(sender)

            if thePID is missing value then -- not started yet

              set thePID to (do shell script "caffeinate &> /dev/null & echo $!")

            end if

        end disableSleep_

       

        on enableSleep_(sender)

            if thePID is missing value then return -- no process

            do shell script "kill " & thePID

            set thePID to missing value -- reset for next time

        end enableSleep_

  • 9. Re: enable/disable screen saver/computer sleep?
    Frank Caggiano Level 7 Level 7 (23,830 points)

    Yes removing the -INT from the kill command as red_menace suggested above will enable the procedure to work  correctly.