Page 1 of 1

wxNotebook wrong focus when hide.

Posted: Thu Sep 22, 2005 5:52 am
by Vaulter
is it right to set focus when window with wxNotebook is hidden?

Code: Select all

MyFrame::MyFrame()
{
wxNotebook* sometabs = new wxNotebook();
}
//...
this->Show(false);//hide form
//...
sometabs->AddPage(/*...*/);//addpage. what going on:
wxNotebook::AddPage() -> wxNotebook::InsertPage() ->
wxNotebook::SetSelection(selNew) -> (invoke by event) ->
wxNotebook::OnSelChange(wxNotebookEvent& event)

Code: Select all

void wxNotebook::OnSelChange(wxNotebookEvent& event)
{
  // is it our tab control?
  if ( event.GetEventObject() == this )
  {
      int sel = event.GetOldSelection();
      if ( sel != -1 )
        m_pages[sel]->Show(false);

      sel = event.GetSelection();
      if ( sel != -1 )
      {
        wxNotebookPage *pPage = m_pages[sel];
        pPage->Show(true);
        
        // As per bug report:
        // http://sourceforge.net/tracker/index.php?func=detail&aid=1150659&group_id=9863&atid=109863,
        // we should not set the page focus (and thereby the focus for
        // a child window) since it erroneously selects radio button controls and also
        // breaks keyboard handling for a notebook's scroll buttons. So
        // we always focus the notebook and not the page.
        SetFocus();

      }
      else // no pages in the notebook, give the focus to itself
      {
          SetFocus();
      }

      m_nSelection = sel;
  }

  // we want to give others a chance to process this message as well
  event.Skip();
}

as the result of SetFocus() is, that current window (even of another application) lost focus, and focus come to hidden form.

Posted: Thu Sep 22, 2005 9:57 am
by priyank_bolia
Get the focus before addpage by FindFocus, and setfocus after the addpage to the window returned by FindFocus.

Posted: Thu Sep 22, 2005 11:24 am
by Vaulter
priyank_bolia wrote:Get the focus before addpage by FindFocus, and setfocus after the addpage to the window returned by FindFocus.
heh, and as a result - something like GTA:SA will unresonable dissapear and then restore back?

Re: wxNotebook wrong focus when hide.

Posted: Thu Sep 22, 2005 6:00 pm
by Jamie
Vaulter wrote:is it right to set focus when window with wxNotebook is hidden?
It's a bug, replace this:

Code: Select all

      sel = event.GetSelection();
      if ( sel != -1 )
      {
        wxNotebookPage *pPage = m_pages[sel];
        pPage->Show(true);
        
        // As per bug report:
        // http://sourceforge.net/tracker/index.php?func=detail&aid=1150659&group_id=9863&atid=109863,
        // we should not set the page focus (and thereby the focus for
        // a child window) since it erroneously selects radio button controls and also
        // breaks keyboard handling for a notebook's scroll buttons. So
        // we always focus the notebook and not the page.
        SetFocus();

      }
      else // no pages in the notebook, give the focus to itself
      {
          SetFocus();
      }

      m_nSelection = sel;
with this:

Code: Select all

      sel = event.GetSelection();
      if ( sel != -1 )
      {
        wxNotebookPage *pPage = m_pages[sel];
        pPage->Show(true);
      }
    
      if ( IsShown() )
          SetFocus();

      m_nSelection = sel;
or do as priyank_bolia suggested.

I will post a patch to SF.

Re: wxNotebook wrong focus when hide.

Posted: Fri Sep 23, 2005 4:42 am
by Vaulter
Jamie wrote:

Code: Select all

      sel = event.GetSelection();
      if ( sel != -1 )
      {
        wxNotebookPage *pPage = m_pages[sel];
        pPage->Show(true);
      }
    
      if ( IsShown() )
          SetFocus();

      m_nSelection = sel;
I will post a patch to SF.
I think, we have to check for visibility all parents.
if we just check IsShown() - so, wxNotebook is NOT hidden on form. but form is!.

in my situation, parentness is - wxFrame -> wxSplitter -> wxNotebook.
i suggest this code for wxWindow:

Code: Select all

bool wxWindow:: IsVisible()
{
  if((m_parent && (!m_parent->IsVisible())) || (!m_isShown)) return false;
  return true;
}
or it can replace wxWindowBase::IsShown()

so we need to write:
if(IsVisible()) SetFocus();
this will invoke all IsVisible for parents, while some hidden not will be found. so all children are hidden to (return false)

Posted: Fri Sep 23, 2005 6:03 am
by Jamie
Yep, of course. I probably shouldn't code at 4am...

Replace

Code: Select all

if ( IsShown() )
with

Code: Select all

if ( ::IsWindowVisible(GetHwnd()) )

Posted: Fri Sep 23, 2005 6:06 am
by phlox81
Jamie wrote:Yep, of course. I probably shouldn't code at 4am...

Replace

Code: Select all

if ( IsShown() )
with

Code: Select all

if ( ::IsWindowVisible(GetHwnd()) )
Edit: left off a bracket
But this is a Windowsonly solution... (?)

Posted: Fri Sep 23, 2005 6:13 am
by Jamie
phlox81 wrote:But this is a Windowsonly solution... (?)
As far as I know it's a Windows only problem. The code snippet originally mentioned is from src/msw/notebook.cpp

Does this happen on other platforms as well?

Posted: Sun Sep 25, 2005 11:56 am
by Jamie
This has now been fixed in CVS.

Thanks

Posted: Wed Sep 28, 2005 8:26 pm
by daddydave
I think I may have a similar problem. I will try taking this bug into account, after I fully digest it.