]> git.saurik.com Git - wxWidgets.git/commitdiff
Set popup menu invoking window in wxWindowBase and not in all ports.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 26 Apr 2010 14:19:17 +0000 (14:19 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 26 Apr 2010 14:19:17 +0000 (14:19 +0000)
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

include/wx/menu.h
src/cocoa/taskbar.mm
src/common/wincmn.cpp
src/gtk/window.cpp
src/gtk1/menu.cpp
src/motif/window.cpp
src/msw/window.cpp
src/os2/window.cpp
src/osx/window_osx.cpp
src/univ/menu.cpp

index 5e318efac6f99bc1944a23f9269cfbbcb9afe2d1..accb6f1d7ea8b32a3bb247c7b4c1ba0bafba00a7 100644 (file)
@@ -259,6 +259,9 @@ public:
     // popup menu and reset after it's hidden. Notice that you probably want to
     // use GetWindow() below instead of GetInvokingWindow() as the latter only
     // returns non-NULL for the top level menus
+    //
+    // NB: avoid calling SetInvokingWindow() directly if possible, use
+    //     wxMenuInvokingWindowSetter class below instead
     void SetInvokingWindow(wxWindow *win);
     wxWindow *GetInvokingWindow() const { return m_invokingWindow; }
 
@@ -551,7 +554,35 @@ protected:
 #endif
 #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
-    // _WX_MENU_H_BASE_
+#endif // _WX_MENU_H_BASE_
index 78bc7c5747cf70c57e6a0d8d51b82f4abad04ff8..05ceafc5ca9ec09fae1b8c4a20a7cd3d2a931410 100644 (file)
@@ -311,8 +311,9 @@ bool wxTaskBarIconCustomStatusItemImpl::RemoveIcon()
 
 bool wxTaskBarIconCustomStatusItemImpl::PopupMenu(wxMenu *menu)
 {
-    wxASSERT(menu);
-    menu->SetInvokingWindow(m_iconWindow);
+    wxCHECK_MSG(menu, false, "can't popup a NULL menu");
+
+    wxMenuInvokingWindowSetter setInvokingWin(*menu, m_iconWindow);
     menu->UpdateUI();
 
     if([m_cocoaNSStatusItem respondsToSelector:@selector(popUpStatusItemMenu:)])
@@ -328,7 +329,6 @@ bool wxTaskBarIconCustomStatusItemImpl::PopupMenu(wxMenu *menu)
             eventNumber:0 clickCount:1 pressure:0.0];
         [NSMenu popUpContextMenu:menu->GetNSMenu() withEvent:nsevent forView:m_iconWindow->GetNSView()];
     }
-    menu->SetInvokingWindow(NULL);
     return true;
 }
 
index fdeecde22213c39396ba63c56681ab6372c2659d..dda93253469dfdc74a61ca07ca8fc613e013f23e 100644 (file)
@@ -2567,6 +2567,9 @@ bool wxWindowBase::PopupMenu(wxMenu *menu, int x, int y)
 {
     wxCHECK_MSG( menu, false, "can't popup NULL menu" );
 
+    wxMenuInvokingWindowSetter
+        setInvokingWin(*menu, static_cast<wxWindow *>(this));
+
     wxCurrentPopupMenu = menu;
     const bool rc = DoPopupMenu(menu, x, y);
     wxCurrentPopupMenu = NULL;
index 3bd97fb96f8a18b794ac0082b6f4b126d0a50d76..e1b0b87036044c3564ed361f621a55d40f635493 100644 (file)
@@ -3996,10 +3996,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
 {
     wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
 
-    wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") );
-
-    menu->SetInvokingWindow( this );
-
     menu->UpdateUI();
 
     wxPoint pos;
@@ -4034,8 +4030,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
         gtk_main_iteration();
     }
 
-    menu->SetInvokingWindow( NULL );
-
     return true;
 }
 
index a14e6b063ae51758ca743858f488ccb85a032a1d..5e3e83d92f6190fd82bfe29598ebf07853807650 100644 (file)
@@ -1457,23 +1457,6 @@ void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting  )
     *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
 void wxPopupMenuPositionCallback( GtkMenu *menu,
                                   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
     //       is ugly code duplication, I know.
 
-    SetInvokingWindow( menu, this );
-
     menu->UpdateUI();
 
     bool is_waiting = true;
index 0d3e0b548eabf875e1ae015acb40a1fa2c5aee45..aca5e608d3587ba30cd5da1fa3e8225e7d7843c3 100644 (file)
@@ -1083,7 +1083,6 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
 
     menu->SetId(1); /* Mark as popped-up */
     menu->CreateMenu(NULL, widget, menu, 0);
-    menu->SetInvokingWindow(this);
 
     menu->UpdateUI();
 
index 3b8ced6092b507aeb3d972a0442fad42a3e101ad..baf0318950fe7043e748b2d5510d5b0a711dbbd7 100644 (file)
@@ -2267,7 +2267,6 @@ static void wxYieldForCommandsOnly()
 
 bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 {
-    menu->SetInvokingWindow(this);
     menu->UpdateUI();
 
     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
     wxYieldForCommandsOnly();
 
-    menu->SetInvokingWindow(NULL);
-
     return true;
 }
 
index 7a44b19018cd028220f5721bac92326c5da028a7..33862da5f0a070ede9d5e5fa6383ae940a0240fd 100644 (file)
@@ -1788,7 +1788,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
     bool bIsWaiting = true;
     int nHeight;
 
-    pMenu->SetInvokingWindow(this);
     pMenu->UpdateUI();
 
     if ( nX == -1 && nY == -1 )
@@ -1824,7 +1823,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
         ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
     }
 
