Native Restart and Logout Dialogs with PyObjC
Recently I wanted to find a friendly way to prompt for logout or restart using the dialog prompts people were already used to. As part of a workflow users had to restart, but the only solutions I found to programmatically accomplish this were to force something like…
sudo shutdown -r now
That works decently, but can be easily interrupted by a blocking process, is abrupt, and isn’t what people are used to when they restart their Mac. When going to > Restart… everyone’s used to seeing this dialog pop up…
Awesome. He took care of the deep dive API work for me and and I now have working code to generate a logout, restart, or shutdown dialog window on demand. The only problem being it’s written in Python 2. A while back I started shipping relocatable Python 3 interpeter to managed clients to get ready for Python 2 deprecation, and Apple eventually not including it by default with macOS. Running the gist unedited through Python 3.8 with PyObjC installed came back with a lot of errors. After messing around with encoding and a few other functions, I came up with a working Python 3 version. This has been tested with Python 3.8+ and PyObjC 6.1, but should work with most Python 3 versions.
The important bits here are the different AERegistry values.
# Defined in AERegistry.h kAELogOut = OSType("logo") kAEReallyLogOut = OSType("rlgo") kAEShowRestartDialog = OSType("rrst") kAEShowShutdownDialog = OSType("rsdn") # Build a standalone application descriptor by bundle id loginwindowDesc = NSAppleEventDescriptor.alloc().initWithDescriptorType_data_( typeApplicationBundleID, memoryview(b"com.apple.loginwindow") ) # Build an event descriptor with our app descriptor as the target and the kAELogOut eventID event = NSAppleEventDescriptor.appleEventWithEventClass_eventID_targetDescriptor_returnID_transactionID_( typeAppleEvent, kAELogOut, loginwindowDesc, kAutoGenerateReturnID, kAnyTransactionID, )
On line 59 of my gist change the value
kAELogOut to any of the others in that list to get a different dialog and corresponding function. Unsurprisingly,
kAELogOut results in a logout dialog.
kAEShowShutdownDialog are self explanatory. Give them a try to see the usual dialog windows you would see from going to > Shutdown… and similar. Be careful when playing with
kAEReallyLogOut. Apparently “really log out” means log out immediately with no dialog prompt. In a future post I plan to explain how I used the restart dialog to prompt users when their uptime was over a certain number of days.