Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eb39be5

Browse files
committed
Lazy-init the OSX event loop.
1 parent 77ba47c commit eb39be5

File tree

2 files changed

+41
-28
lines changed

2 files changed

+41
-28
lines changed

lib/matplotlib/backends/__init__.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ def _get_running_interactive_framework():
5656
except ImportError:
5757
pass
5858
else:
59-
# Note that the NSApp event loop is also running when a non-native
60-
# toolkit (e.g. Qt5) is active, but in that case we want to report the
61-
# other toolkit; thus, this check comes after the other toolkits.
6259
if _macosx.event_loop_is_running():
6360
return "macosx"
6461
if sys.platform.startswith("linux") and not os.environ.get("DISPLAY"):

src/_macosx.m

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,39 @@ - (int)index;
267267

268268
/* ---------------------------- Python classes ---------------------------- */
269269

270+
static bool backend_inited = false;
271+
272+
static void lazy_init(void) {
273+
if (backend_inited) {
274+
return;
275+
}
276+
backend_inited = true;
277+
278+
NSApp = [NSApplication sharedApplication];
279+
280+
PyOS_InputHook = wait_for_stdin;
281+
282+
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
283+
WindowServerConnectionManager* connectionManager = [WindowServerConnectionManager sharedManager];
284+
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
285+
NSNotificationCenter* notificationCenter = [workspace notificationCenter];
286+
[notificationCenter addObserver: connectionManager
287+
selector: @selector(launch:)
288+
name: NSWorkspaceDidLaunchApplicationNotification
289+
object: nil];
290+
[pool release];
291+
}
292+
293+
static PyObject*
294+
event_loop_is_running(PyObject* self)
295+
{
296+
if (backend_inited) {
297+
Py_RETURN_TRUE;
298+
} else {
299+
Py_RETURN_FALSE;
300+
}
301+
}
302+
270303
static CGFloat _get_device_scale(CGContextRef cr)
271304
{
272305
CGSize pixelSize = CGContextConvertSizeToDeviceSpace(cr, CGSizeMake(1, 1));
@@ -281,6 +314,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
281314
static PyObject*
282315
FigureCanvas_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
283316
{
317+
lazy_init();
284318
FigureCanvas *self = (FigureCanvas*)type->tp_alloc(type, 0);
285319
if (!self) return NULL;
286320
self->view = [View alloc];
@@ -641,6 +675,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
641675
static PyObject*
642676
FigureManager_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
643677
{
678+
lazy_init();
644679
Window* window = [Window alloc];
645680
if (!window) return NULL;
646681
FigureManager *self = (FigureManager*)type->tp_alloc(type, 0);
@@ -1016,6 +1051,7 @@ -(void)save_figure:(id)sender
10161051
static PyObject*
10171052
NavigationToolbar_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
10181053
{
1054+
lazy_init();
10191055
NavigationToolbarHandler* handler = [NavigationToolbarHandler alloc];
10201056
if (!handler) return NULL;
10211057
NavigationToolbar *self = (NavigationToolbar*)type->tp_alloc(type, 0);
@@ -1555,6 +1591,7 @@ -(void)save_figure:(id)sender
15551591
static PyObject*
15561592
NavigationToolbar2_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
15571593
{
1594+
lazy_init();
15581595
NavigationToolbar2Handler* handler = [NavigationToolbar2Handler alloc];
15591596
if (!handler) return NULL;
15601597
NavigationToolbar2 *self = (NavigationToolbar2*)type->tp_alloc(type, 0);
@@ -2789,16 +2826,6 @@ - (int)index
27892826
}
27902827
@end
27912828

2792-
static PyObject*
2793-
event_loop_is_running(PyObject* self)
2794-
{
2795-
if ([NSApp isRunning]) {
2796-
Py_RETURN_TRUE;
2797-
} else {
2798-
Py_RETURN_FALSE;
2799-
}
2800-
}
2801-
28022829
static PyObject*
28032830
show(PyObject* self)
28042831
{
@@ -2825,6 +2852,7 @@ - (int)index
28252852
static PyObject*
28262853
Timer_new(PyTypeObject* type, PyObject *args, PyObject *kwds)
28272854
{
2855+
lazy_init();
28282856
Timer* self = (Timer*)type->tp_alloc(type, 0);
28292857
if (!self) return NULL;
28302858
self->timer = NULL;
@@ -3051,7 +3079,7 @@ static bool verify_framework(void)
30513079
{"event_loop_is_running",
30523080
(PyCFunction)event_loop_is_running,
30533081
METH_NOARGS,
3054-
"Return whether the NSApp main event loop is currently running."
3082+
"Return whether the OSX backend has set up the NSApp main event loop."
30553083
},
30563084
{"show",
30573085
(PyCFunction)show,
@@ -3097,13 +3125,12 @@ static bool verify_framework(void)
30973125
|| PyType_Ready(&TimerType) < 0)
30983126
return NULL;
30993127

3100-
NSApp = [NSApplication sharedApplication];
3101-
31023128
if (!verify_framework())
31033129
return NULL;
31043130

31053131
module = PyModule_Create(&moduledef);
3106-
if (module==NULL) return NULL;
3132+
if (!module)
3133+
return NULL;
31073134

31083135
Py_INCREF(&FigureCanvasType);
31093136
Py_INCREF(&FigureManagerType);
@@ -3116,16 +3143,5 @@ static bool verify_framework(void)
31163143
PyModule_AddObject(module, "NavigationToolbar2", (PyObject*) &NavigationToolbar2Type);
31173144
PyModule_AddObject(module, "Timer", (PyObject*) &TimerType);
31183145

3119-
PyOS_InputHook = wait_for_stdin;
3120-
3121-
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
3122-
WindowServerConnectionManager* connectionManager = [WindowServerConnectionManager sharedManager];
3123-
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
3124-
NSNotificationCenter* notificationCenter = [workspace notificationCenter];
3125-
[notificationCenter addObserver: connectionManager
3126-
selector: @selector(launch:)
3127-
name: NSWorkspaceDidLaunchApplicationNotification
3128-
object: nil];
3129-
[pool release];
31303146
return module;
31313147
}

0 commit comments

Comments
 (0)