Opened 12 years ago

Last modified 3 years ago

#3173 confirmed defect

Focus reset to wxTreeCtrl after wxEVT_COMMAND_TREE_ITEM_ACTIVATED handler execution

Reported by: eddonorware Owned by:
Priority: low Milestone:
Component: wxMSW Version: stable-latest
Keywords: Cc: eddonorware, mbabuskov
Blocked By: Blocking:
Patch: no


I've seen this problem in Windows and Mac, not GTK.

In situations where a new window is opened as a result
of a double-click (e.g. EVT_ITEM_ACTIVATED on a tree
control), the new window will open *behind* the old window.

I don't know enough C++ to submit a demo in C++, but
the same behavior exists in both wxPerl and wxPython,
so I assume the problem is in wxwidgets.

I am enclosing a wxpython demo.

Attachments (2) download (948 bytes) - added by eddonorware 12 years ago.
demo of double click -> new window problem
test3173_minimal.diff download (7.2 KB) - added by catalin 5 years ago.

Download all attachments as: .zip

Change History (8)

Changed 12 years ago by eddonorware

demo of double click -> new window problem

comment:1 Changed 12 years ago by mbabuskov

I can confirm the problem.

We worked around it by adding a custom "show-up" event in
queue, so when all event handlers are done, it brings up the
new window.

comment:2 Changed 6 years ago by oneeyeman

This ticket still stands.
Running the attached code on Windows XP with python-2.6, wxPython-2.9.4.
After double clicking the tree the second frame is created but is not activated. Meaning that the first frame has focus (title is blue) while second does not (title is light blue).

comment:3 Changed 6 years ago by vadz

If you could please make a patch reproducing the problem in some C++ sample, it would be useful. TIA!

Changed 5 years ago by catalin

comment:4 Changed 5 years ago by catalin

  • Version set to 2.9-svn

Patch to minimal sample attached.
The test patch uses a wxTreeCtrl for which this always happens.

If a wxButton is used instead, this happens only if the event is skipped in the event handler.
If the double click is on the wxFrame, this never happens (the new frame is always above the double clicked one).

comment:5 Changed 5 years ago by vadz

  • Priority changed from normal to low
  • Status changed from new to confirmed
  • Summary changed from new frame opening beneath old frame on doubleclick to Focus reset to wxTreeCtrl after wxEVT_COMMAND_TREE_ITEM_ACTIVATED handler execution

This is exactly the same problem as I discussed in my recent wxBlog post. It is due to the focus being set back to wxTreeCtrl by the default click handler -- even if we don't skip the activated event. I don't know how can we prevent this from happening so for now I recommend using the workaround proposed in the blog post.

For future reference, here is the patch from the attachment:

  • samples/minimal/minimal.cpp

    a b  
    2929#ifndef WX_PRECOMP
    3030    #include "wx/wx.h"
     32#include "wx/treectrl.h"
    3334// ----------------------------------------------------------------------------
    3435// resources
    class MyFrame : public wxFrame 
    6768    // event handlers (these functions should _not_ be virtual)
    6869    void OnQuit(wxCommandEvent& event);
    6970    void OnAbout(wxCommandEvent& event);
     71    void OnTreeActivate(wxTreeEvent& event);
    7274    // any class wishing to process wxWidgets events must use this macro
    bool MyApp::OnInit() 
    172174    CreateStatusBar(2);
    173175    SetStatusText("Welcome to wxWidgets!");
    174176#endif // wxUSE_STATUSBAR
     178    wxTreeCtrl* tr = new wxTreeCtrl(this);
     179    tr->AddRoot("double click me");
     180    tr->Bind(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, &MyFrame::OnTreeActivate, this);
    178184// event handlers
     186void MyFrame::OnTreeActivate(wxTreeEvent& WXUNUSED(event))
     188    wxFrame* frame2 = new wxFrame(NULL, -1, "Second frame");
     189    frame2->Show();
    180192void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
    182194    // true is to force the frame to close

comment:6 Changed 3 years ago by oneeyeman

Can this ticket be closed with a note that people need to use CallAfter() to prevent this from happening?
Or maybe simply use it in the sample and update the docs?

Note: See TracTickets for help on using tickets.