Run function when Mac machine wakes - macos

I'm looking for a function which will get called when a macOS machine wakes up from sleep.
What are some ways to achieve this?
I'm looking to run code in my Swift application when the computer awakens. I'm trying to open a new websocket when this happens. If I open the lid -> new websocket, if I press the any key -> new websocket.
What I've found useful so far is this which stems from what #Rob Napier has suggested (didWakeNotification)

You'll need to give more information than this. Is this an user-level (GUI?) application that will be running when the machine goes to sleep? Is this a daemon? Do you expect your program to be launched if it isn't already running? Is the program sandboxed? Do you expect to have root access? What if no one is logged in? "Wakes up from sleep" has many subtle corner cases (for example, it includes a "dark wake" mode which are not quite sleep and not quite wake).
That said, the high-level answer is "observe NSWorkspace.didWakeNotification" and the low-level answer is "call IORegisterForSystemPower." But whether either of those help you depends a lot on what problem you're solving.

Related

Golang detect if in focus or minimized

How would I go about detecting if my go CLI program is in focus or minimized?
Current program based off https://github.com/jroimartin/gocui
I require the functionality as it is a chat program and I would like to send OS notifications but only when the program is not in focus or is minimized.
Your help/direction is much appreciated as of right now unsure where to start.
This is not possible from the library itself. A command line program does now have a focus, but the terminal program it is running in.
To implement that (if possible at all) would be dependent on os, window manager etc.
To refine the answer provided by #mbuechmann, I suggest the OP not to try to resort to APIs etc.
The reasoning is simple.
"Contemporary" users are used to running programs in terminal emulators which are typically presented as separate windows, and so the users naturally think of these programs as not really different from GUI apps.
But the reality is different: a terminal emulator—whether graphical or not (for instance, so-called "virtual consoles" provided by the Linux kernel running on an x86/amd64 hardware are terminal emulators as well)—really emulates a typical work session on a real hardware terminal, and there, a program would work in foreground solely, and the only means of "switching" to another program was using the shell's job control (those jobs, bg and fg commands).
In other words, the whole concept of a program working in a terminal has an inbuilt assumption that the terminal is always "foreground"—since at the time the concept was developed, a terminal was a physical device.
Now please also consider that "terminal emulation" may be more pervasive on a contemporary system than you might think: screen and tmux on a Unix-like OS are multiplexing terminal emulators—which may themselves be run in a terminal emulator, and a console window on Windows™ may be considered to be a terminal emulator of sorts as well.
So, "resorting to APIs" have several technical problems:
Terminal emulation tries to actually decouple the program which uses this facility from being aware of how the facility is actually provided.
To put it simple, there's, say, no easy way on X Window System, to know what window is used by the terminal emulator running your program.
You'd need to cover diverse set of APIs in order for your program to still be useful: X Window System on Unix-like systems, Mac OS, Windows™. And contemporary GUI stacks running on Linux tend to be switching to Wayland instead of X.
In certain cases, like running a program in a "nested" terminal emulation sessions (for example, a pane in a "window" of a tmux running in xterm), figuring out such facts about the environment might be next to impossible.
And still the crucial problem is that if your program really needs to know whether it's focused or not, it actually wants to be aware about the concepts currently hardly accessible to it. I mean, it wants to be GUI. And if so, just make it GUI.
In fact, it may be simpler than you think. The core of your program might still be a CLI app with a thin GUI wrapper around it which uses any sort of IPC to talk with the app (which might be two-way, if needed).
The simplest is to write some (usually line-wise) data to the program's standard input.

Handling SIGABRT in Mac Apps

I have created a very simple Desktop app for Mac OS. Due to restrictions, I could not use xcode. I am building the .app directory by hand, and the main executable at the moment is a shell script.
When I was trying my app out, I noticed that if I opened and closed it too quickly, the app would freeze up. At which point, I seemed unable to even force quit it, and had to rm -r the .app itself. A friend mentioned to me, that mac apps must handle SIGABRTs, and if they do not, there is a timeout period where the app could appear as frozen, which might explain what I observed.
I was looking around but uncertain where to find more information about this. Can anyone further explain this situation? Under what circumstances will the app receive a SIGABRT, and how should it be handled? Any links or literature on this topic, would be very appreciated.
In case anyone ever stumbles upon this:
So my friend was referring to Unix signals here. https://people.cs.pitt.edu/~alanjawi/cs449/code/shell/UnixSignals.htm
(to see what is available on your OS, give 'kill -l')
My main executable, in my MyApp.app/Contents/MacOS, is a shell script. So what I've found I can do, is use trap command. This will give a behavior to perform, if the executable receives one of the signals. Example - I now add this line near the top of my shell script:
trap 'exit' 5 6
This means that if the executable receives with a SIGABRT (6) or a SIGTRAP (5) signal, it will perform the command 'exit' and will exit. (I am not certain which all signals should be handled and what is the best course, I guess that might depend on your own app, but that was just as an example of something to do)
Here is a resource about trap commands and unix signals: https://www.tutorialspoint.com/unix/unix-signals-traps.htm
Why does this make a difference - I believe previously, there were scenarios where for example if I opened the app while it was already open, it was receiving a Unix signal like a SIGABRT. This signal was not being handled and the app did not know what to do in that scenario, and was freezing up. Though I have not confirmed this is what was happening.

Automatically force quit frozen applications in OSX maybe using a ruby script?

