diff --git a/common/api/api_plugin_manager.cpp b/common/api/api_plugin_manager.cpp
index e31964b78a..bbbf00418e 100644
--- a/common/api/api_plugin_manager.cpp
+++ b/common/api/api_plugin_manager.cpp
@@ -24,6 +24,7 @@
 #include <fmt/format.h>
 #include <wx/dir.h>
 #include <wx/log.h>
+#include <wx/timer.h>
 #include <wx/utils.h>
 
 #include <api/api_plugin_manager.h>
@@ -43,7 +44,9 @@ wxDEFINE_EVENT( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED, wxCommandEvent );
 
 API_PLUGIN_MANAGER::API_PLUGIN_MANAGER( wxEvtHandler* aEvtHandler ) :
         wxEvtHandler(),
-        m_parent( aEvtHandler )
+        m_parent( aEvtHandler ),
+        m_lastPid( 0 ),
+        m_raiseTimer( nullptr )
 {
     // Read and store pcm schema
     wxFileName schemaFile( PATHS::GetStockDataPath( true ), wxS( "api.v1.schema.json" ) );
@@ -281,7 +284,7 @@ void API_PLUGIN_MANAGER::InvokeAction( const wxString& aIdentifier )
         if( pythonHome )
             env.env[wxS( "VIRTUAL_ENV" )] = *pythonHome;
 
-        manager.Execute( pluginFile.GetFullPath(),
+        long pid = manager.Execute( pluginFile.GetFullPath(),
                 []( int aRetVal, const wxString& aOutput, const wxString& aError )
                 {
                     wxLogTrace( traceApi,
@@ -292,6 +295,36 @@ void API_PLUGIN_MANAGER::InvokeAction( const wxString& aIdentifier )
                 },
                 &env, true );
 
+#ifdef __WXMAC__
+        if( pid )
+        {
+            if( !m_raiseTimer )
+            {
+                m_raiseTimer = new wxTimer( this );
+
+                Bind( wxEVT_TIMER,
+                        [&]( wxTimerEvent& )
+                        {
+                            wxString script = wxString::Format(
+                                wxS( "tell application \"System Events\"\n"
+                                  "  set plist to every process whose unix id is %ld\n"
+                                  "  repeat with proc in plist\n"
+                                  "    set the frontmost of proc to true\n"
+                                  "  end repeat\n"
+                                  "end tell" ), m_lastPid );
+
+                            wxString cmd = wxString::Format( "osascript -e '%s'", script );
+                            wxLogTrace( traceApi, wxString::Format( "Execute: %s", cmd ) );
+                            wxExecute( cmd );
+                        },
+                        m_raiseTimer->GetId() );
+            }
+
+            m_lastPid = pid;
+            m_raiseTimer->StartOnce( 250 );
+        }
+#endif
+
         break;
     }
 
diff --git a/include/api/api_plugin_manager.h b/include/api/api_plugin_manager.h
index 40c6513156..93929a37b7 100644
--- a/include/api/api_plugin_manager.h
+++ b/include/api/api_plugin_manager.h
@@ -28,6 +28,8 @@
 #include <json_schema_validator.h>
 #include <kicommon.h>
 
+class wxTimer;
+
 /// Internal event used for handling async tasks
 wxDECLARE_EVENT( EDA_EVT_PLUGIN_MANAGER_JOB_FINISHED, wxCommandEvent );
 
@@ -101,4 +103,7 @@ private:
     std::deque<JOB> m_jobs;
 
     std::unique_ptr<JSON_SCHEMA_VALIDATOR> m_schema_validator;
+
+    long m_lastPid;
+    wxTimer* m_raiseTimer;
 };
diff --git a/scripting/python_manager.cpp b/scripting/python_manager.cpp
index 37aa83f0b4..467a3995bb 100644
--- a/scripting/python_manager.cpp
+++ b/scripting/python_manager.cpp
@@ -90,7 +90,7 @@ PYTHON_MANAGER::PYTHON_MANAGER( const wxString& aInterpreterPath )
 }
 
 
-void PYTHON_MANAGER::Execute( const wxString& aArgs,
+long PYTHON_MANAGER::Execute( const wxString& aArgs,
         const std::function<void(int, const wxString&, const wxString&)>& aCallback,
         const wxExecuteEnv* aEnv, bool aSaveOutput )
 {
@@ -115,12 +115,9 @@ void PYTHON_MANAGER::Execute( const wxString& aArgs,
             }
         };
 
-#ifdef __WXMAC__
-    wxString cmd = wxString::Format( wxS( "open -a %s --args %s" ), m_interpreterPath, aArgs );
-#else
     wxString cmd = wxString::Format( wxS( "%s %s" ), m_interpreterPath, aArgs );
-#endif
 
+    wxLogTrace( traceApi, wxString::Format( "Execute: %s", cmd ) );
     long pid = wxExecute( cmd, wxEXEC_ASYNC, process, aEnv );
 
     if( pid == 0 )
@@ -144,6 +141,8 @@ void PYTHON_MANAGER::Execute( const wxString& aArgs,
             auto ret = tp.submit( monitor, process );
         }
     }
+
+    return pid;
 }
 
 
diff --git a/scripting/python_manager.h b/scripting/python_manager.h
index 96f5c84d58..ea29275876 100644
--- a/scripting/python_manager.h
+++ b/scripting/python_manager.h
@@ -34,7 +34,15 @@ class KICOMMON_API PYTHON_MANAGER
 public:
     PYTHON_MANAGER( const wxString& aInterpreterPath );
 
-    void Execute( const wxString& aArgs,
+    /**
+     * Launches the Python interpreter with the given arguments
+     * @param aArgs
+     * @param aCallback
+     * @param aEnv
+     * @param aSaveOutput
+     * @return the process ID of the created process, or 0 if one was not created
+     */
+    long Execute( const wxString& aArgs,
                   const std::function<void(int, const wxString&, const wxString&)>& aCallback,
                   const wxExecuteEnv* aEnv = nullptr,
                   bool aSaveOutput = false );