wxGTK wxMenuBar used its own SetInvokingWindow/UnsetInvokingWindow() and
related functions instead of reusing the base class Attach/Detach() which
exist for exactly the same purpose. This resulted in unnecessary code
duplication and confusion and, since the changes of r64104, resulted in
asserts due to use of SetInvokingWindow() for non-popup menus.
Fix this by removing the wxGTK-specific functions and doing the work they used
to do in (now overridden) Attach() and Detach(). Also call Attach/Detach()
instead of these functions from wxGTK wxFrame and wxMDIParentFrame code.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64127
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
// window
virtual bool GTKNeedsParent() const { return false; }
// window
virtual bool GTKNeedsParent() const { return false; }
- void Attach(wxFrame *frame);
+ virtual void Attach(wxFrame *frame);
+ virtual void Detach();
// implementation only from now on
// implementation only from now on
- void SetInvokingWindow( wxWindow *win );
- void UnsetInvokingWindow( wxWindow *win );
GtkWidget *m_menubar; // Public for hildon support
private:
// common part of Append and Insert
bool GtkAppend(wxMenu *menu, const wxString& title, int pos=-1);
GtkWidget *m_menubar; // Public for hildon support
private:
// common part of Append and Insert
bool GtkAppend(wxMenu *menu, const wxString& title, int pos=-1);
- wxWindow *m_invokingWindow;
-
void Init(size_t n, wxMenu *menus[], const wxString titles[], long style);
DECLARE_DYNAMIC_CLASS(wxMenuBar)
void Init(size_t n, wxMenu *menus[], const wxString titles[], long style);
DECLARE_DYNAMIC_CLASS(wxMenuBar)
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
- m_frameMenuBar->UnsetInvokingWindow( this );
-
gtk_widget_ref( m_frameMenuBar->m_widget );
gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
gtk_widget_ref( m_frameMenuBar->m_widget );
gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
hildon_window_set_menu(HILDON_WINDOW(m_widget),
GTK_MENU(m_frameMenuBar->m_menubar));
#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
hildon_window_set_menu(HILDON_WINDOW(m_widget),
GTK_MENU(m_frameMenuBar->m_menubar));
#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
- m_frameMenuBar->SetInvokingWindow( this );
-
m_frameMenuBar->SetParent(this);
// menubar goes into top of vbox (m_mainWidget)
m_frameMenuBar->SetParent(this);
// menubar goes into top of vbox (m_mainWidget)
wxMenuBar *menu_bar = active_child_frame->m_menuBar;
if (menu_bar)
{
wxMenuBar *menu_bar = active_child_frame->m_menuBar;
if (menu_bar)
{
- menu_bar->SetInvokingWindow(active_child_frame);
+ menu_bar->Attach(active_child_frame);
}
}
m_justInserted = false;
}
}
m_justInserted = false;
{
if (menu_bar->Show(true))
{
{
if (menu_bar->Show(true))
{
- menu_bar->SetInvokingWindow( child_frame );
+ // Attach() asserts if we call it for an already
+ // attached menu bar so don't do it if we're already
+ // associated with this frame (it would be nice to get
+ // rid of this check and ensure that this doesn't
+ // happen...)
+ if ( menu_bar->GetFrame() != child_frame )
+ menu_bar->Attach( child_frame );
}
visible_child_menu = true;
}
}
visible_child_menu = true;
}
{
if (menu_bar->Show(false))
{
{
if (menu_bar->Show(false))
{
- menu_bar->UnsetInvokingWindow( child_frame );
if (visible_child_menu)
{
m_frameMenuBar->Show( false );
if (visible_child_menu)
{
m_frameMenuBar->Show( false );
- m_frameMenuBar->UnsetInvokingWindow( this );
+ m_frameMenuBar->Detach();
}
else
{
m_frameMenuBar->Show( true );
}
else
{
m_frameMenuBar->Show( true );
- m_frameMenuBar->SetInvokingWindow( this );
+ m_frameMenuBar->Attach( this );
if (handler && handler->SafelyProcessEvent(event))
return;
if (handler && handler->SafelyProcessEvent(event))
return;
- wxWindow *win = menu->GetInvokingWindow();
- if (win)
- win->HandleWindowEvent( event );
+ wxWindow *win = menu->GetWindow();
+ wxCHECK_RET( win, "event for a menu without associated window?" );
+
+ win->HandleWindowEvent( event );
}
//-----------------------------------------------------------------------------
}
//-----------------------------------------------------------------------------
void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long style)
{
void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long style)
{
- m_invokingWindow = NULL;
-
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
// Hildon window uses a single menu instead of a menu bar, so wxMenuBar is
// the same as menu in this case
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
// Hildon window uses a single menu instead of a menu bar, so wxMenuBar is
// the same as menu in this case
Init(0, NULL, NULL, 0);
}
Init(0, NULL, NULL, 0);
}
-static void
-wxMenubarUnsetInvokingWindow(wxMenu* menu, wxWindow* win, GtkWindow* tlw = NULL)
+// recursive helpers for wxMenuBar::Attach() and Detach(): they are called to
+// associate the menus with the frame they belong to or dissociate them from it
+namespace
- menu->SetInvokingWindow( NULL );
+void
+DetachFromFrame(wxMenu* menu, wxFrame* frame)
+{
// support for native hot keys
if (menu->m_accel)
{
// support for native hot keys
if (menu->m_accel)
{
- if (tlw == NULL)
- tlw = GTK_WINDOW(wxGetTopLevelParent(win)->m_widget);
+ // Note that wxGetTopLevelParent() is really needed because this frame
+ // can be an MDI child frame which is a fake frame and not a TLW at all
+ GtkWindow * const tlw = GTK_WINDOW(wxGetTopLevelParent(frame)->m_widget);
if (g_slist_find(menu->m_accel->acceleratables, tlw))
gtk_window_remove_accel_group(tlw, menu->m_accel);
}
if (g_slist_find(menu->m_accel->acceleratables, tlw))
gtk_window_remove_accel_group(tlw, menu->m_accel);
}
{
wxMenuItem *menuitem = node->GetData();
if (menuitem->IsSubMenu())
{
wxMenuItem *menuitem = node->GetData();
if (menuitem->IsSubMenu())
- wxMenubarUnsetInvokingWindow(menuitem->GetSubMenu(), win, tlw);
+ DetachFromFrame(menuitem->GetSubMenu(), frame);
node = node->GetNext();
}
}
node = node->GetNext();
}
}
-static void
-wxMenubarSetInvokingWindow(wxMenu* menu, wxWindow* win, GtkWindow* tlw = NULL)
+void
+AttachToFrame(wxMenu* menu, wxFrame* frame)
- menu->SetInvokingWindow( win );
-
// support for native hot keys
if (menu->m_accel)
{
// support for native hot keys
if (menu->m_accel)
{
- if (tlw == NULL)
- tlw = GTK_WINDOW(wxGetTopLevelParent(win)->m_widget);
+ GtkWindow * const tlw = GTK_WINDOW(wxGetTopLevelParent(frame)->m_widget);
if (!g_slist_find(menu->m_accel->acceleratables, tlw))
gtk_window_add_accel_group(tlw, menu->m_accel);
}
if (!g_slist_find(menu->m_accel->acceleratables, tlw))
gtk_window_add_accel_group(tlw, menu->m_accel);
}
{
wxMenuItem *menuitem = node->GetData();
if (menuitem->IsSubMenu())
{
wxMenuItem *menuitem = node->GetData();
if (menuitem->IsSubMenu())
- wxMenubarSetInvokingWindow(menuitem->GetSubMenu(), win, tlw);
+ AttachToFrame(menuitem->GetSubMenu(), frame);
node = node->GetNext();
}
}
node = node->GetNext();
}
}
-void wxMenuBar::SetInvokingWindow( wxWindow *win )
-{
- m_invokingWindow = win;
-
- wxMenuList::compatibility_iterator node = m_menus.GetFirst();
- while (node)
- {
- wxMenu *menu = node->GetData();
- wxMenubarSetInvokingWindow( menu, win );
- node = node->GetNext();
- }
-}
+} // anonymous namespace
void wxMenuBar::SetLayoutDirection(wxLayoutDirection dir)
{
void wxMenuBar::SetLayoutDirection(wxLayoutDirection dir)
{
{
wxMenuBarBase::Attach(frame);
{
wxMenuBarBase::Attach(frame);
+ wxMenuList::compatibility_iterator node = m_menus.GetFirst();
+ while (node)
+ {
+ wxMenu *menu = node->GetData();
+ AttachToFrame( menu, frame );
+ node = node->GetNext();
+ }
+
SetLayoutDirection(wxLayout_Default);
}
SetLayoutDirection(wxLayout_Default);
}
-void wxMenuBar::UnsetInvokingWindow( wxWindow *win )
+void wxMenuBar::Detach()
- m_invokingWindow = NULL;
-
wxMenuList::compatibility_iterator node = m_menus.GetFirst();
while (node)
{
wxMenu *menu = node->GetData();
wxMenuList::compatibility_iterator node = m_menus.GetFirst();
while (node)
{
wxMenu *menu = node->GetData();
- wxMenubarUnsetInvokingWindow( menu, win );
+ DetachFromFrame( menu, m_menuBarFrame );
node = node->GetNext();
}
node = node->GetNext();
}
+
+ wxMenuBarBase::Detach();
}
bool wxMenuBar::Append( wxMenu *menu, const wxString &title )
}
bool wxMenuBar::Append( wxMenu *menu, const wxString &title )
else
gtk_menu_shell_insert( GTK_MENU_SHELL(m_menubar), menu->m_owner, pos );
else
gtk_menu_shell_insert( GTK_MENU_SHELL(m_menubar), menu->m_owner, pos );
- // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
- // addings menu later on.
- if (m_invokingWindow)
- wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+ if ( m_menuBarFrame )
+ AttachToFrame( menu, m_menuBarFrame );
gtk_widget_destroy( menu->m_owner );
menu->m_owner = NULL;
gtk_widget_destroy( menu->m_owner );
menu->m_owner = NULL;
- if (m_invokingWindow)
- wxMenubarUnsetInvokingWindow( menu, m_invokingWindow );
+ DetachFromFrame( menu, m_menuBarFrame );
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), mitem->GetSubMenu()->m_menu );
gtk_widget_show( mitem->GetSubMenu()->m_menu );
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), mitem->GetSubMenu()->m_menu );
gtk_widget_show( mitem->GetSubMenu()->m_menu );
-
- // if adding a submenu to a menu already existing in the menu bar, we
- // must set invoking window to allow processing events from this
- // submenu
- if ( m_invokingWindow )
- wxMenubarSetInvokingWindow(mitem->GetSubMenu(), m_invokingWindow);