]> git.saurik.com Git - wxWidgets.git/commitdiff
I think I finally fixed activation behaviour under MSW - now focus is not given
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 22 Jan 2000 01:44:16 +0000 (01:44 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 22 Jan 2000 01:44:16 +0000 (01:44 +0000)
to random window after you switch to/from a frame

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5582 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/panelg.h
include/wx/msw/window.h
src/common/log.cpp
src/generic/panelg.cpp
src/msw/frame.cpp
src/msw/window.cpp

index 308be49ecb7aa642e2d7da0dc6bce921b9ee38b8..de9db536e2401932db52527f2a5d0339b8306ebe 100644 (file)
@@ -92,6 +92,9 @@ protected:
     // 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;
 
index e0181bd29b22d4e85e5e7e7d8643845633d7327f..fd873efbde0dd5a8fd69e84925db3513e5587174 100644 (file)
@@ -179,6 +179,8 @@ public:
 
     // event handlers
     // --------------
+
+    void OnSetFocus(wxFocusEvent& event);
     void OnEraseBackground(wxEraseEvent& event);
     void OnIdle(wxIdleEvent& event);
 
index 129b25305474894316e6ec4d15d5c0da8921f609..2179500499d5863daf550fa0c51e2f7e70da7313 100644 (file)
@@ -178,9 +178,23 @@ void wxLogVerbose(const wxChar *szFormat, ...)
     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));
index e2b2c838e70b070074c8dd8546988694d48bdc1a..3ff8c2dbc0d02d347cf24aec669fd37c863683e5 100644 (file)
@@ -186,59 +186,83 @@ void wxPanel::OnSize(wxSizeEvent& WXUNUSED(event))
 
 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;
 }
index 704d53784a7df6bcc20203d20401757fb419fd86..1b2f3db2e9bde5d9046ab42e18b87a8d4c059083 100644 (file)
@@ -559,6 +559,15 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow
 // 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() )
@@ -579,7 +588,7 @@ void wxFrame::OnActivate(wxActivateEvent& event)
            )
         {
             child->SetFocus();
-            return;
+            break;
         }
     }
 }
index ec39a8be1d37c814c329040582eff6ac716d9178..44c98ddf78fea5cb7fdfb1ee4020115e6d55899f 100644 (file)
@@ -141,13 +141,14 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 // 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()
 
 // ===========================================================================
@@ -2519,6 +2520,33 @@ bool wxWindow::HandleDestroy()
 // 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))
@@ -2541,13 +2569,6 @@ bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd))
     }
 #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);