// common part of all ctors
void Init();
+ // set the focus to the child which had it the last time
+ bool SetFocusToChild();
+
// the child which had the focus last time this panel was activated
wxWindow *m_winLastFocused;
// event handlers
// --------------
+
+ void OnSetFocus(wxFocusEvent& event);
void OnEraseBackground(wxEraseEvent& event);
void OnIdle(wxIdleEvent& event);
if ( pLog != NULL && wxLog::IsAllowedTraceMask(mask) ) {
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
+ wxChar *p = s_szBuf;
+ size_t len = WXSIZEOF(s_szBuf);
+ strncpy(s_szBuf, _T("Trace ("), len);
+ len -= 7; // strlen("Trace (")
+ p += 7;
+ strncat(p, mask, len);
+ size_t lenMask = wxStrlen(mask);
+ len -= lenMask;
+ p += lenMask;
+
+ strncat(p, _T("): "), len);
+ len -= 3;
+ p += 3;
+
va_list argptr;
va_start(argptr, szFormat);
- wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
+ wxVsnprintf(p, len, szFormat, argptr);
va_end(argptr);
wxLog::OnLog(wxLOG_Trace, s_szBuf, time(NULL));
void wxPanel::SetFocus()
{
+ wxLogTrace(_T("focus"), _T("SetFocus on wxPanel 0x%08x."), GetHandle());
+
// If the panel gets the focus *by way of getting it set directly*
// we move the focus to the first window that can get it.
- wxNode *node = GetChildren().First();
- while (node)
+ // VZ: no, we set the focus to the last window too. I don't understand why
+ // should we make this distinction: if an app wants to set focus to
+ // some precise control, it may always do it directly, but if we don't
+ // use m_winLastFocused here, the focus won't be set correctly after a
+ // notebook page change nor after frame activation under MSW (it calls
+ // SetFocus too)
+ //
+ // If you still want to have old behaviour for wxGTK, edit the
+ // following line
+#if 0 // def __WXGTK__
+ m_winLastFocused = (wxWindow *)NULL;
+#endif // 0
+
+ if ( !SetFocusToChild() )
{
- wxWindow *child = (wxWindow*) node->Data();
- if (child->AcceptsFocus())
- {
- m_winLastFocused = child; // should be redundant, but it is not
- child->SetFocus();
- return;
- }
- node = node->Next();
+ wxWindow::SetFocus();
}
-
- m_winLastFocused = (wxWindow*) NULL;
-
- wxWindow::SetFocus();
}
void wxPanel::OnFocus(wxFocusEvent& event)
{
+ wxLogTrace(_T("focus"), _T("OnFocus on wxPanel 0x%08x."), GetHandle());
+
// If the panel gets the focus *by way of getting clicked on*
// we move the focus to either the last window that had the
// focus or the first one that can get it.
+ (void)SetFocusToChild();
+
+ event.Skip();
+}
- if (m_winLastFocused)
+bool wxPanel::SetFocusToChild()
+{
+ if ( m_winLastFocused )
{
- // It might happen that the window got reparented or no longer
- // accepts the focus.
- if ((m_winLastFocused->GetParent() == this) &&
- (m_winLastFocused->AcceptsFocus()))
+ // It might happen that the window got reparented or no longer accepts
+ // the focus.
+ if ( (m_winLastFocused->GetParent() == this) &&
+ m_winLastFocused->AcceptsFocus() )
{
+ wxLogTrace(_T("focus"),
+ _T("SetFocusToChild() => last child (0x%08x)."),
+ m_winLastFocused->GetHandle());
+
m_winLastFocused->SetFocus();
- return;
+ return TRUE;
+ }
+ else
+ {
+ // it doesn't count as such any more
+ m_winLastFocused = (wxWindow *)NULL;
}
}
- wxNode *node = GetChildren().First();
- while (node)
+ // set the focus to the first child who wants it
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while ( node )
{
- wxWindow *child = (wxWindow*) node->Data();
- if (child->AcceptsFocus())
+ wxWindow *child = node->GetData();
+ if ( child->AcceptsFocus() )
{
+ wxLogTrace(_T("focus"),
+ _T("SetFocusToChild() => first child (0x%08x)."),
+ child->GetHandle());
+
m_winLastFocused = child; // should be redundant, but it is not
child->SetFocus();
- return;
+ return TRUE;
}
- node = node->Next();
- }
- m_winLastFocused = (wxWindow*) NULL;
+ node = node->GetNext();
+ }
- event.Skip();
+ return FALSE;
}
// subwindow found.
void wxFrame::OnActivate(wxActivateEvent& event)
{
+ if ( !event.GetActive() )
+ {
+ event.Skip();
+
+ return;
+ }
+
+ wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd);
+
for ( wxWindowList::Node *node = GetChildren().GetFirst();
node;
node = node->GetNext() )
)
{
child->SetFocus();
- return;
+ break;
}
}
}
// event tables
// ---------------------------------------------------------------------------
- IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
+IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
EVT_INIT_DIALOG(wxWindow::OnInitDialog)
EVT_IDLE(wxWindow::OnIdle)
+ EVT_SET_FOCUS(wxWindow::OnSetFocus)
END_EVENT_TABLE()
// ===========================================================================
// activation/focus
// ---------------------------------------------------------------------------
+void wxWindow::OnSetFocus(wxFocusEvent& event)
+{
+ // panel wants to track the window which was the last to have focus in it,
+ // so we want to set ourselves as the window which last had focus
+ //
+ // notice that it's also important to do it upwards the tree becaus
+ // otherwise when the top level panel gets focus, it won't set it back to
+ // us, but to some other sibling
+ wxWindow *win = this;
+ while ( win )
+ {
+ wxWindow *parent = win->GetParent();
+ wxPanel *panel = wxDynamicCast(parent, wxPanel);
+ if ( panel )
+ {
+ panel->SetLastFocus(win);
+ }
+
+ win = parent;
+ }
+
+ wxLogTrace(_T("focus"), _T("%s (0x%08x) gets focus"),
+ GetClassInfo()->GetClassName(), GetHandle());
+
+ event.Skip();
+}
+
bool wxWindow::HandleActivate(int state,
bool WXUNUSED(minimized),
WXHWND WXUNUSED(activate))
}
#endif // wxUSE_CARET
- // panel wants to track the window which was the last to have focus in it
- wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
- if ( panel )
- {
- panel->SetLastFocus(this);
- }
-
wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
event.SetEventObject(this);