static void cinnamon_app_system_init (CinnamonAppSystem *self) { CinnamonAppSystemPrivate *priv; self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self, CINNAMON_TYPE_APP_SYSTEM, CinnamonAppSystemPrivate); priv->running_apps = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL); priv->id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_object_unref); priv->setting_id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_object_unref); /* For now, we want to pick up Evince, Nautilus, etc. We'll * handle NODISPLAY semantics at a higher level or investigate them * case by case. */ priv->apps_tree = gmenu_tree_new ("cinnamon-applications.menu", GMENU_TREE_FLAGS_INCLUDE_NODISPLAY); g_signal_connect (priv->apps_tree, "changed", G_CALLBACK (on_apps_tree_changed_cb), self); priv->settings_tree = gmenu_tree_new ("cinnamon-settings.menu", 0); g_signal_connect (priv->settings_tree, "changed", G_CALLBACK (on_settings_tree_changed_cb), self); on_apps_tree_changed_cb (priv->apps_tree, self); on_settings_tree_changed_cb (priv->settings_tree, self); }
static void shell_app_system_init (ShellAppSystem *self) { ShellAppSystemPrivate *priv; self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SHELL_TYPE_APP_SYSTEM, ShellAppSystemPrivate); priv->running_apps = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL); priv->id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_object_unref); /* All the objects in this hash table are owned by id_to_app */ priv->visible_id_to_app = g_hash_table_new (g_str_hash, g_str_equal); priv->setting_id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_object_unref); /* We want to track NoDisplay apps, so we add INCLUDE_NODISPLAY. We'll * filter NoDisplay apps out when showing them to the user. */ priv->apps_tree = gmenu_tree_new ("applications.menu", GMENU_TREE_FLAGS_INCLUDE_NODISPLAY); g_signal_connect (priv->apps_tree, "changed", G_CALLBACK (on_apps_tree_changed_cb), self); priv->settings_tree = gmenu_tree_new ("gnomecc.menu", 0); g_signal_connect (priv->settings_tree, "changed", G_CALLBACK (on_settings_tree_changed_cb), self); on_apps_tree_changed_cb (priv->apps_tree, self); on_settings_tree_changed_cb (priv->settings_tree, self); }
static void cinnamon_app_system_init (CinnamonAppSystem *self) { CinnamonAppSystemPrivate *priv; self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self, CINNAMON_TYPE_APP_SYSTEM, CinnamonAppSystemPrivate); priv->running_apps = g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL); priv->id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_object_unref); /* According to desktop spec, since our menu file is called 'cinnamon-applications', our * merged menu folders need to be called 'cinnamon-applications-merged'. We'll setup the folder * 'applications-merged' if it doesn't exist yet, and a symlink pointing to it in the * ~/.config/menus directory */ setup_merge_dir_symlink(); /* For now, we want to pick up Evince, Nemo, etc. We'll * handle NODISPLAY semantics at a higher level or investigate them * case by case. */ priv->apps_tree = gmenu_tree_new ("cinnamon-applications.menu", GMENU_TREE_FLAGS_INCLUDE_NODISPLAY); g_signal_connect (priv->apps_tree, "changed", G_CALLBACK (on_apps_tree_changed_cb), self); on_apps_tree_changed_cb (priv->apps_tree, self); }
GtkWidget *elsa_launcher_new() { GtkWidget *icon = NULL; GMenuTree *tree = NULL; icon = gtk_image_new_from_icon_name("start-here", GTK_ICON_SIZE_LARGE_TOOLBAR); gtk_image_set_pixel_size(GTK_IMAGE(icon), 24); eventbox = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(eventbox), icon); tree = gmenu_tree_new("gnome-applications.menu", 0); if (!tree) return eventbox; g_object_connect(G_OBJECT(tree), "signal::changed", G_CALLBACK(menu_tree_changed), NULL, NULL); g_object_connect(G_OBJECT(eventbox), "signal::button-press-event", G_CALLBACK(elsa_launcher_button_press), NULL, NULL); menu_tree_changed(tree, NULL); return eventbox; }
static void setup_model (GnomeControlCenter *shell) { GnomeControlCenterPrivate *priv = shell->priv; gtk_widget_set_margin_top (shell->priv->main_vbox, 8); gtk_widget_set_margin_bottom (shell->priv->main_vbox, 8); gtk_widget_set_margin_left (shell->priv->main_vbox, 12); gtk_widget_set_margin_right (shell->priv->main_vbox, 12); gtk_container_set_focus_vadjustment (GTK_CONTAINER (shell->priv->main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (shell->priv->scrolled_window))); priv->store = (GtkListStore *) cc_shell_model_new (); priv->category_views = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->menu_tree = gmenu_tree_new ("YaST-gnome.menu", 0); reload_menu (shell); g_signal_connect (priv->menu_tree, "changed", G_CALLBACK (on_menu_changed), shell); }
int main() { auto tree=gmenu_tree_new(menu_name, GMENU_TREE_FLAGS_NONE); //no need flags, defaults is good enough { char lang[locale_size]; //here we get system locale string strcpy(lang,getenv("LANG")); char* country=0; //and parse it to 3 strings - lang, country, modifier char* modifier=0; //char* enc=0; //it could be useful somewhere else. let it be commented for(int i=0;lang[i];++i){ switch(lang[i]){ case '_': lang[i]=0; country=lang+i+1; break; case '@': lang[i]=0; modifier=lang+i+1; break; case '.': lang[i]=0; //enc=lang+i+1; break; } } { int loc_i=0; //current locale index if(*lang&&country&&modifier){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"_"+country+"@"+modifier+"]").c_str()); } if(*lang&&country){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"_"+country+"]").c_str()); } if(*lang&&modifier){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"@"+modifier+"]").c_str()); } if(*lang){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"]").c_str()); } locales[loc_i+1][0]=0; //barier to stop in case of buggy .desktop entry } } while(!gmenu_tree_load_sync(tree,NULL)){ //wait for load usleep(sync_wait_time); } qu.push(gmenu_tree_get_root_directory(tree)); //push root menu dir in queue while(!qu.empty()){ //while queue not empty, create menu for first dir auto& dir=qu.front(); { const char* name=gmenu_tree_directory_get_menu_id(dir); //menu id used as unique fvwm menu suffix printf("DestroyMenu \"FvwmMenu%s\"\n",name); printf("AddToMenu \"FvwmMenu%s\"\n",name); } auto it=gmenu_tree_directory_iter(dir); //iterator decltype(gmenu_tree_iter_next(it)) next_type; //iterator type while ((next_type=gmenu_tree_iter_next(it))!=GMENU_TREE_ITEM_INVALID){ switch (next_type){ case GMENU_TREE_ITEM_DIRECTORY:{ //add directory function popup and queue it auto cur=gmenu_tree_iter_get_directory(it); printf("+ \"%s\" Popup \"FvwmMenu%s\"\n", gmenu_tree_directory_get_name(cur), gmenu_tree_directory_get_menu_id(cur)); qu.push(cur); break; } case GMENU_TREE_ITEM_ENTRY:{ auto cur=gmenu_tree_iter_get_entry(it); auto inf=gmenu_tree_entry_get_app_info(cur); std::string exec=g_desktop_app_info_get_string(inf,"Exec"); //get exec command int index; while((index=exec.find('%'))!=-1){ //delete all % params exec.erase(index,2); } int loc_i=0; char* name=0; do{ //find localised name in standard specified order name=g_desktop_app_info_get_string(inf,locales[loc_i]); ++loc_i; }while(!name&&locales[loc_i][0]); if(name){ //if name not empty printf("+ \"%s\" Exec exec %s\n",name,exec.c_str()); //add menu entry } break; } case GMENU_TREE_ITEM_SEPARATOR:{ //add empty menu entry printf("+ \"\" Nop"); } default:{ //TODO: add other types if needed } } } gmenu_tree_iter_unref(it); //unref iterator (dunno why, but why not?) printf("\n"); //just for better readability qu.pop(); } return 0; }
GtkWidget * create_applications_menu (const char *menu_file, const char *menu_path, gboolean always_show_image) { GMenuTree *tree; GtkWidget *menu; guint idle_id; GError *error = NULL; menu = create_empty_menu (); if (always_show_image) g_object_set_data (G_OBJECT (menu), "panel-menu-force-icon-for-categories", GINT_TO_POINTER (TRUE)); tree = gmenu_tree_new (menu_file, GMENU_TREE_FLAGS_SORT_DISPLAY_NAME); if (!gmenu_tree_load_sync (tree, &error)) { g_warning ("Failed to load applications: %s", error->message); g_clear_error (&error); return menu; } g_object_set_data_full (G_OBJECT (menu), "panel-menu-tree", g_object_ref (tree), (GDestroyNotify) g_object_unref); g_object_set_data_full (G_OBJECT (menu), "panel-menu-tree-path", g_strdup (menu_path ? menu_path : "/"), (GDestroyNotify) g_free); g_object_set_data (G_OBJECT (menu), "panel-menu-needs-loading", GUINT_TO_POINTER (TRUE)); g_signal_connect (menu, "show", G_CALLBACK (submenu_to_display), NULL); idle_id = g_idle_add_full (G_PRIORITY_LOW, submenu_to_display_in_idle, menu, NULL); g_object_set_data_full (G_OBJECT (menu), "panel-menu-idle-id", GUINT_TO_POINTER (idle_id), remove_submenu_to_display_idle); g_signal_connect (menu, "button_press_event", G_CALLBACK (menu_dummy_button_press_event), NULL); g_signal_connect (tree, "changed", G_CALLBACK (handle_gmenu_tree_changed), menu); g_signal_connect (menu, "destroy", G_CALLBACK (remove_gmenu_tree_monitor), tree); g_object_unref (tree); return menu; }