[wx-dev] #9563: Nasty flickering when wxScrolledWindow and wxPanel
are combined
wxTrac
noreply at wxsite.net
Wed Jun 11 02:09:08 PDT 2008
Ticket URL: <http://trac.wxwidgets.org/ticket/9563>
#9563: Nasty flickering when wxScrolledWindow and wxPanel are combined
---------------------------+------------------------------------------------
Reporter: hajokirchhoff | Owner:
Type: defect | Status: new
Priority: high | Milestone: 2.8.9
Component: GUI-generic | Version: 2.9-svn
Keywords: flicker | Blockedby:
Patch: 1 | Blocking:
---------------------------+------------------------------------------------
Widgets hierarchy is as follows:
wxScrolledWindow
wxPanel
wxTextCtrl
wxComboCtrl
<other widgets>
When one of the children of the wxPanel gets the focus and the
wxScrolledWindow is too small to display the entire panel, the
scrollhelper will first
a) scroll to the bottom of the panel and then
b) will make the child control visible
The effect is that with _every_ focus change event, the entire scrolled
window first scrolls to the bottom right, then scrolls back up to the
correct position. This does not happen, when the child widgets are
immediate children of the wxScrolledWindow. It only happens when the
widgets are children of a wxPanel which in turn is a child of the
wxScrolledWindow.
The problem is that when the focus changes, the wxPanel propagates its
wxFocus event upwards.
containr.cpp:181
// propagate the last focus upwards so that our parent can set focus back
// to us if it loses it now and regains later; do *not* do this if we are
// a toplevel window (e.g. wxDialog) that has another frame as its parent
So what seems to happen is:
A focus event is sent.
wxPanel sees this event and calls
parent->GetEventHandler()->ProcessEvent(eventFocus);
wxScrollHelper intercepts this event and assumes that the wxPanel is about
to get the focus. It scrolls the wxScrolledWindow accordingly. Since the
wxScrolledWindow is too small to show the entire panel, it scrolls to the
bottom/right corner.
Normal event handling continues, the child widget receives the focus and
the wxScrolledWindow::HandleEvent sees this event again. The
wxScrollHelper will act on the event and scroll the actual child window
into view.
To sum it up: The problem seems to be that the event gets duplicated in
containr.cpp, where it is propagated from the wxPanel to the parent
wxScrolledWindow. The effect is that wxScrolledHelper sees the event twice
and one of the events pretends to be a set focus event for the wxPanel.
I don't know how to fix this at the moment and would like to get some
input. My first impulse was to add a
if (wxDynamicCast(win, wxPanel)!=0)
return;
to the wxScrollHelper::HandleOnChildFocus, IOW: ignoring all events where
a wxPanel is the child. wxPanels as a child would never be scrolled
automatically. But that would disable automatic scrolling for widgets
derived from wxPanel as well.
A better approach might be
if (win->AcceptsFocus()==false)
return;
Widgets that do not accept a focus should not be handled by
HandleOnChildFocus. They should normally not even get a focus event, but
in this special wxPanel case they do. So simply return in this case and do
nothing.
--
Ticket URL: <http://trac.wxwidgets.org/ticket/9563>
More information about the wx-dev
mailing list