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 );