Skip to content

Instantly share code, notes, and snippets.

@nstrauss
Forked from pudquick/loginwindow_events.py
Last active December 15, 2020 22:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nstrauss/0d64cc39829a87935360c4b736b32d07 to your computer and use it in GitHub Desktop.
Save nstrauss/0d64cc39829a87935360c4b736b32d07 to your computer and use it in GitHub Desktop.
Send polite Logout / "really" Logout / Restart / Shutdown Apple Events to loginwindow via python and pyObjC - Python 3
#!/usr/bin/python3
# Stolen entirely from Michael Lynn
# https://gist.github.com/pudquick/9683c333e73a82379b8e377eb2e6fc41
# Edited for Python 3
import struct
import objc
from Cocoa import NSAppleEventDescriptor
from Foundation import NSBundle
def OSType(s):
# Convert 4 character code into 4 byte integer
return struct.unpack(">I", s.encode())[0]
# Create an opaque pointer type to mask the raw AEDesc pointers we'll throw around
AEDescRef = objc.createOpaquePointerType(
"AEDescRef", b"^{AEDesc=I^^{OpaqueAEDataStorageType}}"
)
# Load AESendMessage from AE.framework for sending the AppleEvent
AE_bundle = NSBundle.bundleWithIdentifier_("com.apple.AE")
functions = [
(
"AESendMessage",
b"i^{AEDesc=I^^{OpaqueAEDataStorageType}}^{AEDesc=I^^{OpaqueAEDataStorageType}}iq",
),
]
objc.loadBundleFunctions(AE_bundle, globals(), functions)
# Defined in AEDataModel.h
kAENoReply = 1
kAENeverInteract = 16
kAEDefaultTimeout = -1
kAnyTransactionID = 0
kAutoGenerateReturnID = -1
# Defined in AEDataModel.h
typeAppleEvent = OSType("aevt")
typeApplicationBundleID = OSType("bund")
# 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,
)
eventDesc = event.aeDesc()
# Send a polite logout (returns immediately)
logout = AESendMessage( # noqa: F821
eventDesc, None, kAENoReply | kAENeverInteract, kAEDefaultTimeout
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment