123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- From 40eb88e3f2b933f19f9933e06c8d0899c54f5e25 Mon Sep 17 00:00:00 2001
- From: mortenmacfly <mortenmacfly@2a5c6006-c6dd-42ca-98ab-0921f2732cef>
- Date: Sat, 4 Jan 2020 15:41:53 +0000
- Subject: [PATCH] * applied patch #805: Flashing icons in Windows' taskbar
- while starting C::B. Thanks Miguel Gimenez.
- git-svn-id: https://svn.code.sf.net/p/codeblocks/code/trunk@11938 2a5c6006-c6dd-42ca-98ab-0921f2732cef
- ---
- src/include/compiler.h | 15 +--
- src/plugins/compilergcc/compilerMINGW.cpp | 13 +--
- src/sdk/compiler.cpp | 106 +++++++++++++++++++---
- 3 files changed, 104 insertions(+), 30 deletions(-)
- diff --git a/src/include/compiler.h b/src/include/compiler.h
- index f151ef62f..8d18c8ffc 100644
- --- a/src/include/compiler.h
- +++ b/src/include/compiler.h
- @@ -100,12 +100,12 @@ struct RegExStruct
- }
- RegExStruct& operator=(const RegExStruct &obj)
- {
- - desc=obj.desc;
- - lt=obj.lt;
- - regex=obj.regex;
- - regexCompiled=false;
- - filename=obj.filename;
- - line=obj.line;
- + desc = obj.desc;
- + lt = obj.lt;
- + regex = obj.regex;
- + regexCompiled = false;
- + filename = obj.filename;
- + line = obj.line;
- memcpy(msg, obj.msg, sizeof(msg));
-
- return *this;
- @@ -404,6 +404,9 @@ class DLLIMPORT Compiler : public CompileOptionsBase
- // keeps a copy of current settings (works only the first time it's called)
- void MirrorCurrentSettings();
-
- + // execute without creating taskbar icon
- + long Execute(const wxString& cmd, wxArrayString& output);
- +
- // set the following members in your class
- wxString m_Name;
- wxString m_MasterPath;
- diff --git a/src/plugins/compilergcc/compilerMINGW.cpp b/src/plugins/compilergcc/compilerMINGW.cpp
- index 1c6cd88a7..5f5509229 100644
- --- a/src/plugins/compilergcc/compilerMINGW.cpp
- +++ b/src/plugins/compilergcc/compilerMINGW.cpp
- @@ -173,7 +173,7 @@ void CompilerMINGW::SetVersionString()
- {
- // Manager::Get()->GetLogManager()->DebugLog(_T("Compiler detection for compiler ID: '") + GetID() + _T("' (parent ID= '") + GetParentID() + _T("')"));
-
- - wxArrayString output, errors;
- + wxArrayString output;
- wxString sep = wxFileName::GetPathSeparator();
- wxString master_path = m_MasterPath;
- wxString compiler_exe = m_Programs.C;
- @@ -223,16 +223,7 @@ void CompilerMINGW::SetVersionString()
-
- // Manager::Get()->GetLogManager()->DebugLog(_T("Compiler version detection: Issuing command: ") + gcc_command);
-
- - int flags = wxEXEC_SYNC;
- -#if wxCHECK_VERSION(3, 0, 0)
- - // Stop event-loop while wxExecute runs, to avoid a deadlock on startup,
- - // that occurs from time to time on wx3
- - flags |= wxEXEC_NOEVENTS;
- -#else
- - flags |= wxEXEC_NODISABLE;
- -#endif
- - long result = wxExecute(gcc_command + _T(" --version"), output, errors, flags );
- - if(result != 0)
- + if ( Execute(gcc_command + _T(" --version"), output) != 0 )
- {
- // Manager::Get()->GetLogManager()->DebugLog(_T("Compiler version detection: Error executing command."));
- }
- diff --git a/src/sdk/compiler.cpp b/src/sdk/compiler.cpp
- index b356de382..c80bbbd61 100644
- --- a/src/sdk/compiler.cpp
- +++ b/src/sdk/compiler.cpp
- @@ -20,7 +20,9 @@
- #include "compilerfactory.h"
-
- #include <wx/intl.h>
- + #include <wx/process.h>
- #include <wx/regex.h>
- + #include <wx/txtstrm.h>
- #endif
-
- #include "compilercommandgenerator.h"
- @@ -28,7 +30,6 @@
- #include <wx/filefn.h>
- #include <wx/xml/xml.h>
-
- -
- // static
- wxArrayString Compiler::m_CompilerIDs; // map to guarantee unique IDs
-
- @@ -1229,18 +1230,7 @@ bool Compiler::EvalXMLCondition(const wxXmlNode* node)
-
- long ret = -1;
- if ( !cmd[0].IsEmpty() ) // should never be empty
- - {
- - int flags = wxEXEC_SYNC;
- - #if wxCHECK_VERSION(3, 0, 0)
- - // Stop event-loop while wxExecute runs, to avoid a deadlock on startup,
- - // that occurs from time to time on wx3
- - flags |= wxEXEC_NOEVENTS;
- - #else
- - flags |= wxEXEC_NODISABLE;
- - #endif
- - wxLogNull logNo; // do not warn if execution fails
- - ret = wxExecute(GetStringFromArray(cmd, wxT(" "), false), cmd, flags);
- - }
- + ret = Execute(GetStringFromArray(cmd, wxT(" "), false), cmd);
-
- if (ret != 0) // execution failed
- val = (node->GetAttribute(wxT("default"), wxEmptyString) == wxT("true"));
- @@ -1284,3 +1274,93 @@ wxString Compiler::GetExecName(const wxString& name)
- ret = m_Programs.MAKE;
- return ret;
- }
- +
- +#ifdef __WXMSW__
- +
- +// In MSW calling wxExecute in synchronous mode while the main window is not visible makes
- +// the system show a C::B icon in the taskbar. When this is made repeatedly (as in compiler
- +// loading) the result is a stream of flashing icons.
- +// However, wxExecute in asynchronous mode does not do this. The caveat is that we must wait
- +// in a loop for the end of the task and extract the command output in a separate step.
- +
- +// This auxiliary class is needed for detecting the end of the task and retrieving the ouput.
- +// OnTerminate() will be called when the task ends with the return code of the task, and then
- +// the task output can be retrieved (as a stream).
- +
- +class ExecProcess : public wxProcess
- +{
- + public:
- + ExecProcess(cb_unused wxEvtHandler *parent = NULL, cb_unused int id = -1)
- + {
- + m_status = 0;
- + }
- +
- + long GetStatus() const {return m_status;}
- + wxSemaphore &GetSemaphore() {return m_semaphore;}
- + void OnTerminate(cb_unused int pid, int status)
- + {
- + m_status = status;
- + m_semaphore.Post();
- + }
- +
- + protected:
- + long m_status;
- + wxSemaphore m_semaphore;
- +};
- +
- +// Emulates wxExecute() in synchronous mode using asynchronous mode
- +
- +long Compiler::Execute(const wxString &cmd, wxArrayString &output)
- +{
- + wxLogNull logNo; // do not warn if execution fails
- +
- + output.Clear();
- +
- + ExecProcess process;
- + process.Redirect(); // capture task input/output streams
- +
- + // wxExecute in asynchronous mode returns 0 if execution failed.
- + // Return -1 emulating the behaviour of wxExecute in synchronous mode
- + if ( !wxExecute(cmd, wxEXEC_ASYNC, &process) )
- + return -1;
- +
- + // Wait for the end of the task
- + for (;;)
- + {
- + Manager::Yield(); // needed for semaphore update
- + if (process.GetSemaphore().WaitTimeout(25) == wxSEMA_NO_ERROR)
- + break;
- + }
- +
- + // Loads the wxArrayString with the task output (returned in a wxInputStream)
- + wxInputStream *inputStream = process.GetInputStream();
- + wxTextInputStream text(*inputStream);
- +#if wxCHECK_VERSION(3, 0, 0)
- + while (!text.GetInputStream().Eof())
- +#else
- + while (!inputStream->Eof())
- +#endif
- + {
- + output.Add(text.ReadLine());
- + }
- +
- + // Return task exit code emulating the behaviour of wxExecute in synchronous mode
- + return process.GetStatus();
- +}
- +
- +#else // __WXMSW__
- +
- +long Compiler::Execute(const wxString &cmd, wxArrayString &output)
- +{
- + wxLogNull logNo; // do not warn if execution fails
- + int flags = wxEXEC_SYNC;
- + #if wxCHECK_VERSION(3, 0, 0)
- + // Stop event-loop while wxExecute runs, to avoid a deadlock on startup,
- + // that occurs from time to time on wx3
- + flags |= wxEXEC_NOEVENTS;
- + #else
- + flags |= wxEXEC_NODISABLE;
- + #endif
- + return wxExecute(cmd, output, flags);
- +}
- +#endif // __WXMSW__
|