I built an application using openframeworks that is live 24/7 on a kiosk. Every now and then (every few weeks) it will randomly go unresponsive and I still can't get to the bottom of it because it's so random and infrequent it is hard to debug.
I wrote a ruby script that looks for the application running and if it doesn't exist it will start it up. This works in all cases where the application name doesn't show up in activity monitor. Meaning if the app crashes and completely force quits itself or something. It works just fine.
However, if the app just freezes and goes unresponsive (red highlight in activity monitor) the app doesn't quit out completely unless I force quit manually. Is there some kind of script I can write to look for all "unresponsive apps/processes" every few seconds and force quits them automatically? That way my app launcher script will be able to detect that the app isn't running and boot it up again.
I suggest you look at Monit because it's solid, well tested, well documented, and easy to learn.
If you still want to write your own monitoring script, Monit is a good example to follow.
The most reliable way to detect an unresponsive app is to have a "vital sign" which is a generic term for a signal that an app emit to prove it's healthy. Some people call this a "pulse" or "heartbeat" or "brainwave". Your external script watches the vital sign. If your external script sees the vital sign flatline, then the script takes action to cure the app or restart it.
An alternate way is to have a "ping" which is a generic term for your external script sending a signal to the app or the system, then listening for a reply. You can use tools such as the Unix ps command for processes, or AppleScript Activity Monitor. As far as I know, these do a pretty good job of catching common cases, but have trouble catching apps that are soaking up resources, such as being caught in endless loops.

Cocoa program can't be stopped

I'm trying to write an OS X app that uses a serial port. I found an example (cocoa) and got it running in Xcode 4. On the first run, it opens the port and I'm able to exchange data with the hardware.
If I try to change the port the program goes rogue. The pinwheel starts and the UI is unresponsive. I can't stop the program from Xcode, nor can I kill it from Terminal, or Force Quit. Force Quit of Xcode doesn't do it. Although the PID goes away with a kill from Terminal, the UI is still present with the merrily spinning pinwheel.
The only way out is a re-boot. Any ideas on how to track down the errant code are welcome. I'm new to Cocoa/Objective C, so simple terms are better.
Most likely it became a zombie. It should show up in ps auxww (or similar) with a 'Z' in its status. Activity Monitor might also still show it.
This is relatively common when working with hardware, such as a serial port. Zombies can arise for either of two reasons, most likely the first in this case:
The process is blocked in a kernel call of some kind, that's not interruptible.
The process has exited but its parent hasn't acknowledged that (via wait() or similar).
In the first case it's usually a fundamental bug or design flaw of some kind, and you may not have any good options short of figuring out exactly what code path tickles the problem, and avoiding that.
In the second case the solution is generally simple - find the parent process of your zombie and kill it. Repeat as necessary until your zombie gets adopted by a parent process that does call wait() to reap it (launchd will do this if nothing else).

How to Safely Force Shutdown of Mac

What I want
I'm developing a little app to force me to only work at certain times of day - I need something to force me to stop working in the evenings so I can be more effective in the day.
The option within OS X to shut down my machine at a certain time is too easy to cancel. And you can always log back in afterwards.
I want my app to quit all applications whether they have unsaved work or not.
What I've tried
I thought of killing the loginwindow process, but I've read that this can cause data corruption.
I've come across the shutdown command - I'm using sudo shutdown -h +0 to shutdown immediately. This appears to be just the ticket, but I'm worried that it might cause data corruption if, say, Disk Utility is doing some kind of scan.
Is the shutdown command safe?
Can the shutdown command cause corruption? Or is it safe to use? Is there a better way of forcing shutdown safely?
Use AppleScript to tell application "System Events" to shut down.
The shutdown command sends running processes a signal to terminate, giving them a chance to do clean up work, if needed. So generally, when an application receives this signal (SIGTERM(inate)) it should wrap up and exit.
IIRC in Snow Leopard (10.6) Apple added something called fast-shutdown (or similar) which will send processes that have been flagged as being ok with it a SIGKILL signal, shutting them down without chance for cleanup work. This is supposed to make shutdown faster. The default is that applications still get SIGTERM and have to opt-in for SIGKILL; and they can mark themselves as "dirty", i. e. having unsaved work and do not want to be killed forcibly.
So while shutting down in the middle of a disk utility run will abort whatever disk utility is doing, IMHO it would not cause data corruption in general. However depending on the operation you are currently running, you could end up with an incomplete disk image or a half-formatted partition. Maybe you want to refrain from using it when you know the end of your configured work time is coming close.
Using cron to schedule the shutdown is a viable option if you want it to happen at a specified time. If you want it to happen after a certain amount of time after you log in, you could use the number parameter to shutdown to specify say 8 hours from now.
If you want to lose unsaved work then shutdown -h is your only answer.
However, anyone who has debugged a full-screen app on OS X knows that is it very easy (some say too easy) for an app to capture the screen and render the computer essentially useless (without SSHing from another computer to kill the process.) That's another alternative.
the recommended way to schedule a shutdown of your computer on a regular basis is in the system preferences -> Energy Saver panel. Click on the "schedule" button in the lower right hand corner. the rest is self explanatory...
Forcing your computer to shut down (and discard any unsaved work) doesn't sound like a good idea to me. Wouldn't it be easier and safer to just set an alarm clock to remind yourself when you should stop working, and walk away from your computer when it rings? (That's what I do.)
Edit: That might have come across as a bit rude, which was not my intention at all. (I had no intention of making fun of your question or anything like that.) I just think that this would be a better solution to this problem :)
Maybe cron is installed on your computer? It's wonderful =)

Resources