-    pMenu->SetInvokingWindow(NULL);
     return true;
 } // end of wxWindowOS2::DoPopupMenu
 #endif // wxUSE_MENUS_NATIVE
index 53fb99f7f1b61314cddbba7825f2c7d78adc4c58..cd8aecdc4d55cdec84ab47b461341c620a06b350 100644 (file)
@@ -100,7 +100,7 @@ class WXDLLIMPEXP_CORE wxBlindPlateWindow : public wxWindow
 {
 public:
     wxBlindPlateWindow() { Init(); }
-    
+
     // Old-style constructor (no default values for coordinates to avoid
     // ambiguity with the new one)
     wxBlindPlateWindow(wxWindow *parent,
@@ -109,10 +109,10 @@ public:
             const wxString& name = wxPanelNameStr)
     {
         Init();
-        
+
         Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height), style, name);
     }
-    
+
     // Constructor
     wxBlindPlateWindow(wxWindow *parent,
             wxWindowID winid = wxID_ANY,
@@ -122,10 +122,10 @@ public:
             const wxString& name = wxPanelNameStr)
     {
         Init();
-        
+
         Create(parent, winid, pos, size, style, name);
     }
-    
+
     // Pseudo ctor
     bool Create(wxWindow *parent,
                 wxWindowID winid = wxID_ANY,
@@ -136,25 +136,25 @@ public:
     {
         if ( !wxWindow::Create(parent, winid, pos, size, style, name) )
             return false;
-        
+
         // so that non-solid background renders correctly under GTK+:
         SetThemeEnabled(true);
         return true;
     }
-    
+
     virtual ~wxBlindPlateWindow();
-    
+
     virtual bool AcceptsFocus() const
     {
         return false;
     }
-    
+
 protected:
     // common part of all ctors
     void Init()
     {
     }
-        
+
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxBlindPlateWindow)
     DECLARE_EVENT_TABLE()
 };
@@ -415,7 +415,7 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
     m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
 #endif
 
-    
+
     switch ( variant )
     {
         case wxWINDOW_VARIANT_NORMAL :
@@ -477,7 +477,7 @@ bool wxWindowMac::SetBackgroundStyle(wxBackgroundStyle style)
 {
     if ( !wxWindowBase::SetBackgroundStyle(style) )
         return false;
-    
+
     if ( m_peer )
         m_peer->SetBackgroundStyle(style);
     return true;
@@ -809,7 +809,6 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor)
 bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
 {
 #ifndef __WXUNIVERSAL__
-    menu->SetInvokingWindow((wxWindow*)this);
     menu->UpdateUI();
 
     if ( x == wxDefaultCoord && y == wxDefaultCoord )
@@ -823,7 +822,6 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
         ClientToScreen( &x , &y ) ;
     }
     menu->GetPeer()->PopUp(this, x, y);
-    menu->SetInvokingWindow( NULL );
     return true;
 #else
     // actually this shouldn't be called, because universal is having its own implementation
@@ -844,7 +842,7 @@ void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
 
     if ( m_tooltip )
         m_tooltip->SetWindow(this);
-        
+
     if (m_peer)
         m_peer->SetToolTip(tooltip);
 }
@@ -1154,16 +1152,16 @@ bool wxWindowMac::Show(bool show)
         m_peer->SetVisibility( show ) ;
 
 #ifdef __WXOSX_IPHONE__
-    // only when there's no native event support 
+    // only when there's no native event support
     if ( !IsTopLevel() )
 #endif
     {
         wxShowEvent eventShow(GetId(), show);
         eventShow.SetEventObject(this);
-    
+
         HandleWindowEvent(eventShow);
     }
-    
+
     return true;
 }
 
@@ -1629,7 +1627,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
 
         if (child->IsTopLevel())
             continue;
-        
+
         if ( !IsClientAreaChild(child) )
             continue;
 
index 4714ba73f3464a2d6461f6defb26f03633a8751f..571761f561d1d3a4f4dc51c73e8ae7cfbe8d3bc2 100644 (file)
@@ -2497,10 +2497,6 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
     Update();
 #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));
 
     // 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
     PopEventHandler(true /* delete it */);
 
-    menu->SetInvokingWindow(NULL);
-
 #ifdef __WXMSW__
     SetCursor(cursorOld);
 #endif // __WXMSW__