Discussion:
Need advice to identify the active pane
(too old to reply)
Fulvio Senore
2009-05-13 09:02:08 UTC
Permalink
I am using wxWidgets 2.8.9.

I am developing an application that shows a main frame divided in two
panes using a splitter window. The left pane shows a tree control, the
right pane shows a list control or some thumbnails. The user can choose
among different views in the two panes, so I have many windows for the
left pane and many for the right pane: only one is visible at any time,
depending on the user's choice.

I think that this is a rather common layout, so I hope that other people
already had my problem.

The frame has a menubar with some entries: some of them may work on what
is selected in both the left and right pane, so I need to know which is
the last pane clicked by the user. If he clicks the right pane, then he
selects the menu I know that I must process the items selected in the
right pane. Same for the left pane.

I was looking for an elegant way to solve this problem, so I tried this
solution:

bool CMainFrame::RightPaneHasFocus() {
wxWindow *wp = GetCorrectWindowInRightPane();
wxWindow *wpFocus = wxWindow::FindFocus();
return (wp == wpFocus);
}

I get a pointer to the window that is currently shown in the right pane,
I get a pointer from wxWindow::FindFocus() and I check if the pointer
are equal.

This works well in Windows, but not in Linux. In Linux it works well if
I use the menubar, but it does not work if I right-click and choose a
contest menu. Strangely the function call works in the UI update event
handler, but in the "command menu selected" handler
wxWindow::FindFocus() returns null from both the left and right pane.

Is there a workaround for this?

Maybe other people already had this problem, so I would be glad to know
how they solved it.

I know that I could use a flag to trace SetFocus and KillFocus events,
but it would be rather complicated (I think). Those events are handled
in the left and right panes while I need to know which pane is selected
in the main frame. Showing a context menu in wxGTK causes a KillFocus
event so I need another flag to ignore the event if I am showing up the
context menu. At the moment I have 3 windows for the left pane and 6 for
the right pane. I hope that there is a better way.

Thanks in advance for your help.

Fulvio Senore
Michael Hieke
2009-05-13 10:23:14 UTC
Permalink
Hi,
Post by Fulvio Senore
Maybe other people already had this problem, so I would be glad to know
how they solved it.
We solved the very same problem for FlameRobin by adding a OnChildFocus
event handler for the top-level frame, and setting a flag there that the
focused child window has changed. In the OnIdle handler there is code
to check which control currently has the focus, and this is put into a
member variable for use in OnUpdateUI handlers. This was necessary,
because in addition to your problem simple FindFocus() calls may not
solve the problem completely, because for example for wxGrid one of the
subwindows can be focused as well.

This does of course rely on the fact that between the KillFocus event
and the showing of the popup menu no idle events are handled, but it has
worked so far for us.

Thanks
--
Michael Hieke
Vadim Zeitlin
2009-05-13 13:18:46 UTC
Permalink
On Wed, 13 May 2009 11:02:08 +0200 Fulvio Senore <***@fsoft.it> wrote:

FS> bool CMainFrame::RightPaneHasFocus() {
FS> wxWindow *wp = GetCorrectWindowInRightPane();
FS> wxWindow *wpFocus = wxWindow::FindFocus();
FS> return (wp == wpFocus);
FS> }
FS>
FS> I get a pointer to the window that is currently shown in the right pane,
FS> I get a pointer from wxWindow::FindFocus() and I check if the pointer
FS> are equal.

Shouldn't you check that wp is an ancestor of wpFocus instead?

FS> This works well in Windows, but not in Linux. In Linux it works well if
FS> I use the menubar, but it does not work if I right-click and choose a
FS> contest menu. Strangely the function call works in the UI update event
FS> handler, but in the "command menu selected" handler
FS> wxWindow::FindFocus() returns null from both the left and right pane.

I think FindFocus() returning NULL when the popup menu is shown is a bug
which should be fixed in wxGTK itself if possible. But in the meanwhile you
should be able to easily work around it by storing the focus pointer
somewhere before calling PopupMenu().

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Fulvio Senore
2009-05-13 21:06:00 UTC
Permalink
Thank you for the information. I did not know about EVT_CHILD_FOCUS, and
it was difficult to find documentation about it. I would never
discover this by myself.

Fulvio
Post by Michael Hieke
Hi,
Post by Fulvio Senore
Maybe other people already had this problem, so I would be glad to know
how they solved it.
We solved the very same problem for FlameRobin by adding a OnChildFocus
event handler for the top-level frame, and setting a flag there that the
focused child window has changed. In the OnIdle handler there is code
to check which control currently has the focus, and this is put into a
member variable for use in OnUpdateUI handlers. This was necessary,
because in addition to your problem simple FindFocus() calls may not
solve the problem completely, because for example for wxGrid one of the
subwindows can be focused as well.
This does of course rely on the fact that between the KillFocus event
and the showing of the popup menu no idle events are handled, but it has
worked so far for us.
Thanks
Fulvio Senore
2009-05-13 21:09:31 UTC
Permalink
Post by Vadim Zeitlin
FS> bool CMainFrame::RightPaneHasFocus() {
FS> wxWindow *wp = GetCorrectWindowInRightPane();
FS> wxWindow *wpFocus = wxWindow::FindFocus();
FS> return (wp == wpFocus);
FS> }
FS>
FS> I get a pointer to the window that is currently shown in the right pane,
FS> I get a pointer from wxWindow::FindFocus() and I check if the pointer
FS> are equal.
Shouldn't you check that wp is an ancestor of wpFocus instead?
Yes, you are right. I was lucky that the controls that I used did not
create children windows.
Post by Vadim Zeitlin
FS> This works well in Windows, but not in Linux. In Linux it works well if
FS> I use the menubar, but it does not work if I right-click and choose a
FS> contest menu. Strangely the function call works in the UI update event
FS> handler, but in the "command menu selected" handler
FS> wxWindow::FindFocus() returns null from both the left and right pane.
I think FindFocus() returning NULL when the popup menu is shown is a bug
which should be fixed in wxGTK itself if possible. But in the meanwhile you
should be able to easily work around it by storing the focus pointer
somewhere before calling PopupMenu().
Yes, thank you for the suggestion.

Fulvio

Continue reading on narkive:
Loading...