MGR: work around a Linux bug in wxWidgets which prevents bringing the main window forward on top of Event Log (or any modeless dialog.)

- On all platforms, preserve Z-order of main window and Event Log when hiding / showing or deactivating / activating Manager.
This commit is contained in:
Charlie Fenton 2015-01-16 03:22:10 -08:00
parent bae5869e43
commit e6607a6340
6 changed files with 76 additions and 33 deletions

View File

@ -56,6 +56,7 @@ BEGIN_EVENT_TABLE (CBOINCBaseFrame, wxFrame)
EVT_FRAME_INITIALIZED(CBOINCBaseFrame::OnInitialized)
EVT_FRAME_ALERT(CBOINCBaseFrame::OnAlert)
EVT_FRAME_REFRESH(CBOINCBaseFrame::OnRefreshView)
EVT_ACTIVATE(CBOINCBaseFrame::OnActivate)
EVT_CLOSE(CBOINCBaseFrame::OnClose)
EVT_MENU(ID_CLOSEWINDOW, CBOINCBaseFrame::OnCloseWindow)
EVT_MENU(wxID_EXIT, CBOINCBaseFrame::OnExit)
@ -314,6 +315,13 @@ void CBOINCBaseFrame::OnAlert(CFrameAlertEvent& event) {
}
void CBOINCBaseFrame::OnActivate(wxActivateEvent& event) {
bool isActive = event.GetActive();
if (isActive) wxGetApp().SetEventLogWasActive(false);
event.Skip();
}
void CBOINCBaseFrame::OnClose(wxCloseEvent& event) {
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::OnClose - Function Begin"));
@ -888,7 +896,6 @@ bool CBOINCBaseFrame::Show(bool bShow) {
#else
retval = wxFrame::Show(bShow);
#endif
if (bShow) wxFrame::Raise();
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseFrame::Show - Function End"));
return retval;

View File

@ -59,6 +59,7 @@ public:
void OnInitialized( CFrameEvent& event );
virtual void OnAlert( CFrameAlertEvent& event );
virtual void OnActivate( wxActivateEvent& event );
virtual void OnClose( wxCloseEvent& event );
virtual void OnCloseWindow( wxCommandEvent& event );
virtual void OnExit( wxCommandEvent& event );

View File

@ -370,6 +370,8 @@ bool CBOINCGUIApp::OnInit() {
m_pDocument = NULL;
m_pTaskBarIcon = NULL;
m_pEventLog = NULL;
m_bEventLogWasActive = false;
m_bProcessingActivateAppEvent = false;
#ifdef __WXMAC__
m_pMacDockIcon = NULL;
#endif
@ -1191,26 +1193,28 @@ int CBOINCGUIApp::IdleTrackerDetach() {
void CBOINCGUIApp::OnActivateApp(wxActivateEvent& event) {
#ifdef __WXMAC__
// Make sure any modal dialog (such as Attach Wizard) ends up in front.
if (IsModalDialogDisplayed()) {
event.Skip();
return;
}
#endif
m_bProcessingActivateAppEvent = true;
if (event.GetActive()) {
if (m_pEventLog && !m_pEventLog->IsIconized()) {
#ifdef __WXMAC__
ShowInterface();
#else
bool keepEventLogInFront = m_bEventLogWasActive;
if (m_pEventLog && !m_pEventLog->IsIconized() && !keepEventLogInFront) {
m_pEventLog->Raise();
}
if (m_pFrame) {
m_pFrame->Raise();
}
#ifdef __WXMAC__
ShowInterface();
if (m_pEventLog && !m_pEventLog->IsIconized() && keepEventLogInFront) {
m_pEventLog->Raise();
}
#endif
}
event.Skip();
m_bProcessingActivateAppEvent = false;
}
@ -1263,8 +1267,11 @@ int CBOINCGUIApp::StartBOINCDefaultScreensaverTest() {
}
// Display the Event Log, it is a modeless dialog not owned by any
// other UI element.
// Display the Event Log, it is a modeless dialog not owned by
// any other UI element.
// To work around a Linux bug in wxWidgets 3.0 which prevents
// bringing the main frame forward on top of a modeless dialog,
// the Event Log is now a wxFrame on Linux only.
void CBOINCGUIApp::DisplayEventLog(bool bShowWindow) {
if (m_pEventLog) {
if (bShowWindow) {
@ -1422,26 +1429,28 @@ bool CBOINCGUIApp::SetActiveGUI(int iGUISelection, bool bShowWindow) {
}
// Show the new frame if needed
if (m_pFrame && bShowWindow) {
if (m_pEventLog) {
m_pEventLog->Show();
m_pEventLog->Raise();
#ifdef __WXMSW__
::SetForegroundWindow((HWND)m_pEventLog->GetHWND());
#endif
}
if (!m_bProcessingActivateAppEvent) {
if (m_pFrame && bShowWindow) {
if (m_pEventLog && !m_pEventLog->IsIconized()) {
m_pEventLog->Show();
m_pEventLog->Raise();
#ifdef __WXMSW__
::SetForegroundWindow((HWND)m_pEventLog->GetHWND());
#endif
}
if (!m_pFrame->IsShown()) {
m_pFrame->Show();
}
if (m_pFrame->IsIconized()) {
m_pFrame->Maximize(false);
}
m_pFrame->Raise();
if (!m_pFrame->IsShown()) {
m_pFrame->Show();
}
if (m_pFrame->IsIconized()) {
m_pFrame->Maximize(false);
}
m_pFrame->Raise();
#ifdef __WXMSW__
::SetForegroundWindow((HWND)m_pFrame->GetHWND());
::SetForegroundWindow((HWND)m_pFrame->GetHWND());
#endif
}
}
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCGUIApp::SetActiveGUI - Function End"));

View File

@ -79,6 +79,8 @@ protected:
CMainDocument* m_pDocument;
CTaskBarIcon* m_pTaskBarIcon;
CDlgEventLog* m_pEventLog;
bool m_bEventLogWasActive;
bool m_bProcessingActivateAppEvent;
#ifdef __WXMAC__
CTaskBarIcon* m_pMacDockIcon;
#endif
@ -161,6 +163,7 @@ public:
void SetISOLanguageCode(wxString strISOLanguageCode)
{ m_strISOLanguageCode = strISOLanguageCode; }
void SetEventLogWasActive(bool wasActive) { m_bEventLogWasActive = wasActive; }
void DisplayEventLog(bool bShowWindow = true);
void OnEventLogClose();

View File

@ -66,14 +66,15 @@ static std::string s_strFilteredProjectName;
* CDlgEventLog type definition
*/
IMPLEMENT_DYNAMIC_CLASS( CDlgEventLog, wxDialog )
IMPLEMENT_DYNAMIC_CLASS( CDlgEventLog, DlgEventLogBase )
/*!
* CDlgEventLog event table definition
*/
BEGIN_EVENT_TABLE( CDlgEventLog, wxDialog )
BEGIN_EVENT_TABLE( CDlgEventLog, DlgEventLogBase )
////@begin CDlgEventLog event table entries
EVT_ACTIVATE(CDlgEventLog::OnActivate)
EVT_HELP(wxID_ANY, CDlgEventLog::OnHelp)
EVT_BUTTON(wxID_OK, CDlgEventLog::OnOK)
EVT_BUTTON(ID_COPYAll, CDlgEventLog::OnMessagesCopyAll)
@ -215,7 +216,7 @@ bool CDlgEventLog::Create( wxWindow* parent, wxWindowID id, const wxString& capt
oTempSize = size;
}
wxDialog::Create( parent, id, caption, oTempPoint, oTempSize, style );
DlgEventLogBase::Create( parent, id, caption, oTempPoint, oTempSize, style );
SetSizeHints(DLGEVENTLOG_MIN_WIDTH, DLGEVENTLOG_MIN_HEIGHT);
SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
@ -394,6 +395,16 @@ void CDlgEventLog::SetTextColor() {
}
/*!
* wxEVT_ACTIVATE event handler for ID_DLGMESSAGES
*/
void CDlgEventLog::OnActivate(wxActivateEvent& event) {
bool isActive = event.GetActive();
if (isActive) wxGetApp().SetEventLogWasActive(true);
event.Skip();
}
/*!
* wxEVT_HELP event handler for ID_DLGMESSAGES
*/

View File

@ -74,7 +74,16 @@ class CDlgEventLogListCtrl;
#define wxFIXED_MINSIZE 0
#endif
class CDlgEventLog : public wxDialog
// To work around a Linux bug in wxWidgets 3.0 which prevents
// bringing the main frame forward on top of a modeless dialog,
// the Event Log is now a wxFrame on Linux only.
#ifdef __WXGTK__
#define DlgEventLogBase wxFrame
#else
#define DlgEventLogBase wxDialog
#endif
class CDlgEventLog : public DlgEventLogBase
{
DECLARE_DYNAMIC_CLASS( CDlgEventLog )
DECLARE_EVENT_TABLE()
@ -100,6 +109,9 @@ public:
/// wxEVT_HELP event handler for ID_DLGEVENTLOG
void OnHelp( wxHelpEvent& event );
/// wxEVT_Activate event handler for ID_DLGEVENTLOG
void OnActivate( wxActivateEvent& event );
/// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
void OnOK( wxCommandEvent& event );