PyObjC InputMethodKit Framework
PyObjC-framework-InputMethodKit provides Python wrappers for Apple's InputMethodKit framework on macOS, allowing developers to create custom input methods using Python. It is part of the larger PyObjC project, which acts as a bridge between Python and Objective-C. The library is actively maintained with frequent releases, often synchronized with new macOS SDK versions and Python language updates.
Warnings
- breaking PyObjC 12.0 dropped support for Python 3.9. While 12.1 fixed a packaging metadata issue that incorrectly allowed 3.9 installs, Python 3.9 is no longer officially supported. PyObjC 11.0 dropped support for Python 3.8.
- breaking PyObjC 11.1 introduced a significant change in how PyObjC models Automatic Reference Counting (ARC) for initializer methods, aligning with `clang`'s documentation. This means methods in the 'init' family now correctly steal a reference to `self` and return a new reference, which might affect custom object allocation and initialization patterns if not handled correctly.
- gotcha PyObjC 11.0 introduced experimental support for Python 3.13's free-threading (PEP 703), but the PyObjC project explicitly states that it does *not fully support* free-threading at this time. Using PyObjC in a free-threaded Python 3.13 environment might lead to unexpected behavior or crashes.
- gotcha Building PyObjC from source (e.g., for development or specific environments) requires Xcode or the Xcode Command Line Tools to be installed, along with a suitable macOS SDK. Using an older SDK than the one specified by the PyObjC release can lead to build errors.
- gotcha PyObjC framework wrappers, including `pyobjc-framework-inputmethodkit`, do not include direct documentation for the Objective-C APIs. Developers must consult Apple's official documentation for the `InputMethodKit` framework to understand its classes, methods, and protocols.
Install
-
pip install pyobjc-framework-inputmethodkit
Imports
- InputMethodKit
import InputMethodKit
- IMKInputController
from InputMethodKit import IMKInputController
Quickstart
import InputMethodKit
import objc
from Foundation import NSObject, NSLog, NSBundle
# Define a simple input controller, subclassing IMKInputController
class MyInputController(InputMethodKit.IMKInputController):
def init(self):
self = objc.super(MyInputController, self).init()
if self is None:
return None
NSLog("MyInputController initialized!")
return self
def activateServer_(self, sender):
NSLog("Input Method activated!")
return True
def deactivateServer_(self, sender):
NSLog("Input Method deactivated!")
return True
# In a real input method, you'd implement methods like handleEvent_, keyUp_ etc.
def main():
# In a real Input Method, the name and bundleIdentifier are crucial
# and typically defined in the application's Info.plist.
# For this conceptual example, we use placeholders.
input_method_name = "MyPyIM"
# This bundle ID *must* match the bundle ID in your Info.plist
# for a functional Input Method application.
bundle_id = "com.example.MyPyIM"
# Create an IMKServer instance.
# The server manages client connections and dispatches events to input controllers.
server = InputMethodKit.IMKServer.alloc().initWithName_bundleIdentifier_(
input_method_name,
bundle_id
)
NSLog("IMKServer created for name: %@, bundleIdentifier: %@", input_method_name, bundle_id)
NSLog("\n*** IMPORTANT ***\n")
NSLog("To create a functional macOS Input Method, this Python script must be packaged")
NSLog("inside a .app bundle with a correctly configured Info.plist (e.g., using py2app).")
NSLog("This quickstart only demonstrates the basic class instantiation and setup.")
# A real Input Method would then typically run an AppHelper.runEventLoop()
# from PyObjCTools to handle events and keep the application running.
# For simplicity, we omit the blocking event loop here.
if __name__ == '__main__':
main()