vcl/inc/unx/gtk/gloactiongroup.h | 3 vcl/inc/unx/gtk/glomenu.h | 168 +++++++++++++-------------- vcl/unx/gtk/app/gtkinst.cxx | 2 vcl/unx/gtk/window/gloactiongroup.cxx | 23 +++ vcl/unx/gtk/window/gtksalmenu.cxx | 209 +++++++++++++++++++--------------- 5 files changed, 228 insertions(+), 177 deletions(-)
New commits: commit c833b98c0a84b0aeedd5e50d3cc03047f1ece94a Author: Antonio Fernandez <antonio.fernan...@aentos.es> Date: Wed Aug 15 10:15:44 2012 +0100 Menu is now displayed properly in all windows. Change-Id: I9f8cffc3d19bb4c75c1153ff9f06fd5bab3440f6 diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h index b71ae47..431b93b 100644 --- a/vcl/inc/unx/gtk/gloactiongroup.h +++ b/vcl/inc/unx/gtk/gloactiongroup.h @@ -52,6 +52,9 @@ void g_lo_action_group_insert (GLOActionGroup void g_lo_action_group_remove (GLOActionGroup *group, const gchar *action_name); +// This function has been added to make current implementation of GtkSalMenu work. +void g_lo_action_group_clear (GLOActionGroup *group); + void g_lo_action_group_add_entries (GLOActionGroup *group, const GActionEntry *entries, gint n_entries, diff --git a/vcl/inc/unx/gtk/glomenu.h b/vcl/inc/unx/gtk/glomenu.h index 54c7b5b..db2f034 100644 --- a/vcl/inc/unx/gtk/glomenu.h +++ b/vcl/inc/unx/gtk/glomenu.h @@ -42,91 +42,91 @@ typedef struct _GLOMenuItem GLOMenuItem; typedef struct _GLOMenu GLOMenu; GLIB_AVAILABLE_IN_2_32 -GType g_lo_menu_get_type (void) G_GNUC_CONST; +GType g_lo_menu_get_type (void) G_GNUC_CONST; GLIB_AVAILABLE_IN_2_32 -GLOMenu * g_lo_menu_new (void); - -void g_lo_menu_freeze (GLOMenu *menu); - -void g_lo_menu_insert_item (GLOMenu *menu, - gint position, - GLOMenuItem *item); -void g_lo_menu_prepend_item (GLOMenu *menu, - GLOMenuItem *item); -void g_lo_menu_append_item (GLOMenu *menu, - GLOMenuItem *item); -void g_lo_menu_remove (GLOMenu *menu, - gint position); - -void g_lo_menu_insert (GLOMenu *menu, - gint position, - const gchar *label, - const gchar *detailed_action); -void g_lo_menu_prepend (GLOMenu *menu, - const gchar *label, - const gchar *detailed_action); -void g_lo_menu_append (GLOMenu *menu, - const gchar *label, - const gchar *detailed_action); - -void g_lo_menu_insert_section (GLOMenu *menu, - gint position, - const gchar *label, - GMenuModel *section); -void g_lo_menu_prepend_section (GLOMenu *menu, - const gchar *label, - GMenuModel *section); -void g_lo_menu_append_section (GLOMenu *menu, - const gchar *label, - GMenuModel *section); - -void g_lo_menu_insert_submenu (GLOMenu *menu, - gint position, - const gchar *label, - GMenuModel *submenu); -void g_lo_menu_prepend_submenu (GLOMenu *menu, - const gchar *label, - GMenuModel *submenu); -void g_lo_menu_append_submenu (GLOMenu *menu, - const gchar *label, - GMenuModel *submenu); - - -GType g_lo_menu_item_get_type (void) G_GNUC_CONST; -GLOMenuItem * g_lo_menu_item_new (const gchar *label, - const gchar *detailed_action); - -GLOMenuItem * g_lo_menu_item_new_submenu (const gchar *label, - GMenuModel *submenu); - -GLOMenuItem * g_lo_menu_item_new_section (const gchar *label, - GMenuModel *section); - -void g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item, - const gchar *attribute, - GVariant *value); -void g_lo_menu_item_set_attribute (GLOMenuItem *menu_item, - const gchar *attribute, - const gchar *format_string, - ...); -void g_lo_menu_item_set_link (GLOMenuItem *menu_item, - const gchar *link, - GMenuModel *model); -void g_lo_menu_item_set_label (GLOMenuItem *menu_item, - const gchar *label); -void g_lo_menu_item_set_submenu (GLOMenuItem *menu_item, - GMenuModel *submenu); -void g_lo_menu_item_set_section (GLOMenuItem *menu_item, - GMenuModel *section); -void g_lo_menu_item_set_action_and_target_value (GLOMenuItem *menu_item, - const gchar *action, - GVariant *target_value); -void g_lo_menu_item_set_action_and_target (GLOMenuItem *menu_item, - const gchar *action, - const gchar *format_string, - ...); -void g_lo_menu_item_set_detailed_action (GLOMenuItem *menu_item, - const gchar *detailed_action); +GLOMenu * g_lo_menu_new (void); + +void g_lo_menu_freeze (GLOMenu *menu); + +void g_lo_menu_insert_item (GLOMenu *menu, + gint position, + GLOMenuItem *item); +void g_lo_menu_prepend_item (GLOMenu *menu, + GLOMenuItem *item); +void g_lo_menu_append_item (GLOMenu *menu, + GLOMenuItem *item); +void g_lo_menu_remove (GLOMenu *menu, + gint position); + +void g_lo_menu_insert (GLOMenu *menu, + gint position, + const gchar *label, + const gchar *detailed_action); +void g_lo_menu_prepend (GLOMenu *menu, + const gchar *label, + const gchar *detailed_action); +void g_lo_menu_append (GLOMenu *menu, + const gchar *label, + const gchar *detailed_action); + +void g_lo_menu_insert_section (GLOMenu *menu, + gint position, + const gchar *label, + GMenuModel *section); +void g_lo_menu_prepend_section (GLOMenu *menu, + const gchar *label, + GMenuModel *section); +void g_lo_menu_append_section (GLOMenu *menu, + const gchar *label, + GMenuModel *section); + +void g_lo_menu_insert_submenu (GLOMenu *menu, + gint position, + const gchar *label, + GMenuModel *submenu); +void g_lo_menu_prepend_submenu (GLOMenu *menu, + const gchar *label, + GMenuModel *submenu); +void g_lo_menu_append_submenu (GLOMenu *menu, + const gchar *label, + GMenuModel *submenu); + + +GType g_lo_menu_item_get_type (void) G_GNUC_CONST; +GLOMenuItem * g_lo_menu_item_new (const gchar *label, + const gchar *detailed_action); + +GLOMenuItem * g_lo_menu_item_new_submenu (const gchar *label, + GMenuModel *submenu); + +GLOMenuItem * g_lo_menu_item_new_section (const gchar *label, + GMenuModel *section); + +void g_lo_menu_item_set_attribute_value (GLOMenuItem *menu_item, + const gchar *attribute, + GVariant *value); +void g_lo_menu_item_set_attribute (GLOMenuItem *menu_item, + const gchar *attribute, + const gchar *format_string, + ...); +void g_lo_menu_item_set_link (GLOMenuItem *menu_item, + const gchar *link, + GMenuModel *model); +void g_lo_menu_item_set_label (GLOMenuItem *menu_item, + const gchar *label); +void g_lo_menu_item_set_submenu (GLOMenuItem *menu_item, + GMenuModel *submenu); +void g_lo_menu_item_set_section (GLOMenuItem *menu_item, + GMenuModel *section); +void g_lo_menu_item_set_action_and_target_value (GLOMenuItem *menu_item, + const gchar *action, + GVariant *target_value); +void g_lo_menu_item_set_action_and_target (GLOMenuItem *menu_item, + const gchar *action, + const gchar *format_string, + ...); +void g_lo_menu_item_set_detailed_action (GLOMenuItem *menu_item, + const gchar *detailed_action); G_END_DECLS diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx index 3239ad7..2e00b34 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -531,7 +531,7 @@ void GtkInstance::DestroyMenu( SalMenu* pMenu ) { (void)pMenu; delete pMenu; - OSL_ENSURE( pMenu == 0, "DestroyMenu called with non-native menus" ); +// OSL_ENSURE( pMenu == 0, "DestroyMenu called with non-native menus" ); } SalMenuItem* GtkInstance::CreateMenuItem( const SalItemParams* pItemData ) diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx index b728e4a..4e99712 100644 --- a/vcl/unx/gtk/window/gloactiongroup.cxx +++ b/vcl/unx/gtk/window/gloactiongroup.cxx @@ -290,6 +290,29 @@ g_lo_action_group_remove (GLOActionGroup *group, g_action_map_remove_action (G_ACTION_MAP (group), action_name); } +// This function has been added to make current implementation of GtkSalMenu work. +void +g_lo_action_group_clear (GLOActionGroup *group) +{ + g_return_if_fail (G_IS_LO_ACTION_GROUP (group)); + + GAction *action; + + GList* keys = g_hash_table_get_keys(group->priv->table); + + for ( GList* list = g_list_first(keys); list; list = g_list_next(list)) { + gchar* action_name = (gchar*) list->data; + action = G_ACTION( g_hash_table_lookup (group->priv->table, action_name) ); + + if (action != NULL) + { + g_action_group_action_removed (G_ACTION_GROUP (group), action_name); + g_lo_action_group_disconnect (NULL, action, group); + g_hash_table_remove (group->priv->table, action_name); + } + } +} + void g_lo_action_group_add_entries (GLOActionGroup *group, const GActionEntry *entries, diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index a3812d7..b66d4d1 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -90,7 +90,7 @@ dispatchAction (GSimpleAction *action, void generateActions( GtkSalMenu* pMenu, GLOActionGroup* pActionGroup ) { - if ( !pMenu || !pMenu->GetMenuModel() ) + if ( !pMenu || !pActionGroup ) return; for (sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++) { @@ -104,6 +104,54 @@ void generateActions( GtkSalMenu* pMenu, GLOActionGroup* pActionGroup ) } } +void updateNativeMenu( GtkSalMenu* pMenu ) { + if ( pMenu ) { + for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { + GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); + String aText = pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ); + + // Force updating of native menu labels. + pMenu->SetItemText( i, pSalMenuItem, aText ); + + if ( pSalMenuItem->mpSubMenu && pSalMenuItem->mpSubMenu->GetMenu() ) { + pSalMenuItem->mpSubMenu->GetMenu()->Activate(); + updateNativeMenu( pSalMenuItem->mpSubMenu ); + } + } + } +} + +void updateSpecialMenus( GtkSalMenu *pMenu ) { + if ( pMenu ) { + for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { + GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); + + rtl::OUString aCommand = pSalMenuItem->mpVCLMenu->GetItemCommand( pSalMenuItem->mnId ); + + if ( isSpecialSubmenu( aCommand ) ) { + updateNativeMenu( pSalMenuItem->mpSubMenu ); + } + + updateSpecialMenus( pSalMenuItem->mpSubMenu ); + } + } +} + +gboolean GenerateMenu(gpointer user_data) { + GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data ); + + // We only update special menus periodically. + updateSpecialMenus( pSalMenu ); + + return TRUE; +} + +void ObjectDestroyedNotify( gpointer data ) { + if ( data ) { + g_object_unref( data ); + } +} + void gdk_x11_window_set_utf8_property (GdkWindow *window, const gchar *name, @@ -132,6 +180,10 @@ gdk_x11_window_set_utf8_property (GdkWindow *window, } } +/* + * GtkSalMenu + */ + void GtkSalMenu::publishMenu( GMenuModel *pMenu, GActionGroup *pActionGroup ) { if ( mMenubarId ) { @@ -187,19 +239,20 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) : pSessionBus( NULL ), mMenubarId( 0 ), mActionGroupId ( 0 ), + mpMenuModel( NULL ), mpActionGroup( NULL ) { mpCurrentSection = G_MENU_MODEL( g_lo_menu_new() ); maSections.push_back( mpCurrentSection ); - mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); - g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); - if (bMenuBar) { - mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() ); +// mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() ); pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if(!pSessionBus) puts ("Fail bus get"); + } else { + mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); + g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); } } @@ -207,30 +260,17 @@ GtkSalMenu::~GtkSalMenu() { g_source_remove_by_user_data( this ); - // FIXME: Not sure if we need to unset X Properties. - if ( mpFrame ) { - GtkWidget *widget = GTK_WIDGET( mpFrame->getWindow() ); - GdkWindow *gdkWindow = gtk_widget_get_window( widget ); - if (gdkWindow) { - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", NULL ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", NULL ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", NULL ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", NULL ); - } - } - - if ( mMenubarId ) { - g_dbus_connection_unexport_menu_model( pSessionBus, mMenubarId ); - mMenubarId = 0; - } + g_object_unref( mpCurrentSection ); - if ( mActionGroupId ) { - g_dbus_connection_unexport_action_group( pSessionBus, mActionGroupId ); - mActionGroupId = 0; + if ( mbMenuBar ) { + g_lo_menu_remove( G_LO_MENU( mpMenuModel ), 0 ); + mpMenuModel = NULL; + } else { + g_object_unref( mpMenuModel ); } - if ( pSessionBus ) { - g_dbus_connection_flush_sync( pSessionBus, NULL, NULL ); + if ( mpActionGroup ) { + g_lo_action_group_clear( G_LO_ACTION_GROUP( mpActionGroup ) ); } pSessionBus = NULL; @@ -240,13 +280,6 @@ GtkSalMenu::~GtkSalMenu() maSections.clear(); maItems.clear(); - - g_object_unref( mpMenuModel ); - g_object_unref( mpCurrentSection ); - - if ( mpActionGroup ) { - g_object_unref( mpActionGroup ); - } } sal_Bool GtkSalMenu::VisibleMenuBar() @@ -269,7 +302,10 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) // If no mpMenuItem exists, then item is a separator. mpCurrentSection = G_MENU_MODEL( g_lo_menu_new() ); maSections.push_back( mpCurrentSection ); - g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); + + if ( mpMenuModel ) { + g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); + } } pGtkSalMenuItem->mpParentMenu = this; @@ -301,34 +337,6 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig } } -void updateNativeMenu( GtkSalMenu* pMenu ); - -void updateSpecialMenus( GtkSalMenu *pMenu ) { - if ( pMenu ) { - for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { - GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); - - rtl::OUString aCommand = pSalMenuItem->mpVCLMenu->GetItemCommand( pSalMenuItem->mnId ); - - if ( isSpecialSubmenu( aCommand ) ) { - updateNativeMenu( pSalMenuItem->mpSubMenu ); - } - - updateSpecialMenus( pSalMenuItem->mpSubMenu ); - } - } -} - -gboolean GenerateMenu(gpointer user_data) { - cout << "Generating menu..." << endl; - GtkSalMenu* pSalMenu = static_cast< GtkSalMenu* >( user_data ); -// updateNativeMenu( pSalMenu ); - updateSpecialMenus( pSalMenu ); - - return TRUE; -} - - void GtkSalMenu::SetFrame( const SalFrame* pFrame ) { mpFrame = static_cast<const GtkSalFrame*>( pFrame ); @@ -338,19 +346,40 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) GdkWindow *gdkWindow = gtk_widget_get_window( widget ); if (gdkWindow) { - XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow ); + gpointer pMenu = g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ); + gpointer pActionGroup = g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-action-group" ); + + if ( pMenu && pActionGroup ) { + mpMenuModel = G_MENU_MODEL( pMenu ); + mpActionGroup = G_ACTION_GROUP( pActionGroup ); + } else { + mpMenuModel = G_MENU_MODEL( g_lo_menu_new() ); + mpActionGroup = G_ACTION_GROUP( g_lo_action_group_new() ); - aDBusPath = g_strdup_printf("/window/%lu", windowId); - gchar* aDBusWindowPath = g_strdup_printf( "/window/%lu", windowId ); - aDBusMenubarPath = g_strdup_printf( "/window/%lu/menus/menubar", windowId ); + g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", mpMenuModel, ObjectDestroyedNotify ); + g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", mpActionGroup, ObjectDestroyedNotify ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "" ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath ); - gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); + XLIB_Window windowId = GDK_WINDOW_XID( gdkWindow ); - // Publish the menu. - this->publishMenu( mpMenuModel, mpActionGroup ); + aDBusPath = g_strdup_printf("/window/%lu", windowId); + gchar* aDBusWindowPath = g_strdup_printf( "/window/%lu", windowId ); + aDBusMenubarPath = g_strdup_printf( "/window/%lu/menus/menubar", windowId ); + + gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) ); + gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "" ); + gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath ); + gdk_x11_window_set_utf8_property ( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); + + g_free( aDBusWindowPath ); + + // Publish the menu. + publishMenu( mpMenuModel, mpActionGroup ); + } + + g_lo_menu_append_section( G_LO_MENU( mpMenuModel ), NULL, mpCurrentSection ); + + updateNativeMenu( this ); + generateActions( this, G_LO_ACTION_GROUP( mpActionGroup ) ); // Refresh the menu every second. // This code is a workaround until required modifications in Gtk+ are available. @@ -392,11 +421,23 @@ void GtkSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const rt GLOMenuItem *pMenuItem = G_LO_MENU_ITEM( pGtkSalMenuItem->mpMenuItem ); - g_lo_menu_item_set_label( pMenuItem, aConvertedText.getStr() ); + GVariant* aCurrentLabel = g_menu_model_get_item_attribute_value( pGtkSalMenuItem->mpParentSection, pGtkSalMenuItem->mnPos, G_MENU_ATTRIBUTE_LABEL, G_VARIANT_TYPE_STRING ); + + sal_Bool bSetLabel = sal_True; - if ( pGtkSalMenuItem->mpParentSection ) { - g_lo_menu_remove( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos ); - g_lo_menu_insert_item( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem ); + if ( aCurrentLabel ) { + if ( g_strcmp0( g_variant_get_string( aCurrentLabel, NULL ), aConvertedText.getStr() ) == 0 ) { + bSetLabel = sal_False; + } + } + + if ( bSetLabel == sal_True ) { + g_lo_menu_item_set_label( pMenuItem, aConvertedText.getStr() ); + + if ( pGtkSalMenuItem->mpParentSection ) { + g_lo_menu_remove( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos ); + g_lo_menu_insert_item( G_LO_MENU( pGtkSalMenuItem->mpParentSection ), pGtkSalMenuItem->mnPos, pGtkSalMenuItem->mpMenuItem ); + } } } @@ -442,22 +483,6 @@ void GtkSalMenu::GetSystemMenuData( SystemMenuData* pData ) { } -void updateNativeMenu( GtkSalMenu* pMenu ) { - if ( pMenu ) { - for ( sal_uInt16 i = 0; i < pMenu->GetItemCount(); i++ ) { - GtkSalMenuItem* pSalMenuItem = pMenu->GetItemAtPos( i ); - String aText = pSalMenuItem->mpVCLMenu->GetItemText( pSalMenuItem->mnId ); - - // Force updating of native menu labels. - pMenu->SetItemText( i, pSalMenuItem, aText ); - - if ( pSalMenuItem->mpSubMenu && pSalMenuItem->mpSubMenu->GetMenu() ) { - pSalMenuItem->mpSubMenu->GetMenu()->Activate(); - updateNativeMenu( pSalMenuItem->mpSubMenu ); - } - } - } -} void GtkSalMenu::Freeze() { updateNativeMenu( this ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits