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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy