From: Vadim Zeitlin Date: Sun, 22 Oct 2006 20:25:08 +0000 (+0000) Subject: add alt popup window style allowing to use keyboard and comboboxes in the popup windo... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/06077aaf2c11135bb9ca18ef33181ab18ac7480e?ds=inline add alt popup window style allowing to use keyboard and comboboxes in the popup window and use it for the generic date picker (patch 1582391 from Jaakko) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42247 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/latex/wx/comboctrl.tex b/docs/latex/wx/comboctrl.tex index 1dc9e049ce..210f3c3e5a 100644 --- a/docs/latex/wx/comboctrl.tex +++ b/docs/latex/wx/comboctrl.tex @@ -664,3 +664,15 @@ Show the popup. Undoes the last edit in the text field. Windows only. + +\membersection{wxComboCtrl::UseAltPopupWindow}\label{wxcomboctrlusealtpopupwindow} + +\func{void}{UseAltPopupWindow}{\param{bool }{enable = true}} + +Enable or disable usage of an alternative popup window, which guarantees +ability to focus the popup control, and allows common native controls to +function normally. This alternative popup window is usually a wxDialog, +and as such, when it is shown, its parent top-level window will appear +as if the focus has been lost from it. + + diff --git a/include/wx/combo.h b/include/wx/combo.h index 4de8d8aa3d..e3723d0794 100644 --- a/include/wx/combo.h +++ b/include/wx/combo.h @@ -83,7 +83,9 @@ enum // Internal use: SetTextIndent has been called wxCC_IFLAG_INDENT_SET = 0x0400, // Internal use: Set wxTAB_TRAVERSAL to parent when popup is dismissed - wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800 + wxCC_IFLAG_PARENT_TAB_TRAVERSAL = 0x0800, + // Internal use: Secondary popup window type should be used (if available). + wxCC_IFLAG_USE_ALT_POPUP = 0x1000 }; @@ -305,6 +307,21 @@ public: return m_tcArea; } + // Call with enable as true to use a type of popup window that guarantees ability + // to focus the popup control, and normal function of common native controls. + // This alternative popup window is usually a wxDialog, and as such it's parent + // frame will appear as if the focus has been lost from it. + void UseAltPopupWindow( bool enable = true ) + { + wxASSERT_MSG( !m_winPopup, + wxT("call this only before SetPopupControl") ); + + if ( enable ) + m_iFlags |= wxCC_IFLAG_USE_ALT_POPUP; + else + m_iFlags &= ~wxCC_IFLAG_USE_ALT_POPUP; + } + // // Utilies needed by the popups or native implementations // @@ -459,6 +476,9 @@ protected: // this is for the control in popup wxEvtHandler* m_popupExtraHandler; + // this is for the popup window + wxEvtHandler* m_popupWinEvtHandler; + // used to prevent immediate re-popupping incase closed popup // by clicking on the combo control (needed because of inconsistent // transient implementation across platforms). @@ -527,6 +547,9 @@ private: wxByte m_ignoreEvtText; // Number of next EVT_TEXTs to ignore + // Is popup window wxPopupTransientWindow, wxPopupWindow or wxDialog? + wxByte m_popupWinType; + DECLARE_EVENT_TABLE() DECLARE_ABSTRACT_CLASS(wxComboCtrlBase) diff --git a/samples/combo/combo.cpp b/samples/combo/combo.cpp index 3ce2870d17..4deda51fec 100644 --- a/samples/combo/combo.cpp +++ b/samples/combo/combo.cpp @@ -83,6 +83,8 @@ public: // log wxComboCtrl events void OnComboBoxUpdate( wxCommandEvent& event ); + void OnIdle( wxIdleEvent& event ); + protected: wxTextCtrl* m_logWin; wxLog* m_logOld; @@ -127,6 +129,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(ComboControl_Compare, MyFrame::OnShowComparison) EVT_MENU(ComboControl_Quit, MyFrame::OnQuit) EVT_MENU(ComboControl_About, MyFrame::OnAbout) + + EVT_IDLE(MyFrame::OnIdle) END_EVENT_TABLE() // Create a new application object: this macro will allow wxWidgets to create @@ -729,6 +733,9 @@ MyFrame::MyFrame(const wxString& title) cc = new wxComboCtrl(panel,2,wxEmptyString, wxDefaultPosition, wxDefaultSize); + // Make sure we use popup that allows focusing the listview. + cc->UseAltPopupWindow(); + cc->SetPopupMinWidth(300); ListViewComboPopup* iface = new ListViewComboPopup(); @@ -749,6 +756,9 @@ MyFrame::MyFrame(const wxString& title) gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString, wxDefaultPosition, wxDefaultSize); + // Make sure we use popup that allows focusing the treectrl. + gcc->UseAltPopupWindow(); + // Set popup interface right away, otherwise some of the calls // below may fail TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup(); @@ -1059,3 +1069,27 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) wxOK | wxICON_INFORMATION, this); } + +void MyFrame::OnIdle(wxIdleEvent& event) +{ + // This code is useful for debugging focus problems + // (which are plentiful when dealing with popup windows). +#if 0 + static wxWindow* lastFocus = (wxWindow*) NULL; + + wxWindow* curFocus = ::wxWindow::FindFocus(); + + if ( curFocus != lastFocus ) + { + const wxChar* className = wxT(""); + if ( curFocus ) + className = curFocus->GetClassInfo()->GetClassName(); + lastFocus = curFocus; + wxLogDebug( wxT("FOCUSED: %s %X"), + className, + (unsigned int)curFocus); + } +#endif + + event.Skip(); +} diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index aef6c75cbf..0b53234ca9 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -62,6 +62,9 @@ #if defined(__WXMSW__) #define USE_TRANSIENT_POPUP 1 // Use wxPopupWindowTransient (preferred, if it works properly on platform) +#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common + // native controls work on it like normal. +#define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 0 // 1 if text in textctrl is vertically centered //#undef wxUSE_POPUPWIN @@ -69,17 +72,32 @@ #elif defined(__WXGTK__) +// NB: It is not recommended to use wxDialog as popup on wxGTK, because of +// this bug: If wxDialog is hidden, its position becomes corrupt +// between hide and next show, but without internal coordinates being +// reflected (or something like that - atleast commenting out ->Hide() +// seemed to eliminate the position change). + #define USE_TRANSIENT_POPUP 1 // Use wxPopupWindowTransient (preferred, if it works properly on platform) +#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common + // native controls work on it like normal. +#define POPUPWIN_IS_PERFECT 1 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered #elif defined(__WXMAC__) #define USE_TRANSIENT_POPUP 0 // Use wxPopupWindowTransient (preferred, if it works properly on platform) +#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common + // native controls work on it like normal. +#define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered #else #define USE_TRANSIENT_POPUP 0 // Use wxPopupWindowTransient (preferred, if it works properly on platform) +#define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common + // native controls work on it like normal. +#define POPUPWIN_IS_PERFECT 0 // Same, but for non-transient popup window. #define TEXTCTRL_TEXT_CENTERED 1 // 1 if text in textctrl is vertically centered #endif @@ -102,24 +120,77 @@ #endif -#if USE_TRANSIENT_POPUP +// Define different types of popup windows +enum +{ + POPUPWIN_NONE = 0, + POPUPWIN_WXPOPUPTRANSIENTWINDOW = 1, + POPUPWIN_WXPOPUPWINDOW = 2, + POPUPWIN_WXDIALOG = 3 +}; - #define wxComboPopupWindowBase wxPopupTransientWindow - #define INSTALL_TOPLEV_HANDLER 0 + +#if USE_TRANSIENT_POPUP + // wxPopupTransientWindow is implemented + + #define wxComboPopupWindowBase wxPopupTransientWindow + #define PRIMARY_POPUP_TYPE POPUPWIN_WXPOPUPTRANSIENTWINDOW + #define USES_WXPOPUPTRANSIENTWINDOW 1 + + #if TRANSIENT_POPUPWIN_IS_PERFECT + // + #elif POPUPWIN_IS_PERFECT + #define wxComboPopupWindowBase2 wxPopupWindow + #define SECONDARY_POPUP_TYPE POPUPWIN_WXPOPUPWINDOW + #define USES_WXPOPUPWINDOW 1 + #else + #define wxComboPopupWindowBase2 wxDialog + #define SECONDARY_POPUP_TYPE POPUPWIN_WXDIALOG + #define USES_WXDIALOG 1 + #endif #elif wxUSE_POPUPWIN + // wxPopupWindow (but not wxPopupTransientWindow) is properly implemented - #define wxComboPopupWindowBase wxPopupWindow - #define INSTALL_TOPLEV_HANDLER 1 + #define wxComboPopupWindowBase wxPopupWindow + #define PRIMARY_POPUP_TYPE POPUPWIN_WXPOPUPWINDOW + #define USES_WXPOPUPWINDOW 1 + + #if !POPUPWIN_IS_PERFECT + #define wxComboPopupWindowBase2 wxDialog + #define SECONDARY_POPUP_TYPE POPUPWIN_WXDIALOG + #define USES_WXDIALOG 1 + #endif #else + // wxPopupWindow is not implemented + + #define wxComboPopupWindowBase wxDialog + #define PRIMARY_POPUP_TYPE POPUPWIN_WXDIALOG + #define USES_WXDIALOG 1 + +#endif + + +#ifndef USES_WXPOPUPTRANSIENTWINDOW + #define USES_WXPOPUPTRANSIENTWINDOW 0 +#endif - #define wxComboPopupWindowBase wxDialog - #define INSTALL_TOPLEV_HANDLER 0 // Doesn't need since can monitor active event +#ifndef USES_WXPOPUPWINDOW + #define USES_WXPOPUPWINDOW 0 +#endif +#ifndef USES_WXDIALOG + #define USES_WXDIALOG 0 #endif +#if USES_WXPOPUPWINDOW + #define INSTALL_TOPLEV_HANDLER 1 +#else + #define INSTALL_TOPLEV_HANDLER 0 +#endif + // // ** TODO ** @@ -252,7 +323,7 @@ void wxComboFrameEventHandler::OnMove( wxMoveEvent& event ) #endif // INSTALL_TOPLEV_HANDLER // ---------------------------------------------------------------------------- -// wxComboPopupWindow is wxPopupWindow customized for +// wxComboPopupWindow is, in essence, wxPopupWindow customized for // wxComboCtrl. // ---------------------------------------------------------------------------- @@ -260,105 +331,105 @@ class wxComboPopupWindow : public wxComboPopupWindowBase { public: - wxComboPopupWindow( wxComboCtrlBase *parent, int style = wxBORDER_NONE ); + wxComboPopupWindow( wxComboCtrlBase *parent, + int style ) + #if USES_WXPOPUPWINDOW || USES_WXPOPUPTRANSIENTWINDOW + : wxComboPopupWindowBase(parent,style) + #else + : wxComboPopupWindowBase(parent, + wxID_ANY, + wxEmptyString, + wxPoint(-21,-21), + wxSize(20,20), + style) + #endif + { + } -#if USE_TRANSIENT_POPUP +#if USES_WXPOPUPTRANSIENTWINDOW virtual bool ProcessLeftDown(wxMouseEvent& event); + virtual void OnDismiss(); #endif - void OnKeyEvent(wxKeyEvent& event); +}; - void OnMouseEvent( wxMouseEvent& event ); -#if !wxUSE_POPUPWIN - void OnActivate( wxActivateEvent& event ); -#endif -protected: +#if USES_WXPOPUPTRANSIENTWINDOW +bool wxComboPopupWindow::ProcessLeftDown(wxMouseEvent& event ) +{ + return wxComboPopupWindowBase::ProcessLeftDown(event); +} -#if USE_TRANSIENT_POPUP - virtual void OnDismiss(); +// First thing that happens when a transient popup closes is that this method gets called. +void wxComboPopupWindow::OnDismiss() +{ + wxComboCtrlBase* combo = (wxComboCtrlBase*) GetParent(); + wxASSERT_MSG( combo->IsKindOf(CLASSINFO(wxComboCtrlBase)), + wxT("parent might not be wxComboCtrl, but check IMPLEMENT_DYNAMIC_CLASS(2) macro for correctness") ); + + combo->OnPopupDismiss(); +} +#endif // USES_WXPOPUPTRANSIENTWINDOW + + +// ---------------------------------------------------------------------------- +// wxComboPopupWindowEvtHandler does bulk of the custom event handling +// of a popup window. It is separate so we can have different types +// of popup windows. +// ---------------------------------------------------------------------------- + +class wxComboPopupWindowEvtHandler : public wxEvtHandler +{ +public: + + wxComboPopupWindowEvtHandler( wxComboCtrlBase *parent ) + { + m_combo = parent; + } + + void OnKeyEvent(wxKeyEvent& event); +#if USES_WXDIALOG + void OnActivate( wxActivateEvent& event ); #endif private: + wxComboCtrlBase* m_combo; + DECLARE_EVENT_TABLE() }; -BEGIN_EVENT_TABLE(wxComboPopupWindow, wxComboPopupWindowBase) - EVT_MOUSE_EVENTS(wxComboPopupWindow::OnMouseEvent) -#if !wxUSE_POPUPWIN - EVT_ACTIVATE(wxComboPopupWindow::OnActivate) +BEGIN_EVENT_TABLE(wxComboPopupWindowEvtHandler, wxEvtHandler) + EVT_KEY_DOWN(wxComboPopupWindowEvtHandler::OnKeyEvent) + EVT_KEY_UP(wxComboPopupWindowEvtHandler::OnKeyEvent) +#if USES_WXDIALOG + EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate) #endif - EVT_KEY_DOWN(wxComboPopupWindow::OnKeyEvent) - EVT_KEY_UP(wxComboPopupWindow::OnKeyEvent) END_EVENT_TABLE() -wxComboPopupWindow::wxComboPopupWindow( wxComboCtrlBase *parent, - int style ) -#if wxUSE_POPUPWIN - : wxComboPopupWindowBase(parent,style) -#else - : wxComboPopupWindowBase(parent, - wxID_ANY, - wxEmptyString, - wxPoint(-21,-21), - wxSize(20,20), - style) -#endif -{ -} - -void wxComboPopupWindow::OnKeyEvent( wxKeyEvent& event ) +void wxComboPopupWindowEvtHandler::OnKeyEvent( wxKeyEvent& event ) { // Relay keyboard event to the main child controls - // (just skipping may just cause the popup to close) - wxWindowList children = GetChildren(); + wxWindowList children = m_combo->GetPopupWindow()->GetChildren(); wxWindowList::iterator node = children.begin(); wxWindow* child = (wxWindow*)*node; child->AddPendingEvent(event); } -void wxComboPopupWindow::OnMouseEvent( wxMouseEvent& event ) -{ - event.Skip(); -} - -#if !wxUSE_POPUPWIN -void wxComboPopupWindow::OnActivate( wxActivateEvent& event ) +#if USES_WXDIALOG +void wxComboPopupWindowEvtHandler::OnActivate( wxActivateEvent& event ) { if ( !event.GetActive() ) { // Tell combo control that we are dismissed. - wxComboCtrl* combo = (wxComboCtrl*) GetParent(); - wxASSERT( combo ); - wxASSERT( combo->IsKindOf(CLASSINFO(wxComboCtrl)) ); - - combo->HidePopup(); + m_combo->HidePopup(); event.Skip(); } } #endif -#if USE_TRANSIENT_POPUP -bool wxComboPopupWindow::ProcessLeftDown(wxMouseEvent& event ) -{ - return wxComboPopupWindowBase::ProcessLeftDown(event); -} -#endif - -#if USE_TRANSIENT_POPUP -// First thing that happens when a transient popup closes is that this method gets called. -void wxComboPopupWindow::OnDismiss() -{ - wxComboCtrlBase* combo = (wxComboCtrlBase*) GetParent(); - wxASSERT_MSG( combo->IsKindOf(CLASSINFO(wxComboCtrlBase)), - wxT("parent might not be wxComboCtrl, but check IMPLEMENT_DYNAMIC_CLASS(2) macro for correctness") ); - - combo->OnPopupDismiss(); -} -#endif // ---------------------------------------------------------------------------- // wxComboPopup @@ -639,6 +710,7 @@ void wxComboCtrlBase::Init() m_btnWidDefault = 0; m_blankButtonBg = false; m_ignoreEvtText = 0; + m_popupWinType = POPUPWIN_NONE; m_btnWid = m_btnHei = -1; m_btnSide = wxRIGHT; m_btnSpacingX = 0; @@ -1354,12 +1426,15 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event, wxLongLong t = ::wxGetLocalTimeMillis(); int evtType = event.GetEventType(); -#if !USE_TRANSIENT_POPUP - if ( m_isPopupShown && - ( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) ) +#if USES_WXPOPUPWINDOW || USES_WXDIALOG + if ( m_popupWinType != POPUPWIN_WXPOPUPTRANSIENTWINDOW ) { - HidePopup(); - return true; + if ( m_isPopupShown && + ( evtType == wxEVT_LEFT_DOWN || evtType == wxEVT_RIGHT_DOWN ) ) + { + HidePopup(); + return true; + } } #endif @@ -1382,11 +1457,10 @@ void wxComboCtrlBase::HandleNormalMouseEvent( wxMouseEvent& event ) { if ( m_isPopupShown ) { - #if !wxUSE_POPUPWIN - // Normally do nothing - evt handler should close it for us - #elif !USE_TRANSIENT_POPUP + #if USES_WXPOPUPWINDOW // Click here always hides the popup. - HidePopup(); + if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW ) + HidePopup(); #endif } else @@ -1495,7 +1569,28 @@ void wxComboCtrlBase::CreatePopup() wxWindow* popup; if ( !m_winPopup ) - m_winPopup = new wxComboPopupWindow( this, wxNO_BORDER ); + { +#ifdef wxComboPopupWindowBase2 + if ( m_iFlags & wxCC_IFLAG_USE_ALT_POPUP ) + { + #if !USES_WXDIALOG + m_winPopup = new wxComboPopupWindowBase2( this, wxNO_BORDER ); + #else + m_winPopup = new wxComboPopupWindowBase2( this, wxID_ANY, wxEmptyString, + wxPoint(-21,-21), wxSize(20, 20), + wxNO_BORDER ); + #endif + m_popupWinType = SECONDARY_POPUP_TYPE; + } + else +#endif + { + m_winPopup = new wxComboPopupWindow( this, wxNO_BORDER ); + m_popupWinType = PRIMARY_POPUP_TYPE; + } + m_popupWinEvtHandler = new wxComboPopupWindowEvtHandler(this); + m_winPopup->PushEventHandler(m_popupWinEvtHandler); + } popupInterface->Create(m_winPopup); m_popup = popup = popupInterface->GetControl(); @@ -1524,7 +1619,12 @@ void wxComboCtrlBase::DestroyPopup() delete m_popupInterface; if ( m_winPopup ) + { + m_winPopup->RemoveEventHandler(m_popupWinEvtHandler); + delete m_popupWinEvtHandler; + m_popupWinEvtHandler = NULL; m_winPopup->Destroy(); + } m_popupExtraHandler = (wxEvtHandler*) NULL; m_popupInterface = (wxComboPopup*) NULL; @@ -1728,32 +1828,47 @@ void wxComboCtrlBase::ShowPopup() m_isPopupShown = true; // Show it -#if USE_TRANSIENT_POPUP - ((wxPopupTransientWindow*)winPopup)->Popup(popup); -#else - winPopup->Show(); +#if USES_WXPOPUPTRANSIENTWINDOW + if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW ) + ((wxPopupTransientWindow*)winPopup)->Popup(popup); + else #endif + winPopup->Show(); #if INSTALL_TOPLEV_HANDLER // Put top level window event handler into place - if ( !m_toplevEvtHandler ) - m_toplevEvtHandler = new wxComboFrameEventHandler(this); + if ( m_popupWinType == POPUPWIN_WXPOPUPWINDOW ) + { + if ( !m_toplevEvtHandler ) + m_toplevEvtHandler = new wxComboFrameEventHandler(this); - wxWindow* toplev = ::wxGetTopLevelParent( this ); - wxASSERT( toplev ); - ((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup(); - toplev->PushEventHandler( m_toplevEvtHandler ); + wxWindow* toplev = ::wxGetTopLevelParent( this ); + wxASSERT( toplev ); + ((wxComboFrameEventHandler*)m_toplevEvtHandler)->OnPopup(); + toplev->PushEventHandler( m_toplevEvtHandler ); + } #endif } void wxComboCtrlBase::OnPopupDismiss() -{ +{ // Just in case, avoid double dismiss if ( !m_isPopupShown ) return; - // *Must* set this before focus etc. + // NB: Focus setting is really funny, atleast on wxMSW. First of all, + // we need to have SetFocus at the end. Otherwise wxTextCtrl may + // freeze until focus goes somewhere else. Second, wxTreeCtrl as + // popup, when dismissing, "steals" focus back to itself unless + // SetFocus is called also here, exactly before m_isPopupShown + // is set to false. Which is truly weird since SetFocus is just + // wxWindowMSW method and does not call event handler or anything like + // that (ie. does not care about m_isPopupShown). + + SetFocus(); + + // This should preferably be set before focus. m_isPopupShown = false; // Inform popup control itself @@ -1791,10 +1906,7 @@ void wxComboCtrlBase::OnPopupDismiss() // refresh control (necessary even if m_text) Refresh(); -#if !wxUSE_POPUPWIN SetFocus(); -#endif - } void wxComboCtrlBase::HidePopup() @@ -1807,11 +1919,12 @@ void wxComboCtrlBase::HidePopup() // transfer value and show it in textctrl, if any SetValue( m_popupInterface->GetStringValue() ); -#if USE_TRANSIENT_POPUP - ((wxPopupTransientWindow*)m_winPopup)->Dismiss(); -#else - m_winPopup->Hide(); +#if USES_WXPOPUPTRANSIENTWINDOW + if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW ) + ((wxPopupTransientWindow*)m_winPopup)->Dismiss(); + else #endif + m_winPopup->Hide(); OnPopupDismiss(); } diff --git a/src/common/popupcmn.cpp b/src/common/popupcmn.cpp index 41b8878af3..d0a3534f37 100644 --- a/src/common/popupcmn.cpp +++ b/src/common/popupcmn.cpp @@ -561,7 +561,7 @@ void wxPopupFocusHandler::OnKillFocus(wxFocusEvent& event) void wxPopupFocusHandler::OnKeyDown(wxKeyEvent& event) { // let the window have it first, it might process the keys - if ( !m_popup->ProcessEvent(event) ) + if ( !m_popup->GetEventHandler()->ProcessEvent(event) ) { // by default, dismiss the popup m_popup->DismissAndNotify(); diff --git a/src/generic/datectlg.cpp b/src/generic/datectlg.cpp index d22073d67e..b75484ed05 100644 --- a/src/generic/datectlg.cpp +++ b/src/generic/datectlg.cpp @@ -414,6 +414,10 @@ bool wxDatePickerCtrlGeneric::Create(wxWindow *parent, m_popup = new wxCalendarComboPopup(); +#if defined(__WXMSW__) + // without this keyboard navigation in month control doesn't work + m_combo->UseAltPopupWindow(); +#endif m_combo->SetPopupControl(m_popup); m_cal = m_popup;