/** * cinnamon_app_get_app_info: * @app: a #CinnamonApp * * Returns: (transfer none): The #GDesktopAppInfo for this app, or %NULL if backed by a window */ GDesktopAppInfo * cinnamon_app_get_app_info (CinnamonApp *app) { if (app->entry) return gmenu_tree_entry_get_app_info (app->entry); return NULL; }
const char * cinnamon_app_get_keywords (CinnamonApp *app) { const char * const *keywords; const char *keyword; gint i; gchar *ret = NULL; if (app->keywords) return app->keywords; if (app->entry) keywords = g_desktop_app_info_get_keywords (G_DESKTOP_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); else keywords = NULL; if (keywords != NULL) { GString *keyword_list = g_string_new(NULL); for (i = 0; keywords[i] != NULL; i++) { keyword = keywords[i]; g_string_append_printf (keyword_list, "%s;", keyword); } ret = g_string_free (keyword_list, FALSE); } app->keywords = ret; return ret; }
/** * cinnamon_app_create_icon_texture: * * Look up the icon for this application, and create a #ClutterTexture * for it at the given size. * * Return value: (transfer none): A floating #ClutterActor */ ClutterActor * cinnamon_app_create_icon_texture (CinnamonApp *app, int size) { GIcon *icon; ClutterActor *ret; ret = NULL; if (app->entry == NULL) return window_backed_app_get_icon (app, size); icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); if (icon != NULL) ret = st_texture_cache_load_gicon (st_texture_cache_get_default (), NULL, icon, size); if (ret == NULL) { icon = g_themed_icon_new ("application-x-executable"); ret = st_texture_cache_load_gicon (st_texture_cache_get_default (), NULL, icon, size); g_object_unref (icon); } return ret; }
const char * cinnamon_app_get_description (CinnamonApp *app) { if (app->entry) return g_app_info_get_description (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); else return NULL; }
static GList * xde_entry(MenuContext *ctx, GMenuTreeEntry *ent) { GDesktopAppInfo *info; GList *text = NULL, *acts; const char *name; char *esc1, *esc2, *cmd, *p; char *s, *icon = NULL; GIcon *gicon = NULL; char *appid; if (!(info = gmenu_tree_entry_get_app_info(ent)) || g_desktop_app_info_get_is_hidden(info) || g_desktop_app_info_get_nodisplay(info) || !g_desktop_app_info_get_show_in(info, NULL) || !g_app_info_should_show(G_APP_INFO(info))) return (text); name = g_app_info_get_name(G_APP_INFO(info)); esc1 = xde_character_escape(name, ')'); if ((appid = strdup(gmenu_tree_entry_get_desktop_file_id(ent))) && (p = strstr(appid, ".desktop"))) *p = '\0'; if (ctx->stack) gicon = gmenu_tree_directory_get_icon(ctx->stack->data); icon = xde_get_app_icon(ctx, info, gicon, "exec", "unknown", GET_ENTRY_ICON_FLAG_XPM | GET_ENTRY_ICON_FLAG_PNG | GET_ENTRY_ICON_FLAG_JPG | GET_ENTRY_ICON_FLAG_SVG); if (options.launch) { cmd = g_strdup_printf("xdg-launch --pointer %s", appid); } else { cmd = xde_get_command(info, appid, icon); } esc2 = xde_character_escape(cmd, '}'); icon = ctx->wmm.wrap(ctx, icon); if (options.actions && (acts = ctx->wmm.ops.actions(ctx, ent, info))) { xde_increase_indent(ctx); s = g_strdup_printf("%s[exec] (%s) {%s}%s\n", ctx->indent, esc1, esc2, icon); xde_decrease_indent(ctx); acts = g_list_prepend(acts, s); s = g_strdup_printf("%s[submenu] (%s) {%s}%s\n", ctx->indent, esc1, esc1, icon); acts = g_list_prepend(acts, s); s = g_strdup_printf("%s[end]\n", ctx->indent); acts = g_list_append(acts, s); text = g_list_concat(text, acts); } else { s = g_strdup_printf("%s[exec] (%s) {%s}%s\n", ctx->indent, esc1, esc2, icon); text = g_list_append(text, s); } free(icon); free(appid); free(esc1); free(esc2); free(cmd); return (text); }
/** * cinnamon_app_launch: * @timestamp: Event timestamp, or 0 for current event timestamp * @uris: (element-type utf8): List of uris to pass to application * @workspace: Start on this workspace, or -1 for default * @startup_id: (out): Returned startup notification ID, or %NULL if none * @error: A #GError */ gboolean cinnamon_app_launch (CinnamonApp *app, guint timestamp, GList *uris, int workspace, char **startup_id, GError **error) { GDesktopAppInfo *gapp; GdkAppLaunchContext *context; gboolean ret; CinnamonGlobal *global; MetaScreen *screen; GdkDisplay *gdisplay; if (startup_id) *startup_id = NULL; if (app->entry == NULL) { MetaWindow *window = window_backed_app_get_window (app); /* We can't pass URIs into a window; shouldn't hit this * code path. If we do, fix the caller to disallow it. */ g_return_val_if_fail (uris == NULL, TRUE); meta_window_activate (window, timestamp); return TRUE; } global = cinnamon_global_get (); screen = cinnamon_global_get_screen (global); gdisplay = gdk_screen_get_display (cinnamon_global_get_gdk_screen (global)); if (timestamp == 0) timestamp = cinnamon_global_get_current_time (global); if (workspace < 0) workspace = meta_screen_get_active_workspace_index (screen); context = gdk_display_get_app_launch_context (gdisplay); gdk_app_launch_context_set_timestamp (context, timestamp); gdk_app_launch_context_set_desktop (context, workspace); gapp = gmenu_tree_entry_get_app_info (app->entry); ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris, G_APP_LAUNCH_CONTEXT (context), G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, _gather_pid_callback, app, error); g_object_unref (context); return ret; }
static GList * xde_entry(MenuContext *ctx, GMenuTreeEntry *ent) { GDesktopAppInfo *info; GList *text = NULL; const char *name; char *esc1, *qname, *esc2, *cmd, *p; char *s, *icon = NULL; GIcon *gicon = NULL; char *appid; if (!(info = gmenu_tree_entry_get_app_info(ent)) || g_desktop_app_info_get_is_hidden(info) || g_desktop_app_info_get_nodisplay(info) || !g_desktop_app_info_get_show_in(info, NULL) || !g_app_info_should_show(G_APP_INFO(info))) return (text); name = g_app_info_get_name(G_APP_INFO(info)); esc1 = xde_character_escape(name, '"'); qname = g_strdup_printf("\"%s\"", esc1); if ((appid = strdup(gmenu_tree_entry_get_desktop_file_id(ent))) && (p = strstr(appid, ".desktop"))) *p = '\0'; if (ctx->stack) gicon = gmenu_tree_directory_get_icon(ctx->stack->data); icon = xde_get_app_icon(ctx, info, gicon, "exec", "unknown", GET_ENTRY_ICON_FLAG_XPM | GET_ENTRY_ICON_FLAG_PNG | GET_ENTRY_ICON_FLAG_JPG | GET_ENTRY_ICON_FLAG_SVG); if (options.launch) { cmd = g_strdup_printf("xdg-launch --pointer %s", appid); } else { cmd = xde_get_command(info, appid, icon); } esc2 = xde_character_escape(cmd, '"'); s = g_strdup_printf(" %-32s f.exec \"exec %s &\"\n", qname, esc2); text = g_list_append(text, s); free(icon); free(appid); g_free(qname); free(esc1); free(esc2); free(cmd); return (text); }
const char * cinnamon_app_get_name (CinnamonApp *app) { if (app->entry) return g_app_info_get_name (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); else if (app->running_state == NULL) return _("Unknown"); else { MetaWindow *window = window_backed_app_get_window (app); const char *name; name = meta_window_get_wm_class (window); if (!name) name = _("Unknown"); return name; } }
static void cinnamon_app_init_search_data (CinnamonApp *app) { const char *name; const char *exec; const char *comment; char *normalized_exec; GDesktopAppInfo *appinfo; appinfo = gmenu_tree_entry_get_app_info (app->entry); name = g_app_info_get_name (G_APP_INFO (appinfo)); app->casefolded_name = cinnamon_util_normalize_and_casefold (name); comment = g_app_info_get_description (G_APP_INFO (appinfo)); app->casefolded_description = cinnamon_util_normalize_and_casefold (comment); exec = g_app_info_get_executable (G_APP_INFO (appinfo)); normalized_exec = cinnamon_util_normalize_and_casefold (exec); app->casefolded_exec = trim_exec_line (normalized_exec); g_free (normalized_exec); }
static CoglHandle cinnamon_app_create_faded_icon_cpu (StTextureCache *cache, const char *key, void *datap, GError **error) { CreateFadedIconData *data = datap; CinnamonApp *app; GdkPixbuf *pixbuf; int size; int scale; CoglHandle texture; gint width, height, rowstride; guint8 n_channels; gboolean have_alpha; gint fade_start; gint fade_range; guint i, j; guint pixbuf_byte_size; guint8 *orig_pixels; guint8 *pixels; GIcon *icon; GtkIconInfo *info; app = data->app; size = data->size; scale = data->scale; info = NULL; icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); if (icon != NULL) { info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (), icon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); } if (info == NULL) { icon = g_themed_icon_new ("application-x-executable"); info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (), icon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); g_object_unref (icon); } if (info == NULL) return COGL_INVALID_HANDLE; pixbuf = gtk_icon_info_load_icon (info, NULL); g_object_unref (info); if (pixbuf == NULL) return COGL_INVALID_HANDLE; width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); rowstride = gdk_pixbuf_get_rowstride (pixbuf); n_channels = gdk_pixbuf_get_n_channels (pixbuf); orig_pixels = gdk_pixbuf_get_pixels (pixbuf); have_alpha = gdk_pixbuf_get_has_alpha (pixbuf); pixbuf_byte_size = (height - 1) * rowstride + + width * ((n_channels * gdk_pixbuf_get_bits_per_sample (pixbuf) + 7) / 8); pixels = g_malloc0 (rowstride * height); memcpy (pixels, orig_pixels, pixbuf_byte_size); fade_start = width / 2; fade_range = width - fade_start; for (i = fade_start; i < width; i++) { for (j = 0; j < height; j++) { guchar *pixel = &pixels[j * rowstride + i * n_channels]; float fade = 1.0 - ((float) i - fade_start) / fade_range; pixel[0] = 0.5 + pixel[0] * fade; pixel[1] = 0.5 + pixel[1] * fade; pixel[2] = 0.5 + pixel[2] * fade; if (have_alpha) pixel[3] = 0.5 + pixel[3] * fade; } } texture = st_cogl_texture_new_from_data_wrapper (width, height, COGL_TEXTURE_NONE, have_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, rowstride, pixels); g_free (pixels); g_object_unref (pixbuf); return texture; }
static GList * xde_entry(MenuContext *ctx, GMenuTreeEntry *ent) { GDesktopAppInfo *info; GList *text = NULL; const char *name; char *esc1, *esc2, *cmd, *p; char *icon = NULL, *wrap, *s; GIcon *gicon = NULL; gboolean notify; char *wmclass, *appid; if (!(info = gmenu_tree_entry_get_app_info(ent)) || g_desktop_app_info_get_is_hidden(info) || g_desktop_app_info_get_nodisplay(info) || !g_desktop_app_info_get_show_in(info, NULL) || !g_app_info_should_show(G_APP_INFO(info))) return (text); name = g_app_info_get_name(G_APP_INFO(info)); esc1 = g_markup_escape_text(name, -1); if (ctx->stack) gicon = gmenu_tree_directory_get_icon(ctx->stack->data); icon = xde_get_app_icon(ctx, info, gicon, "exec", "unknown", GET_ENTRY_ICON_FLAG_XPM | GET_ENTRY_ICON_FLAG_PNG | GET_ENTRY_ICON_FLAG_JPG | GET_ENTRY_ICON_FLAG_SVG); wrap = ctx->wmm.wrap(ctx, strdup(icon)); notify = g_desktop_app_info_get_boolean(info, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY); wmclass = g_desktop_app_info_get_string(info, G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS); if ((appid = strdup(gmenu_tree_entry_get_desktop_file_id(ent))) && (p = strstr(appid, ".desktop"))) *p = '\0'; if (options.launch) { cmd = g_strdup_printf("xdg-launch --pointer %s", appid); } else { cmd = xde_get_command(info, appid, icon); } esc2 = g_markup_escape_text(cmd, -1); s = g_strdup_printf("%s<item label=\"%s\"%s>\n", ctx->indent, esc1, wrap); text = g_list_append(text, s); s = g_strdup_printf("%s <action name=\"Execute\">\n", ctx->indent); text = g_list_append(text, s); s = g_strdup_printf("%s <command>%s</command>\n", ctx->indent, esc2); text = g_list_append(text, s); if (!options.launch && (notify || wmclass)) { /* don't put launch specifics if we are launching with xdg-launch */ s = g_strdup_printf("%s <startupnotify>\n", ctx->indent); text = g_list_append(text, s); if (notify) { s = g_strdup_printf("%s <enabled>yes</enabled>\n", ctx->indent); text = g_list_append(text, s); } if (wmclass) { s = g_strdup_printf("%s <wmclass>%s</wmclass>\n", ctx->indent, wmclass); text = g_list_append(text, s); } s = g_strdup_printf("%s <name>%s</name>\n", ctx->indent, esc1); text = g_list_append(text, s); if (icon) { s = g_strdup_printf("%s <icon>%s</icon>\n", ctx->indent, icon); text = g_list_append(text, s); } s = g_strdup_printf("%s </startupnotify>\n", ctx->indent); text = g_list_append(text, s); } s = g_strdup_printf("%s </action>\n", ctx->indent); text = g_list_append(text, s); s = g_strdup_printf("%s</item>\n", ctx->indent); text = g_list_append(text, s); free(wrap); free(icon); g_free(wmclass); free(appid); g_free(esc1); g_free(esc2); free(cmd); return (text); }
static void on_apps_tree_changed_cb (GMenuTree *tree, gpointer user_data) { CinnamonAppSystem *self = CINNAMON_APP_SYSTEM (user_data); GError *error = NULL; GHashTable *new_apps; GHashTableIter iter; gpointer key, value; GSList *removed_apps = NULL; GSList *removed_node; g_assert (tree == self->priv->apps_tree); g_slist_foreach (self->priv->known_vendor_prefixes, (GFunc)g_free, NULL); g_slist_free (self->priv->known_vendor_prefixes); self->priv->known_vendor_prefixes = NULL; if (!gmenu_tree_load_sync (self->priv->apps_tree, &error)) { g_warning ("Failed to load apps: %s", error->message); return; } new_apps = get_flattened_entries_from_tree (self->priv->apps_tree); g_hash_table_iter_init (&iter, new_apps); while (g_hash_table_iter_next (&iter, &key, &value)) { const char *id = key; GMenuTreeEntry *entry = value; GMenuTreeEntry *old_entry; char *prefix; CinnamonApp *app; GDesktopAppInfo *info; const char *startup_wm_class; prefix = get_prefix_for_entry (entry); if (prefix != NULL && !g_slist_find_custom (self->priv->known_vendor_prefixes, prefix, (GCompareFunc)g_strcmp0)) self->priv->known_vendor_prefixes = g_slist_append (self->priv->known_vendor_prefixes, prefix); else g_free (prefix); app = g_hash_table_lookup (self->priv->id_to_app, id); if (app != NULL) { /* We hold a reference to the original entry temporarily, * because otherwise the hash table would be referencing * potentially free'd memory until we replace it below with * the new data. */ old_entry = cinnamon_app_get_tree_entry (app); gmenu_tree_item_ref (old_entry); _cinnamon_app_set_entry (app, entry); g_object_ref (app); /* Extra ref, removed in _replace below */ } else { old_entry = NULL; app = _cinnamon_app_new (entry); } /* Note that "id" is owned by app->entry. Since we're always * setting a new entry, even if the app already exists in the * hash table we need to replace the key so that the new id * string is pointed to. */ g_hash_table_replace (self->priv->id_to_app, (char*)id, app); // if (!gmenu_tree_entry_get_is_nodisplay_recurse (entry)) // g_hash_table_replace (self->priv->visible_id_to_app, (char*)id, app); if (old_entry) { GDesktopAppInfo *old_info; const gchar *old_startup_wm_class; old_info = gmenu_tree_entry_get_app_info (old_entry); old_startup_wm_class = g_desktop_app_info_get_startup_wm_class (old_info); if (old_startup_wm_class) g_hash_table_remove (self->priv->startup_wm_class_to_app, old_startup_wm_class); } info = gmenu_tree_entry_get_app_info (entry); startup_wm_class = g_desktop_app_info_get_startup_wm_class (info); if (startup_wm_class) g_hash_table_replace (self->priv->startup_wm_class_to_app, (char*)startup_wm_class, g_object_ref (app)); if (old_entry) gmenu_tree_item_unref (old_entry); } /* Now iterate over the apps again; we need to unreference any apps * which have been removed. The JS code may still be holding a * reference; that's fine. */ g_hash_table_iter_init (&iter, self->priv->id_to_app); while (g_hash_table_iter_next (&iter, &key, &value)) { const char *id = key; if (!g_hash_table_lookup (new_apps, id)) removed_apps = g_slist_prepend (removed_apps, (char*)id); } for (removed_node = removed_apps; removed_node; removed_node = removed_node->next) { const char *id = removed_node->data; g_hash_table_remove (self->priv->id_to_app, id); } g_slist_free (removed_apps); g_hash_table_destroy (new_apps); g_signal_emit (self, signals[INSTALLED_CHANGED], 0); }
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; }
static void create_menuitem (GtkWidget *menu, GMenuTreeEntry *entry, GMenuTreeDirectory *alias_directory) { GtkWidget *menuitem; menuitem = panel_image_menu_item_new2 (); if (alias_directory) panel_load_menu_image_deferred (menuitem, panel_menu_icon_get_size (), gmenu_tree_directory_get_icon (alias_directory), NULL, NULL); else panel_load_menu_image_deferred (menuitem, panel_menu_icon_get_size (), g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (entry))), NULL, NULL); setup_menuitem (menuitem, panel_menu_icon_get_size (), NULL, alias_directory ? gmenu_tree_directory_get_name (alias_directory) : g_app_info_get_display_name (G_APP_INFO (gmenu_tree_entry_get_app_info (entry)))); if (alias_directory && gmenu_tree_directory_get_comment (alias_directory)) panel_util_set_tooltip_text (menuitem, gmenu_tree_directory_get_comment (alias_directory)); else if (!alias_directory) { const char *description = g_app_info_get_description (G_APP_INFO (gmenu_tree_entry_get_app_info (entry))); if (!description) description = g_desktop_app_info_get_generic_name (gmenu_tree_entry_get_app_info (entry)); if (description) panel_util_set_tooltip_text (menuitem, description); } g_signal_connect_after (menuitem, "button_press_event", G_CALLBACK (menu_dummy_button_press_event), NULL); if (!panel_lockdown_get_panels_locked_down_s ()) { GIcon *icon; static GtkTargetEntry menu_item_targets[] = { { "text/uri-list", 0, 0 } }; gtk_drag_source_set (menuitem, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, menu_item_targets, 1, GDK_ACTION_COPY); icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (entry))); if (icon != NULL) gtk_drag_source_set_icon_gicon (menuitem, icon); g_signal_connect (G_OBJECT (menuitem), "drag_begin", G_CALLBACK (drag_begin_menu_cb), NULL); g_signal_connect (menuitem, "drag_data_get", G_CALLBACK (drag_data_get_menu_cb), entry); g_signal_connect (menuitem, "drag_end", G_CALLBACK (drag_end_menu_cb), NULL); } gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (menuitem, "activate", G_CALLBACK (activate_app_def), entry); gtk_widget_show (menuitem); }
/* * This function inherit from gnome-menus/util/test-menu-spec.c */ static void traverse_directory(GMenuTreeDirectory *dir, GtkWidget *parent) { GMenuTreeIter *iter = NULL; GtkWidget *dir_submenu = parent ? gtk_menu_new() : NULL; GtkWidget *entry_submenu = gtk_menu_new(); GIcon *icon = NULL; const char *text = NULL; GtkWidget *menuitem = NULL; iter = gmenu_tree_directory_iter(dir); while (TRUE) { gpointer item = NULL; switch (gmenu_tree_iter_next(iter)) { case GMENU_TREE_ITEM_INVALID: goto done; case GMENU_TREE_ITEM_ENTRY: item = gmenu_tree_iter_get_entry(iter); GDesktopAppInfo *appinfo = gmenu_tree_entry_get_app_info((GMenuTreeEntry *)item); icon = g_app_info_get_icon((GAppInfo *)appinfo); text = g_app_info_get_display_name((GAppInfo *)appinfo); menuitem = menu_item_new_with_icon_text(icon, text); gtk_menu_shell_append(GTK_MENU_SHELL(entry_submenu), menuitem); g_object_connect(G_OBJECT(menuitem), "signal::activate", G_CALLBACK(menu_item_activate), appinfo, NULL); break; case GMENU_TREE_ITEM_DIRECTORY: item = gmenu_tree_iter_get_directory(iter); icon = gmenu_tree_directory_get_icon((GMenuTreeDirectory *)item); text = gmenu_tree_directory_get_name((GMenuTreeDirectory *)item); menuitem = menu_item_new_with_icon_text(icon, text); gtk_menu_shell_append(dir_submenu ? GTK_MENU_SHELL(dir_submenu) : GTK_MENU_SHELL(popup), menuitem); traverse_directory(item, menuitem); break; } if (item) { gmenu_tree_item_unref(item); item = NULL; } continue; done: break; } if (parent) { if (dir_submenu) gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), dir_submenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), entry_submenu); } if (iter) { gmenu_tree_iter_unref(iter); iter = NULL; } }