Set popup menu invoking window in wxWindowBase and not in all ports.
Don't duplicate the code for setting (and unsetting, which was forgotten by at least wxGTK) the popup menu invoking window in all ports but do it in the base class PopupMenu() itself. Also add a helper wxMenuInvokingWindowSetter class which ensures that the invoking window will be unset in any case. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64143 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -259,6 +259,9 @@ public:
|
|||||||
// popup menu and reset after it's hidden. Notice that you probably want to
|
// popup menu and reset after it's hidden. Notice that you probably want to
|
||||||
// use GetWindow() below instead of GetInvokingWindow() as the latter only
|
// use GetWindow() below instead of GetInvokingWindow() as the latter only
|
||||||
// returns non-NULL for the top level menus
|
// returns non-NULL for the top level menus
|
||||||
|
//
|
||||||
|
// NB: avoid calling SetInvokingWindow() directly if possible, use
|
||||||
|
// wxMenuInvokingWindowSetter class below instead
|
||||||
void SetInvokingWindow(wxWindow *win);
|
void SetInvokingWindow(wxWindow *win);
|
||||||
wxWindow *GetInvokingWindow() const { return m_invokingWindow; }
|
wxWindow *GetInvokingWindow() const { return m_invokingWindow; }
|
||||||
|
|
||||||
@@ -551,7 +554,35 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
#endif // wxUSE_BASE_CLASSES_ONLY/!wxUSE_BASE_CLASSES_ONLY
|
#endif // wxUSE_BASE_CLASSES_ONLY/!wxUSE_BASE_CLASSES_ONLY
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Helper class used in the implementation only: sets the invoking window of
|
||||||
|
// the given menu in its ctor and resets it in dtor.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxMenuInvokingWindowSetter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Ctor sets the invoking window for the given menu.
|
||||||
|
//
|
||||||
|
// The menu lifetime must be greater than that of this class.
|
||||||
|
wxMenuInvokingWindowSetter(wxMenu& menu, wxWindow *win)
|
||||||
|
: m_menu(menu)
|
||||||
|
{
|
||||||
|
menu.SetInvokingWindow(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dtor resets the invoking window.
|
||||||
|
~wxMenuInvokingWindowSetter()
|
||||||
|
{
|
||||||
|
m_menu.SetInvokingWindow(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxMenu& m_menu;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxMenuInvokingWindowSetter);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // wxUSE_MENUS
|
#endif // wxUSE_MENUS
|
||||||
|
|
||||||
#endif
|
#endif // _WX_MENU_H_BASE_
|
||||||
// _WX_MENU_H_BASE_
|
|
||||||
|
@@ -311,8 +311,9 @@ bool wxTaskBarIconCustomStatusItemImpl::RemoveIcon()
|
|||||||
|
|
||||||
bool wxTaskBarIconCustomStatusItemImpl::PopupMenu(wxMenu *menu)
|
bool wxTaskBarIconCustomStatusItemImpl::PopupMenu(wxMenu *menu)
|
||||||
{
|
{
|
||||||
wxASSERT(menu);
|
wxCHECK_MSG(menu, false, "can't popup a NULL menu");
|
||||||
menu->SetInvokingWindow(m_iconWindow);
|
|
||||||
|
wxMenuInvokingWindowSetter setInvokingWin(*menu, m_iconWindow);
|
||||||
menu->UpdateUI();
|
menu->UpdateUI();
|
||||||
|
|
||||||
if([m_cocoaNSStatusItem respondsToSelector:@selector(popUpStatusItemMenu:)])
|
if([m_cocoaNSStatusItem respondsToSelector:@selector(popUpStatusItemMenu:)])
|
||||||
@@ -328,7 +329,6 @@ bool wxTaskBarIconCustomStatusItemImpl::PopupMenu(wxMenu *menu)
|
|||||||
eventNumber:0 clickCount:1 pressure:0.0];
|
eventNumber:0 clickCount:1 pressure:0.0];
|
||||||
[NSMenu popUpContextMenu:menu->GetNSMenu() withEvent:nsevent forView:m_iconWindow->GetNSView()];
|
[NSMenu popUpContextMenu:menu->GetNSMenu() withEvent:nsevent forView:m_iconWindow->GetNSView()];
|
||||||
}
|
}
|
||||||
menu->SetInvokingWindow(NULL);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2567,6 +2567,9 @@ bool wxWindowBase::PopupMenu(wxMenu *menu, int x, int y)
|
|||||||
{
|
{
|
||||||
wxCHECK_MSG( menu, false, "can't popup NULL menu" );
|
wxCHECK_MSG( menu, false, "can't popup NULL menu" );
|
||||||
|
|
||||||
|
wxMenuInvokingWindowSetter
|
||||||
|
setInvokingWin(*menu, static_cast<wxWindow *>(this));
|
||||||
|
|
||||||
wxCurrentPopupMenu = menu;
|
wxCurrentPopupMenu = menu;
|
||||||
const bool rc = DoPopupMenu(menu, x, y);
|
const bool rc = DoPopupMenu(menu, x, y);
|
||||||
wxCurrentPopupMenu = NULL;
|
wxCurrentPopupMenu = NULL;
|
||||||
|
@@ -3996,10 +3996,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
|
|||||||
{
|
{
|
||||||
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
|
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
|
||||||
|
|
||||||
wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") );
|
|
||||||
|
|
||||||
menu->SetInvokingWindow( this );
|
|
||||||
|
|
||||||
menu->UpdateUI();
|
menu->UpdateUI();
|
||||||
|
|
||||||
wxPoint pos;
|
wxPoint pos;
|
||||||
@@ -4034,8 +4030,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
|
|||||||
gtk_main_iteration();
|
gtk_main_iteration();
|
||||||
}
|
}
|
||||||
|
|
||||||
menu->SetInvokingWindow( NULL );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1457,23 +1457,6 @@ void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting )
|
|||||||
*is_waiting = false;
|
*is_waiting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDLLIMPEXP_CORE void SetInvokingWindow( wxMenu *menu, wxWindow* win )
|
|
||||||
{
|
|
||||||
menu->SetInvokingWindow( win );
|
|
||||||
|
|
||||||
wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *menuitem = node->GetData();
|
|
||||||
if (menuitem->IsSubMenu())
|
|
||||||
{
|
|
||||||
SetInvokingWindow( menuitem->GetSubMenu(), win );
|
|
||||||
}
|
|
||||||
|
|
||||||
node = node->GetNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" WXDLLIMPEXP_CORE
|
extern "C" WXDLLIMPEXP_CORE
|
||||||
void wxPopupMenuPositionCallback( GtkMenu *menu,
|
void wxPopupMenuPositionCallback( GtkMenu *menu,
|
||||||
gint *x, gint *y,
|
gint *x, gint *y,
|
||||||
@@ -1503,8 +1486,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
|
|||||||
// the same code in taskbar.cpp as well. This
|
// the same code in taskbar.cpp as well. This
|
||||||
// is ugly code duplication, I know.
|
// is ugly code duplication, I know.
|
||||||
|
|
||||||
SetInvokingWindow( menu, this );
|
|
||||||
|
|
||||||
menu->UpdateUI();
|
menu->UpdateUI();
|
||||||
|
|
||||||
bool is_waiting = true;
|
bool is_waiting = true;
|
||||||
|
@@ -1083,7 +1083,6 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
|||||||
|
|
||||||
menu->SetId(1); /* Mark as popped-up */
|
menu->SetId(1); /* Mark as popped-up */
|
||||||
menu->CreateMenu(NULL, widget, menu, 0);
|
menu->CreateMenu(NULL, widget, menu, 0);
|
||||||
menu->SetInvokingWindow(this);
|
|
||||||
|
|
||||||
menu->UpdateUI();
|
menu->UpdateUI();
|
||||||
|
|
||||||
|
@@ -2267,7 +2267,6 @@ static void wxYieldForCommandsOnly()
|
|||||||
|
|
||||||
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||||
{
|
{
|
||||||
menu->SetInvokingWindow(this);
|
|
||||||
menu->UpdateUI();
|
menu->UpdateUI();
|
||||||
|
|
||||||
if ( x == wxDefaultCoord && y == wxDefaultCoord )
|
if ( x == wxDefaultCoord && y == wxDefaultCoord )
|
||||||
@@ -2310,8 +2309,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
|
|||||||
// for example) and so we do need to process the event immediately
|
// for example) and so we do need to process the event immediately
|
||||||
wxYieldForCommandsOnly();
|
wxYieldForCommandsOnly();
|
||||||
|
|
||||||
menu->SetInvokingWindow(NULL);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1788,7 +1788,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
|
|||||||
bool bIsWaiting = true;
|
bool bIsWaiting = true;
|
||||||
int nHeight;
|
int nHeight;
|
||||||
|
|
||||||
pMenu->SetInvokingWindow(this);
|
|
||||||
pMenu->UpdateUI();
|
pMenu->UpdateUI();
|
||||||
|
|
||||||
if ( nX == -1 && nY == -1 )
|
if ( nX == -1 && nY == -1 )
|
||||||
@@ -1824,7 +1823,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
|
|||||||
::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
|
::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pMenu->SetInvokingWindow(NULL);
|
|
||||||
return true;
|
return true;
|
||||||
} // end of wxWindowOS2::DoPopupMenu
|
} // end of wxWindowOS2::DoPopupMenu
|
||||||
#endif // wxUSE_MENUS_NATIVE
|
#endif // wxUSE_MENUS_NATIVE
|
||||||
|
@@ -809,7 +809,6 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor)
|
|||||||
bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
|
bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||||
{
|
{
|
||||||
#ifndef __WXUNIVERSAL__
|
#ifndef __WXUNIVERSAL__
|
||||||
menu->SetInvokingWindow((wxWindow*)this);
|
|
||||||
menu->UpdateUI();
|
menu->UpdateUI();
|
||||||
|
|
||||||
if ( x == wxDefaultCoord && y == wxDefaultCoord )
|
if ( x == wxDefaultCoord && y == wxDefaultCoord )
|
||||||
@@ -823,7 +822,6 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
|
|||||||
ClientToScreen( &x , &y ) ;
|
ClientToScreen( &x , &y ) ;
|
||||||
}
|
}
|
||||||
menu->GetPeer()->PopUp(this, x, y);
|
menu->GetPeer()->PopUp(this, x, y);
|
||||||
menu->SetInvokingWindow( NULL );
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
// actually this shouldn't be called, because universal is having its own implementation
|
// actually this shouldn't be called, because universal is having its own implementation
|
||||||
|
@@ -2497,10 +2497,6 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
|||||||
Update();
|
Update();
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
menu->SetInvokingWindow(this);
|
|
||||||
|
|
||||||
// wxLogDebug( "Name of invoking window %s", menu->GetInvokingWindow()->GetName().c_str() );
|
|
||||||
|
|
||||||
menu->Popup(ClientToScreen(wxPoint(x, y)), wxSize(0,0));
|
menu->Popup(ClientToScreen(wxPoint(x, y)), wxSize(0,0));
|
||||||
|
|
||||||
// this is not very useful if the menu was popped up because of the mouse
|
// this is not very useful if the menu was popped up because of the mouse
|
||||||
@@ -2523,8 +2519,6 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
|||||||
// remove the handler
|
// remove the handler
|
||||||
PopEventHandler(true /* delete it */);
|
PopEventHandler(true /* delete it */);
|
||||||
|
|
||||||
menu->SetInvokingWindow(NULL);
|
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
SetCursor(cursorOld);
|
SetCursor(cursorOld);
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
Reference in New Issue
Block a user