/
OSXAWTwrapper.py
105 lines (83 loc) · 3.7 KB
/
OSXAWTwrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""
This script is a wrapper to allow Java code that uses AWT to run properly on
macOS. It starts the Cocoa event loop before Java and keeps Cocoa happy.
See https://github.com/kivy/pyjnius/issues/151 for more.
In particular, this wrapper allows one to run the code from imglyb-examples.
usage: python OSXAWTwrapper.py [module name | script path] [module or script parameters]
NB: Since the creation of this script, the imglyb project switched from pyjnius
to jpype, and this script is not really necessary anymore. You can instead use
jpype.setupGuiEnvironment(...), passing a function that does Java AWT things,
and it will be executed on the correct thread.
"""
import os
import sys
usage = "usage: python OSXAWTwrapper.py [module name | script path] [module or script parameters]"
def runAwtStuff():
import runpy
# user can provide either a module or a path to a script;
# either way, need to remove it from sys.argv,
# because the wrapped module or script might parse sys.argv for its own reasons:
if len(sys.argv) > 1:
name = sys.argv[1]
sys.argv.remove(name)
# whether module or script, need to set the run_name for things to work as expected!
try:
if os.path.exists(name):
runpy.run_path(name, run_name="__main__")
else:
runpy.run_module(name, run_name="__main__")
except Exception as e:
print("exception occurred while running {}: {}".format(name, e))
## lots can go wrong here, and exceptions can bubble up from
# the Java layer, too; uncomment lines below to print
# more information on exception
# note: different exceptions have different attributes, so you
# might need to adjust the lines below; use dir(e) to see
# what you have available when you are debugging
# print("exception details: ")
# print("e.args: ", e.args)
# print("e.__class__: ", e.__class__)
# print("e.stacktrace: ")
# for line in e.stacktrace:
# print("\t", line)
## if Java throws a reflection error, you might want this:
## print("e.innermessage", e.innermessage)
else:
print(usage)
print("no module or script specified")
def main():
try:
import objc
from PyObjCTools import AppHelper
from AppKit import (
NSApplication,
NSApp,
NSObject,
NSApplicationActivationPolicyRegular,
)
# from Foundation import *
class AppDelegate(NSObject):
def init(self):
self = objc.super(AppDelegate, self).init()
if self is None:
return None
return self
def runjava_(self, arg):
runAwtStuff()
# we need to terminate explicitly, or it'll hang when
# the wrapped code exits
NSApp().terminate_(self)
def applicationDidFinishLaunching_(self, aNotification):
self.performSelectorInBackground_withObject_("runjava:", 0)
app = NSApplication.sharedApplication()
delegate = AppDelegate.alloc().init()
NSApp().setDelegate_(delegate)
# this is necessary to have keyboard events sent to the UI;
# basically this call makes the script act like an OS X application,
# with Dock icon and everything
NSApp.setActivationPolicy_(NSApplicationActivationPolicyRegular)
AppHelper.runEventLoop()
except ModuleNotFoundError:
print("Skipping OSXAWTwrapper - module 'objc' is not installed")
if __name__ == "__main__":
main()