Advertisement
ananas

Dynamic XDG menus for FVWM

Sep 20th, 2011
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.39 KB | None | 0 0
  1. /*
  2.  * This program is free software; you can redistribute it and/or modify
  3.  * it under the terms of the GNU General Public License as published by
  4.  * the Free Software Foundation; either version 3 of the License, or
  5.  * (at your option) any later version.
  6.  *
  7.  * This program is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10.  * GNU General Public License for more details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License
  13.  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14.  *
  15.  * Copyright (C) 2011, Victor Ananjevsky <ananasik@gmail.com>
  16.  */
  17.  
  18. /* Compile command: gcc -o fvwmmenu `pkg-config --cflags --libs gtk+-2.0 libgnome-menu` fvwmmenu.c */
  19.  
  20. #include <gtk/gtk.h>
  21.  
  22. #define GMENU_I_KNOW_THIS_IS_UNSTABLE
  23. #include <gmenu-tree.h>
  24.  
  25. static GtkIconTheme *theme;
  26. static gint size = -1;
  27.  
  28. static gchar *cache_path;
  29.  
  30. static gchar *term = "xterm";
  31.  
  32. static gchar *
  33. cache_icon (const gchar * name)
  34. {
  35.   gchar *filename = NULL;
  36.   GdkPixbuf *pb = NULL;
  37.  
  38.   if (size == 0)
  39.     return "";
  40.  
  41.   if (g_file_test (name, G_FILE_TEST_EXISTS))
  42.     {
  43.       filename = g_strdup_printf ("%s/%s", cache_path, basename (name));
  44.       if (!g_file_test (filename, G_FILE_TEST_EXISTS))
  45.         pb = gdk_pixbuf_new_from_file_at_size (name, size, size, NULL);
  46.     }
  47.   else
  48.     {
  49.       gchar *p, *sname = g_strdup (name);
  50.  
  51.       if (p = g_strrstr (sname, ".png"))
  52.         *p = '\0';
  53.  
  54.       filename = g_strdup_printf ("%s/%s.png", cache_path, sname);
  55.       if (!g_file_test (filename, G_FILE_TEST_EXISTS))
  56.         pb = gtk_icon_theme_load_icon (theme, sname, size, GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
  57.       g_free (sname);
  58.     }
  59.  
  60.   if (pb)
  61.     {
  62.       gdk_pixbuf_save (pb, filename, "png", NULL);
  63.       g_object_unref (pb);
  64.     }
  65.  
  66.   return (gchar *) basename (filename);
  67. }
  68.  
  69. static gchar *
  70. cstrip (const gchar * cmd)
  71. {
  72.   gchar *p, *ret = g_strdup (cmd);
  73.  
  74.   if (p = g_strrstr (ret, "%"))
  75.     *p = '\0';
  76.  
  77.   return ret;
  78. }
  79.  
  80. gint
  81. main (gint argc, gchar * argv[])
  82. {
  83.   gchar **menus;
  84.   GOptionEntry entrs[] = {
  85.     {"size", 's', 0, G_OPTION_ARG_INT, &size, "Set icon size", "SIZE"}
  86.     ,
  87.     {"term", 't', 0, G_OPTION_ARG_STRING, &term, "Set terminal command", "TERM"}
  88.     ,
  89.     {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &menus, NULL, NULL}
  90.     ,
  91.     {NULL}
  92.   };
  93.  
  94.   gtk_init_with_args (&argc, &argv, "- Create xdg menus for FVWM", entrs, NULL, NULL);
  95.  
  96.   theme = gtk_icon_theme_get_default ();
  97.   if (size == -1)
  98.     {
  99.       gint w, h;
  100.       gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
  101.       size = MIN (w, h);
  102.     }
  103.   cache_path = g_build_filename (g_get_user_cache_dir (), "fvwm", "menu", NULL);
  104.   g_mkdir_with_parents (cache_path, 0644);
  105.  
  106.   if (menus && menus[0])
  107.     {
  108.       if (g_ascii_strcasecmp (menus[0], "recent") == 0)
  109.         {
  110.           GList *r = gtk_recent_manager_get_items (gtk_recent_manager_get_default ());
  111.  
  112.           g_printf ("DestroyMenu recreate %s\n", menus[0]);
  113.  
  114.           for (; r; r = r->next)
  115.             {
  116.               GtkRecentInfo *ri = (GtkRecentInfo *) r->data;
  117.               if (gtk_recent_info_exists (ri))
  118.                 {
  119.                   gchar *doc, *cmd;
  120.  
  121.                   doc = (gchar *) gtk_recent_info_get_display_name (ri);
  122.                   gtk_recent_info_get_application_info (ri, gtk_recent_info_last_application (ri),
  123.                                                         (const gchar **) &cmd, NULL, NULL);
  124.  
  125.                   g_printf ("AddToMenu %s \"%s\" Exec exec %s\n", menus[0], doc, cmd);
  126.                 }
  127.             }
  128.         }
  129.       else
  130.         {
  131.           GMenuTree *tree;
  132.           GMenuTreeDirectory *root, *dir;
  133.           GSList *items;
  134.           gchar *file;
  135.           const gchar *menuname;
  136.  
  137.           file = g_strdup_printf ("%s.menu", g_ascii_strdown (menus[0], -1));
  138.           if ((tree = gmenu_tree_lookup (file, GMENU_TREE_FLAGS_NONE)) == NULL)
  139.             return 1;
  140.           g_free (file);
  141.  
  142.           if (menus[1])
  143.             root = gmenu_tree_get_directory_from_path (tree, menus[1]);
  144.           else
  145.             root = gmenu_tree_get_root_directory (tree);
  146.           if (!root)
  147.             return 1;
  148.  
  149.           if (menus[1])
  150.             menuname = gmenu_tree_directory_get_menu_id (root);
  151.           else
  152.             menuname = menus[0];
  153.           g_printf ("DestroyMenu recreate %s\n", menuname);
  154.  
  155.           for (items = gmenu_tree_directory_get_contents (root); items; items = items->next)
  156.             {
  157.               GMenuTreeItem *it = (GMenuTreeItem *) items->data;
  158.  
  159.               switch (gmenu_tree_item_get_type (it))
  160.                 {
  161.                 case GMENU_TREE_ITEM_ALIAS:
  162.                   it = gmenu_tree_alias_get_item (GMENU_TREE_ALIAS (it));
  163.                   if (gmenu_tree_item_get_type (it) != GMENU_TREE_ITEM_ENTRY)
  164.                     break;
  165.                 case GMENU_TREE_ITEM_ENTRY:
  166.                   if (!gmenu_tree_entry_get_is_excluded (GMENU_TREE_ENTRY (it)) ||
  167.                       !gmenu_tree_entry_get_is_nodisplay (GMENU_TREE_ENTRY (it)))
  168.                     {
  169.                       const gchar *n, *i, *c;
  170.  
  171.                       n = gmenu_tree_entry_get_generic_name (GMENU_TREE_ENTRY (it));
  172.                       if (!n)
  173.                         n = gmenu_tree_entry_get_display_name (GMENU_TREE_ENTRY (it));
  174.                       i = gmenu_tree_entry_get_icon (GMENU_TREE_ENTRY (it));
  175.                       c = gmenu_tree_entry_get_exec (GMENU_TREE_ENTRY (it));
  176.  
  177.                       if (gmenu_tree_entry_get_launch_in_terminal (GMENU_TREE_ENTRY (it)))
  178.                         {
  179.                           g_printf ("AddToMenu %s \"%s%%menu/%s%%\" Exec exec %s -e \"%s\"\n",
  180.                                     menuname, g_strstrip ((gchar *) n), cache_icon (i), term, cstrip (c));
  181.                         }
  182.                       else
  183.                         {
  184.                           g_printf ("AddToMenu %s \"%s%%menu/%s%%\" Exec exec %s\n",
  185.                                     menuname, g_strstrip ((gchar *) n), cache_icon (i), cstrip (c));
  186.                         }
  187.                     }
  188.                   break;
  189.                 case GMENU_TREE_ITEM_DIRECTORY:
  190.                   if (!gmenu_tree_directory_get_is_nodisplay (GMENU_TREE_DIRECTORY (it)))
  191.                     {
  192.                       const gchar *n, *i, *m;
  193.  
  194.                       n = gmenu_tree_directory_get_name (GMENU_TREE_DIRECTORY (it));
  195.                       i = gmenu_tree_directory_get_icon (GMENU_TREE_DIRECTORY (it));
  196.                       m = gmenu_tree_directory_get_menu_id (GMENU_TREE_DIRECTORY (it));
  197.  
  198.                       g_printf ("AddToMenu %s \"%s%%menu/%s%%\" Popup %s\n", menuname, n, cache_icon (i), m);
  199.  
  200.                       g_printf ("DestroyMenu %s\n", m);
  201.                       g_printf ("AddToMenu %s DynamicPopupAction PipeRead \"%s -s %d -t %s %s %s\"\n",
  202.                                 m, argv[0], size, term, menus[0],
  203.                                 gmenu_tree_directory_make_path (GMENU_TREE_DIRECTORY (it), NULL));
  204.                     }
  205.                   break;
  206.                 case GMENU_TREE_ITEM_SEPARATOR:
  207.                   g_printf ("AddToMenu %s \"\" Nop\n", menuname);
  208.                   break;
  209.                 }
  210.             }
  211.         }
  212.     }
  213.   else
  214.     return 1;
  215.  
  216.   return 0;
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement