#include "wx/stockitem.h"
#include "wx/gtk/private.h"
-#ifdef __WXGTK20__
-#include <gdk/gdktypes.h>
-#endif
-
// FIXME: is this right? somehow I don't think so (VZ)
#define gtk_accel_group_attach(g, o) gtk_window_add_accel_group((o), (g))
-//#define gtk_accel_group_detach(g, o) gtk_window_remove_accel_group((o), (g))
+#define gtk_accel_group_detach(g, o) gtk_window_remove_accel_group((o), (g))
//#define gtk_menu_ensure_uline_accel_group(m) gtk_menu_get_accel_group(m)
#define ACCEL_OBJECT GtkWindow
extern "C" {
-static void gtk_menu_open_callback( GtkWidget *widget, wxMenu *menu )
+static void
+gtk_menu_open_callback(GtkWidget * WXUNUSED(widget), wxMenu *menu)
{
wxMenuEvent event(wxEVT_MENU_OPEN, -1, menu);
DoCommonMenuCallbackCode(menu, event);
}
-static void gtk_menu_close_callback( GtkWidget *widget, wxMenuBar *menubar )
+static void
+gtk_menu_close_callback(GtkWidget * WXUNUSED(widget), wxMenuBar *menubar)
{
if ( !menubar->GetMenuCount() )
{
while (top_frame->GetParent() && !(top_frame->IsTopLevel()))
top_frame = top_frame->GetParent();
+ // support for native hot keys
+ ACCEL_OBJECT *obj = ACCEL_OBJ_CAST(top_frame->m_widget);
+ if ( menu->m_accel && g_slist_find( ACCEL_OBJECTS(menu->m_accel), obj ) )
+ gtk_accel_group_detach( menu->m_accel, obj );
+
wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
while (node)
{
// m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
// addings menu later on.
if (m_invokingWindow)
- {
wxMenubarSetInvokingWindow( menu, m_invokingWindow );
- // OPTIMISE ME: we should probably cache this, or pass it
- // directly, but for now this is a minimal
- // change to validate the new dynamic sizing.
- // see (and refactor :) similar code in Remove
- // below.
-
- wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame );
-
- if( frame )
- frame->UpdateMenuBarSize();
- }
-
return true;
}
menu->m_owner = NULL;
if (m_invokingWindow)
- {
- // OPTIMISE ME: see comment in GtkAppend
- wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame );
-
- if( frame )
- frame->UpdateMenuBarSize();
- }
+ wxMenubarUnsetInvokingWindow( menu, m_invokingWindow );
return menu;
}
commandEvent.SetEventObject(frame);
if (item->IsCheckable())
commandEvent.SetInt(item->IsChecked());
- commandEvent.SetEventObject(menu);
frame->GetEventHandler()->ProcessEvent(commandEvent);
}
wxString wxMenuItem::GetItemLabel() const
{
- return wxConvertFromGTKToWXLabel(m_text);
+ wxString label = wxConvertFromGTKToWXLabel(m_text);
+ if (!m_hotKey.IsEmpty())
+ label = label + wxT("\t") + m_hotKey;
+ return label;
}
void wxMenuItem::SetItemLabel( const wxString& str )
wxMenu::~wxMenu()
{
- WX_CLEAR_LIST(wxMenuItemList, m_items);
-
if ( GTK_IS_WIDGET( m_menu ))
{
// see wxMenu::Init
if ( m_owner )
gtk_widget_destroy( m_menu );
}
+
+ // This must come after we release GTK resources above. Otherwise, GTK will
+ // give warnings/errors when attempting to free accelerator resources from
+ // child items that just were destroyed (the m_menu widget can contain
+ // references to accelerators in child items. Problem detected when removing
+ // a menu from a wxMenuBar, and the removed menu had submenus with accelerators.)
+ WX_CLEAR_LIST(wxMenuItemList, m_items);
}
void wxMenu::SetLayoutDirection(const wxLayoutDirection dir)