Opened 10 years ago

Last modified 7 years ago

#11274 infoneeded_new defect

wxTreeCtrl SelectItem() activate inactive application and grab focus

Reported by: TNikolay Owned by:
Priority: normal Milestone:
Component: wxMSW Version: stable-latest
Keywords: wxTreeCtrl Cc:
Blocked By: Blocking:
Patch: no

Description

Background:
I have application that works in background (no visible window, only tray icon). At some point it captures some data, adds new item to wxTreeCtrl and moves selection to it. It works perfect in 2.8, but I have faced with problem when I tried switching to trunk. Sometimes (not every time) when my app adds item to treectrl and calls m_treeCtrl->SelectItem(item); main window of application is activated, is brought to front and receives input focus (even if the window was hidden).

I have changed minimal sample to reproduce this problem. I have added wxTreeCtrl and timer. When we start the last item in tree is selected, in 5 seconds timer handler switches selection to the first item and we can see the problem.

Steps to reproduce:

  1. Run application - it will be at foreground, last item in tree is selected
  2. Click mouse in any maximized window, for example IDE - it should get focus, bring to front and overlap our app.
  3. In 5 seconds when m_treeCtrl->SelectItem(item); was called - our app would appear at the screen and grab the input focus

I can reproduce this bug only first time when we call SelectItem() in test example, in my app it happens often.

Second (related or the same problem)

When user selects item in tree we receive EVT_TREE_SEL_CHANGING \ EVT_TREE_SEL_CHANGED , but if we try to do this in code using SelectItem() we receive these notifications twice
EVT_TREE_SEL_CHANGING \ EVT_TREE_SEL_CHANGING \ EVT_TREE_SEL_CHANGED \ EVT_TREE_SEL_CHANGED

You can see this using treetest example

  1. Run it and select any items, you will see in the log window

8:32:05: OnSelChanging("Folder child 2")
8:32:05: OnSelChanged("Folder child 2")

  1. Select in menu Tree -> Select Root Item, you will see

8:32:45: OnSelChanging("Root")
8:32:45: OnSelChanging("Root")
8:32:45: OnSelChanged("Root")
8:32:45: OnSelChanged("Root")

wxWidgets trunk, msw, XP SP3

Attachments (1)

minimal.cpp download (7.9 KB) - added by TNikolay 10 years ago.

Download all attachments as: .zip

Change History (6)

Changed 10 years ago by TNikolay

comment:1 Changed 10 years ago by TNikolay

Hello

I have found a source of first problem, but I am not sure that I can fix correct. r49588, see this diff.  It caused the problem.

It seems this is bad idea to force set focus to tree when we change selection programatically.

comment:2 Changed 9 years ago by VZ

(In [65905]) Don't grab focus when calling wxTreeCtrl::SelectItem().

The workaround for the unexpected events order introduced in r49588 should
only apply to the situation when the user selects an item in the tree, not
when it's done programmatically as this results in unexpected focus changes
(see #11274).

comment:3 Changed 9 years ago by VZ

  • Resolution set to fixed
  • Status changed from new to closed

(In [65906]) Avoid duplicate wxEVT_COMMAND_TREE_SEL_CHANG{ING,ED} events in wxMSW.

When changing the selected item programmatically 2 CHANGING and CHANGED events
were sent because the assumption that comctl32.dll didn't send these events
itself was not correct any more, it does send them at least since XP. However
to avoid the tests for its exact version it's simpler to just ignore the
events it generates and continue sending our own ones.

Closes #11274.

comment:4 follow-up: Changed 7 years ago by troelsk

  • Resolution fixed deleted
  • Status changed from closed to reopened

wxTreeCtrl::SelectItem() still calls ::SetFocus(), taking the focus from other controls inside the same app. In wx2.8 SelectItem() did not dabble with focus, maybe just remove the ::SetFocus() call?
As of now, a workaround like this is needed,

        wxWindow* focus = FindFocus(); // wx trunk focus prb in wxTreeCtrl::SelectItem
        SelectItem(idFile);
        if (focus) focus->SetFocus(); // wx trunk focus prb in wxTreeCtrl::SelectItem

comment:5 in reply to: ↑ 4 Changed 7 years ago by vadz

  • Status changed from reopened to infoneeded_new

Replying to troelsk:

wxTreeCtrl::SelectItem() still calls ::SetFocus()

Wait, this is not the same SetFocus(). This is the one from here, not the global function changing the focus. So how can it result in focus change?

More details needed...

Note: See TracTickets for help on using tickets.