From 83ce01adfb0e01fcaf98289e64bfc6a170c27a27 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Thu, 18 Oct 2018 11:40:10 -0700 Subject: [PATCH 1/6] FIX: move verify framework out of macosx init --- lib/matplotlib/backends/backend_macosx.py | 2 ++ src/_macosx.m | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index b19aa18c267d..66a62b7dd114 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -123,6 +123,8 @@ class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): Wrap everything up into a window for the pylab interface """ def __init__(self, canvas, num): + _macosx.verify_framework() + FigureManagerBase.__init__(self, canvas, num) title = "Figure %d" % num _macosx.FigureManager.__init__(self, canvas, title) diff --git a/src/_macosx.m b/src/_macosx.m index ce791d1f9d21..300714f29a31 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -2619,7 +2619,12 @@ static bool verify_framework(void) METH_VARARGS, "Sets the active cursor." }, - {NULL, NULL, 0, NULL} /* sentinel */ + {"verify_framework", + (PyCFunction)verify_framework, + METH_NOARGS, + "Verifies that the framework build is being used." + }, + {NULL, NULL, 0, NULL, NULL} /* sentinel */ }; static struct PyModuleDef moduledef = { @@ -2644,8 +2649,6 @@ static bool verify_framework(void) || PyType_Ready(&TimerType) < 0) return NULL; - if (!verify_framework()) - return NULL; module = PyModule_Create(&moduledef); if (!module) From 952e6a9643e02a59916effe64e771c2b90229783 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Thu, 18 Oct 2018 11:52:00 -0700 Subject: [PATCH 2/6] FIX: move verify framework out of macosx init --- lib/matplotlib/backends/backend_macosx.py | 13 ++++++++++++- src/_macosx.m | 16 ++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index 66a62b7dd114..af7033f81aee 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -123,7 +123,18 @@ class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): Wrap everything up into a window for the pylab interface """ def __init__(self, canvas, num): - _macosx.verify_framework() + + if not _macosx.verify_framework(): + raise ImportError( + "Python is not installed as a framework. The Mac OS X backend " + "will not be able to function correctly if Python is not " + "installed as a framework. See the Python documentation for more " + "information on installing Python as a framework on Mac OS X. " + "Please either reinstall Python as a framework, or try one of " + "the other backends. If you are using (Ana)Conda please install " + "python.app and replace the use of 'python' with 'pythonw'. See " + "'Working with Matplotlib on OSX' in the Matplotlib FAQ for " + "more information.") FigureManagerBase.__init__(self, canvas, num) title = "Figure %d" % num diff --git a/src/_macosx.m b/src/_macosx.m index 300714f29a31..71699af146b5 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -2575,24 +2575,16 @@ static void context_cleanup(const void* info) Timer_new, /* tp_new */ }; -static bool verify_framework(void) +PyObject* +verify_framework(void) { ProcessSerialNumber psn; /* These methods are deprecated, but they don't require the app to have started */ if (CGMainDisplayID()!=0 && GetCurrentProcess(&psn)==noErr - && SetFrontProcess(&psn)==noErr) return true; - PyErr_SetString(PyExc_ImportError, - "Python is not installed as a framework. The Mac OS X backend will " - "not be able to function correctly if Python is not installed as a " - "framework. See the Python documentation for more information on " - "installing Python as a framework on Mac OS X. Please either reinstall " - "Python as a framework, or try one of the other backends. If you are " - "using (Ana)Conda please install python.app and replace the use of " - "'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the " - "Matplotlib FAQ for more information."); - return false; + && SetFrontProcess(&psn)==noErr) return Py_True; + return Py_False; } static struct PyMethodDef methods[] = { From 41dd8c4b3650e5a3dcf0852b9959a6a4c3c0eb69 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Thu, 18 Oct 2018 14:28:41 -0700 Subject: [PATCH 3/6] FIX: move verify framework out of macosx init --- lib/matplotlib/backends/backend_macosx.py | 1 - lib/matplotlib/pyplot.py | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index af7033f81aee..d3d0916b9a20 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -123,7 +123,6 @@ class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): Wrap everything up into a window for the pylab interface """ def __init__(self, canvas, num): - if not _macosx.verify_framework(): raise ImportError( "Python is not installed as a framework. The Mac OS X backend " diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 6ceced49285c..9e8e408ad035 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -188,7 +188,6 @@ def switch_backend(newbackend): The name of the backend to use. """ close("all") - if newbackend is rcsetup._auto_backend_sentinel: for candidate in ["macosx", "qt5agg", "qt4agg", "gtk3agg", "gtk3cairo", "tkagg", "wxagg", "agg", "cairo"]: From 0b112934fc98b030f4bb918cfa20237798cfc5ee Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Fri, 19 Oct 2018 12:42:19 -0700 Subject: [PATCH 4/6] FIX: move check for framework to pyplot --- lib/matplotlib/backends/backend_macosx.py | 12 ------------ lib/matplotlib/pyplot.py | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index d3d0916b9a20..b19aa18c267d 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -123,18 +123,6 @@ class FigureManagerMac(_macosx.FigureManager, FigureManagerBase): Wrap everything up into a window for the pylab interface """ def __init__(self, canvas, num): - if not _macosx.verify_framework(): - raise ImportError( - "Python is not installed as a framework. The Mac OS X backend " - "will not be able to function correctly if Python is not " - "installed as a framework. See the Python documentation for more " - "information on installing Python as a framework on Mac OS X. " - "Please either reinstall Python as a framework, or try one of " - "the other backends. If you are using (Ana)Conda please install " - "python.app and replace the use of 'python' with 'pythonw'. See " - "'Working with Matplotlib on OSX' in the Matplotlib FAQ for " - "more information.") - FigureManagerBase.__init__(self, canvas, num) title = "Figure %d" % num _macosx.FigureManager.__init__(self, canvas, title) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 9e8e408ad035..204a2a844756 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2348,6 +2348,23 @@ def _autogen_docstring(base): # Set up the backend. switch_backend(rcParams["backend"]) +# We need an extra check here for macosx framework. If we are using MacOSX +# and not using the framework build we throw an ImportError (for back compat). +if dict.__getitem__(rcParams, "backend") == 'MacOSX': + from matplotlib.backends import _macosx + if not _macosx.verify_framework(): + raise ImportError( + "Python is not installed as a framework. The Mac OS X backend " + "will not be able to function correctly if Python is not " + "installed as a framework. See the Python documentation for more " + "information on installing Python as a framework on Mac OS X. " + "Please either reinstall Python as a framework, or try one of " + "the other backends. If you are using (Ana)Conda please install " + "python.app and replace the use of 'python' with 'pythonw'. See " + "'Working with Matplotlib on OSX' in the Matplotlib FAQ for " + "more information.") + + # Just to be safe. Interactive mode can be turned on without # calling `plt.ion()` so register it again here. # This is safe because multiple calls to `install_repl_displayhook` From 5fc7db20086d5740fd6fa3149e0ad31f60e1f3da Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Tue, 23 Oct 2018 11:37:00 -0700 Subject: [PATCH 5/6] FIX: return focus to previous process --- src/_macosx.m | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/_macosx.m b/src/_macosx.m index 71699af146b5..fb5ec04ceb3d 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -2579,11 +2579,17 @@ static void context_cleanup(const void* info) verify_framework(void) { ProcessSerialNumber psn; + ProcessSerialNumber oldpsn; /* These methods are deprecated, but they don't require the app to have started */ + GetFrontProcess(&oldpsn); if (CGMainDisplayID()!=0 && GetCurrentProcess(&psn)==noErr - && SetFrontProcess(&psn)==noErr) return Py_True; + && SetFrontProcess(&psn)==noErr){ + SetFrontProcess(&oldpsn); + return Py_False; + } + SetFrontProcess(&oldpsn); return Py_False; } From 329e6a19275ee7fcd6436c151626b193a3e6a496 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Tue, 23 Oct 2018 11:51:04 -0700 Subject: [PATCH 6/6] FIX: don't rely (as much) on deprecated fcns --- src/_macosx.m | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/_macosx.m b/src/_macosx.m index fb5ec04ceb3d..f3e3a52c34d5 100644 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -2578,17 +2578,32 @@ static void context_cleanup(const void* info) PyObject* verify_framework(void) { - ProcessSerialNumber psn; ProcessSerialNumber oldpsn; + GetFrontProcess(&oldpsn); + +#ifdef COMPILING_FOR_10_6 + NSApp = [NSApplication sharedApplication]; + NSApplicationActivationPolicy activationPolicy = [NSApp activationPolicy]; + switch (activationPolicy) { + case NSApplicationActivationPolicyRegular: + case NSApplicationActivationPolicyAccessory: + { SetFrontProcess(&oldpsn); + return Py_True; + } + case NSApplicationActivationPolicyProhibited: + break; + } +#else + ProcessSerialNumber psn; /* These methods are deprecated, but they don't require the app to have started */ - GetFrontProcess(&oldpsn); if (CGMainDisplayID()!=0 && GetCurrentProcess(&psn)==noErr && SetFrontProcess(&psn)==noErr){ SetFrontProcess(&oldpsn); - return Py_False; + return Py_True; } +#endif SetFrontProcess(&oldpsn); return Py_False; }