40eb88e3f2b933f19f9933e06c8d0899c54f5e25.patch 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. From 40eb88e3f2b933f19f9933e06c8d0899c54f5e25 Mon Sep 17 00:00:00 2001
  2. From: mortenmacfly <mortenmacfly@2a5c6006-c6dd-42ca-98ab-0921f2732cef>
  3. Date: Sat, 4 Jan 2020 15:41:53 +0000
  4. Subject: [PATCH] * applied patch #805: Flashing icons in Windows' taskbar
  5. while starting C::B. Thanks Miguel Gimenez.
  6. git-svn-id: https://svn.code.sf.net/p/codeblocks/code/trunk@11938 2a5c6006-c6dd-42ca-98ab-0921f2732cef
  7. ---
  8. src/include/compiler.h | 15 +--
  9. src/plugins/compilergcc/compilerMINGW.cpp | 13 +--
  10. src/sdk/compiler.cpp | 106 +++++++++++++++++++---
  11. 3 files changed, 104 insertions(+), 30 deletions(-)
  12. diff --git a/src/include/compiler.h b/src/include/compiler.h
  13. index f151ef62f..8d18c8ffc 100644
  14. --- a/src/include/compiler.h
  15. +++ b/src/include/compiler.h
  16. @@ -100,12 +100,12 @@ struct RegExStruct
  17. }
  18. RegExStruct& operator=(const RegExStruct &obj)
  19. {
  20. - desc=obj.desc;
  21. - lt=obj.lt;
  22. - regex=obj.regex;
  23. - regexCompiled=false;
  24. - filename=obj.filename;
  25. - line=obj.line;
  26. + desc = obj.desc;
  27. + lt = obj.lt;
  28. + regex = obj.regex;
  29. + regexCompiled = false;
  30. + filename = obj.filename;
  31. + line = obj.line;
  32. memcpy(msg, obj.msg, sizeof(msg));
  33. return *this;
  34. @@ -404,6 +404,9 @@ class DLLIMPORT Compiler : public CompileOptionsBase
  35. // keeps a copy of current settings (works only the first time it's called)
  36. void MirrorCurrentSettings();
  37. + // execute without creating taskbar icon
  38. + long Execute(const wxString& cmd, wxArrayString& output);
  39. +
  40. // set the following members in your class
  41. wxString m_Name;
  42. wxString m_MasterPath;
  43. diff --git a/src/plugins/compilergcc/compilerMINGW.cpp b/src/plugins/compilergcc/compilerMINGW.cpp
  44. index 1c6cd88a7..5f5509229 100644
  45. --- a/src/plugins/compilergcc/compilerMINGW.cpp
  46. +++ b/src/plugins/compilergcc/compilerMINGW.cpp
  47. @@ -173,7 +173,7 @@ void CompilerMINGW::SetVersionString()
  48. {
  49. // Manager::Get()->GetLogManager()->DebugLog(_T("Compiler detection for compiler ID: '") + GetID() + _T("' (parent ID= '") + GetParentID() + _T("')"));
  50. - wxArrayString output, errors;
  51. + wxArrayString output;
  52. wxString sep = wxFileName::GetPathSeparator();
  53. wxString master_path = m_MasterPath;
  54. wxString compiler_exe = m_Programs.C;
  55. @@ -223,16 +223,7 @@ void CompilerMINGW::SetVersionString()
  56. // Manager::Get()->GetLogManager()->DebugLog(_T("Compiler version detection: Issuing command: ") + gcc_command);
  57. - int flags = wxEXEC_SYNC;
  58. -#if wxCHECK_VERSION(3, 0, 0)
  59. - // Stop event-loop while wxExecute runs, to avoid a deadlock on startup,
  60. - // that occurs from time to time on wx3
  61. - flags |= wxEXEC_NOEVENTS;
  62. -#else
  63. - flags |= wxEXEC_NODISABLE;
  64. -#endif
  65. - long result = wxExecute(gcc_command + _T(" --version"), output, errors, flags );
  66. - if(result != 0)
  67. + if ( Execute(gcc_command + _T(" --version"), output) != 0 )
  68. {
  69. // Manager::Get()->GetLogManager()->DebugLog(_T("Compiler version detection: Error executing command."));
  70. }
  71. diff --git a/src/sdk/compiler.cpp b/src/sdk/compiler.cpp
  72. index b356de382..c80bbbd61 100644
  73. --- a/src/sdk/compiler.cpp
  74. +++ b/src/sdk/compiler.cpp
  75. @@ -20,7 +20,9 @@
  76. #include "compilerfactory.h"
  77. #include <wx/intl.h>
  78. + #include <wx/process.h>
  79. #include <wx/regex.h>
  80. + #include <wx/txtstrm.h>
  81. #endif
  82. #include "compilercommandgenerator.h"
  83. @@ -28,7 +30,6 @@
  84. #include <wx/filefn.h>
  85. #include <wx/xml/xml.h>
  86. -
  87. // static
  88. wxArrayString Compiler::m_CompilerIDs; // map to guarantee unique IDs
  89. @@ -1229,18 +1230,7 @@ bool Compiler::EvalXMLCondition(const wxXmlNode* node)
  90. long ret = -1;
  91. if ( !cmd[0].IsEmpty() ) // should never be empty
  92. - {
  93. - int flags = wxEXEC_SYNC;
  94. - #if wxCHECK_VERSION(3, 0, 0)
  95. - // Stop event-loop while wxExecute runs, to avoid a deadlock on startup,
  96. - // that occurs from time to time on wx3
  97. - flags |= wxEXEC_NOEVENTS;
  98. - #else
  99. - flags |= wxEXEC_NODISABLE;
  100. - #endif
  101. - wxLogNull logNo; // do not warn if execution fails
  102. - ret = wxExecute(GetStringFromArray(cmd, wxT(" "), false), cmd, flags);
  103. - }
  104. + ret = Execute(GetStringFromArray(cmd, wxT(" "), false), cmd);
  105. if (ret != 0) // execution failed
  106. val = (node->GetAttribute(wxT("default"), wxEmptyString) == wxT("true"));
  107. @@ -1284,3 +1274,93 @@ wxString Compiler::GetExecName(const wxString& name)
  108. ret = m_Programs.MAKE;
  109. return ret;
  110. }
  111. +
  112. +#ifdef __WXMSW__
  113. +
  114. +// In MSW calling wxExecute in synchronous mode while the main window is not visible makes
  115. +// the system show a C::B icon in the taskbar. When this is made repeatedly (as in compiler
  116. +// loading) the result is a stream of flashing icons.
  117. +// However, wxExecute in asynchronous mode does not do this. The caveat is that we must wait
  118. +// in a loop for the end of the task and extract the command output in a separate step.
  119. +
  120. +// This auxiliary class is needed for detecting the end of the task and retrieving the ouput.
  121. +// OnTerminate() will be called when the task ends with the return code of the task, and then
  122. +// the task output can be retrieved (as a stream).
  123. +
  124. +class ExecProcess : public wxProcess
  125. +{
  126. + public:
  127. + ExecProcess(cb_unused wxEvtHandler *parent = NULL, cb_unused int id = -1)
  128. + {
  129. + m_status = 0;
  130. + }
  131. +
  132. + long GetStatus() const {return m_status;}
  133. + wxSemaphore &GetSemaphore() {return m_semaphore;}
  134. + void OnTerminate(cb_unused int pid, int status)
  135. + {
  136. + m_status = status;
  137. + m_semaphore.Post();
  138. + }
  139. +
  140. + protected:
  141. + long m_status;
  142. + wxSemaphore m_semaphore;
  143. +};
  144. +
  145. +// Emulates wxExecute() in synchronous mode using asynchronous mode
  146. +
  147. +long Compiler::Execute(const wxString &cmd, wxArrayString &output)
  148. +{
  149. + wxLogNull logNo; // do not warn if execution fails
  150. +
  151. + output.Clear();
  152. +
  153. + ExecProcess process;
  154. + process.Redirect(); // capture task input/output streams
  155. +
  156. + // wxExecute in asynchronous mode returns 0 if execution failed.
  157. + // Return -1 emulating the behaviour of wxExecute in synchronous mode
  158. + if ( !wxExecute(cmd, wxEXEC_ASYNC, &process) )
  159. + return -1;
  160. +
  161. + // Wait for the end of the task
  162. + for (;;)
  163. + {
  164. + Manager::Yield(); // needed for semaphore update
  165. + if (process.GetSemaphore().WaitTimeout(25) == wxSEMA_NO_ERROR)
  166. + break;
  167. + }
  168. +
  169. + // Loads the wxArrayString with the task output (returned in a wxInputStream)
  170. + wxInputStream *inputStream = process.GetInputStream();
  171. + wxTextInputStream text(*inputStream);
  172. +#if wxCHECK_VERSION(3, 0, 0)
  173. + while (!text.GetInputStream().Eof())
  174. +#else
  175. + while (!inputStream->Eof())
  176. +#endif
  177. + {
  178. + output.Add(text.ReadLine());
  179. + }
  180. +
  181. + // Return task exit code emulating the behaviour of wxExecute in synchronous mode
  182. + return process.GetStatus();
  183. +}
  184. +
  185. +#else // __WXMSW__
  186. +
  187. +long Compiler::Execute(const wxString &cmd, wxArrayString &output)
  188. +{
  189. + wxLogNull logNo; // do not warn if execution fails
  190. + int flags = wxEXEC_SYNC;
  191. + #if wxCHECK_VERSION(3, 0, 0)
  192. + // Stop event-loop while wxExecute runs, to avoid a deadlock on startup,
  193. + // that occurs from time to time on wx3
  194. + flags |= wxEXEC_NOEVENTS;
  195. + #else
  196. + flags |= wxEXEC_NODISABLE;
  197. + #endif
  198. + return wxExecute(cmd, output, flags);
  199. +}
  200. +#endif // __WXMSW__