Advertisement
Guest User

last version using dbus vs reimplementation of dbus

a guest
Dec 1st, 2010
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 44.11 KB | None | 0 0
  1. diff -aur compiz-deskmenu2/deskmenu-menu.c compiz-boxmenu/deskmenu-menu.c
  2. --- compiz-deskmenu2/deskmenu-menu.c    2010-12-01 15:31:32.000000000 -0800
  3. +++ compiz-boxmenu/deskmenu-menu.c  2010-12-01 15:11:05.000000000 -0800
  4. @@ -18,13 +18,10 @@
  5.   /*
  6.  
  7.  Roadmap:
  8.  
  9.  Necessary:
  10.  
  11. -   TODO: Get rid of dbus reload and show method for pipemenus to work as intended
  12.  
  13. -   TODO: Add tilde expansion for icons in both the editor and the menu difficulty: easy
  14.  
  15. -   TODO: Add a viewport # indicator for the window list for accesiblity reasons difficulty: easy
  16.  
  17. +   TODO: Add a viewport # indicator for the window list for accesiblity reasons difficulty: hard
  18.  
  19.     TODO: Add configuration for menu icon size difficulty: easy
  20.  
  21.     TODO: Add toggle of tearables difficulty: easy
  22.  
  23.     TODO: Add a sane icon dialog difficulty: medium-hard
  24.  
  25. -   TODO: Add icon choice for viewports: easy
  26.  
  27.  For fun, might not implement:
  28.  
  29.  TODO: Add ability to call up menus from the menu.xml file by name, if this is really, really needed or requested
  30.  
  31.   */
  32.  
  33. @@ -44,7 +41,9 @@
  34.  #include "deskmenu-glue.h"
  35.  
  36.  
  37.  
  38.  
  39.  
  40. -G_DEFINE_TYPE(Deskmenu, deskmenu, G_TYPE_OBJECT)
  41.  
  42. +G_DEFINE_TYPE(Deskmenu, deskmenu, G_TYPE_OBJECT) //this is calling deskmenu_class_init
  43.  
  44. +
  45.  
  46. +//launcher.c is the file to look for apwal mode for deskmenu
  47.  
  48.  
  49.  
  50.  GQuark
  51.  
  52.  deskmenu_error_quark (void)
  53.  
  54. @@ -63,6 +62,8 @@
  55.  }
  56.  
  57.  
  58.  
  59.  //stolen from openbox, possibly move this outside in order to make it a function to parse launchers and icon location
  60.  
  61. +//optimize code to reduce calls to this, should only be called once per parse
  62.  
  63. +static
  64.  
  65.  gchar *parse_expand_tilde(const gchar *f)
  66.  
  67.  {
  68.  
  69.  gchar *ret;
  70.  
  71. @@ -70,7 +71,6 @@
  72.  
  73.  
  74.  if (!f)
  75.  
  76.      return NULL;
  77.  
  78. -
  79.  
  80.  regex = g_regex_new("(?:^|(?<=[ \\t]))~(?:(?=[/ \\t])|$)",
  81.  
  82.                      G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
  83.  
  84.  ret = g_regex_replace_literal(regex, f, -1, 0, g_get_home_dir(), 0, NULL);
  85.  
  86. @@ -86,9 +86,7 @@
  87.                      gchar     *command)
  88.  
  89.  {
  90.  
  91.      GError *error = NULL;
  92.  
  93. -    Deskmenu *deskmenu;
  94.  
  95. -  
  96.  
  97. -    deskmenu = g_object_get_data (G_OBJECT (widget), "deskmenu");
  98.  
  99. +
  100.  
  101.     if (!gdk_spawn_command_line_on_screen (gdk_screen_get_default (), parse_expand_tilde(command), &error))
  102.  
  103.      {
  104.  
  105.          GtkWidget *message = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
  106.  
  107. @@ -99,17 +97,43 @@
  108.  
  109.  
  110.  }
  111.  
  112.  
  113.  
  114. -//place & in front of stdout for standard stdout, how a command is launched as an exec
  115.  
  116. +//This is how a recent document is opened
  117.  
  118.  static void
  119.  
  120. -launcher_name_exec_update (GtkWidget *label)
  121.  
  122. +recent_activated (GtkRecentChooser *chooser,
  123.  
  124. +                  gchar     *command)
  125.  
  126.  {
  127.  
  128. -    gchar *exec, *stdout;
  129.  
  130. -    exec = g_object_get_data (G_OBJECT (label), "exec");
  131.  
  132. -    if (g_spawn_command_line_sync (parse_expand_tilde(exec), &stdout, NULL, NULL, NULL))
  133.  
  134. -        gtk_label_set_text (GTK_LABEL (label), g_strstrip(stdout));
  135.  
  136. -    else
  137.  
  138. -        gtk_label_set_text (GTK_LABEL (label), "execution error");
  139.  
  140. -    g_free (stdout);
  141.  
  142. +    GError *error = NULL;
  143.  
  144. +  
  145.  
  146. +   gchar *full_command;
  147.  
  148. +   gchar *file;
  149.  
  150. +   GRegex *regex, *regex2;
  151.  
  152. +
  153.  
  154. +   regex = g_regex_new("file:///", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
  155.  
  156. +   regex2 = g_regex_new("%f", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
  157.  
  158. +
  159.  
  160. +   file = g_strstrip(g_regex_replace_literal(regex, gtk_recent_chooser_get_current_uri (chooser), -1, 0, "/", 0, NULL));
  161.  
  162. +  
  163.  
  164. +   if (g_regex_match (regex2,command,0,0))
  165.  
  166. +   {
  167.  
  168. +       //if using custom complex command, replace %f with filename
  169.  
  170. +       full_command = g_strstrip(g_regex_replace_literal(regex2, command, -1, 0, file, 0, NULL));
  171.  
  172. +   }
  173.  
  174. +   else
  175.  
  176. +   {
  177.  
  178. +       full_command = g_strjoin (" ", command, file, NULL);
  179.  
  180. +   }
  181.  
  182. +  
  183.  
  184. +   g_regex_unref(regex);
  185.  
  186. +   g_regex_unref(regex2);
  187.  
  188. +  
  189.  
  190. +   if (!gdk_spawn_command_line_on_screen (gdk_screen_get_default (), parse_expand_tilde(full_command), &error))
  191.  
  192. +    {
  193.  
  194. +        GtkWidget *message = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
  195.  
  196. +            GTK_BUTTONS_CLOSE, "%s", error->message);
  197.  
  198. +        gtk_dialog_run (GTK_DIALOG (message));
  199.  
  200. +        gtk_widget_destroy (message);
  201.  
  202. +    }
  203.  
  204. +
  205.  
  206.  }
  207.  
  208.  
  209.  
  210.  static void
  211.  
  212. @@ -125,22 +149,13 @@
  213.          case DESKMENU_ITEM_LAUNCHER:
  214.  
  215.              if (item->name_exec)
  216.  
  217.              {
  218.  
  219. -                GtkWidget *label;
  220.  
  221. -                GHook *hook;
  222.  
  223. -
  224.  
  225. +                gchar *stdout;
  226.  
  227.                  name = g_strstrip (item->name->str);
  228.  
  229. -
  230.  
  231. -                menu_item = gtk_image_menu_item_new ();
  232.  
  233. -                label = gtk_label_new_with_mnemonic (NULL);
  234.  
  235. -                gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  236.  
  237. -
  238.  
  239. -                g_object_set_data (G_OBJECT (label), "exec", g_strdup (name));
  240.  
  241. -                gtk_container_add (GTK_CONTAINER (menu_item), label);
  242.  
  243. -                hook = g_hook_alloc (deskmenu->show_hooks);
  244.  
  245. -
  246.  
  247. -                hook->data = (gpointer) label;
  248.  
  249. -                hook->func = (GHookFunc *) launcher_name_exec_update;
  250.  
  251. -                g_hook_append (deskmenu->show_hooks, hook);
  252.  
  253. +               if (g_spawn_command_line_sync (parse_expand_tilde(name), &stdout, NULL, NULL, NULL))
  254.  
  255. +                   menu_item = gtk_image_menu_item_new_with_mnemonic (g_strstrip(stdout));
  256.  
  257. +               else
  258.  
  259. +                   menu_item = gtk_image_menu_item_new_with_mnemonic ("Unable to get output");
  260.  
  261. +               g_free (stdout);
  262.  
  263.              }
  264.  
  265.              else
  266.  
  267.              {
  268.  
  269. @@ -170,7 +185,6 @@
  270.              {
  271.  
  272.                
  273.  
  274.                  command = g_strstrip (item->command->str);
  275.  
  276. -                g_object_set_data (G_OBJECT (menu_item), "deskmenu", deskmenu);
  277.  
  278.                  g_signal_connect (G_OBJECT (menu_item), "activate",
  279.  
  280.                      G_CALLBACK (launcher_activated), g_strdup (command));
  281.  
  282.              }
  283.  
  284. @@ -239,7 +253,97 @@
  285.              }
  286.  
  287.              break;
  288.  
  289.  #endif
  290.  
  291. +        case DESKMENU_ITEM_RELOAD:
  292.  
  293. +            menu_item = gtk_image_menu_item_new_with_mnemonic ("Reload");
  294.  
  295.  
  296.  
  297. +            if (item->icon)
  298.  
  299. +            {
  300.  
  301. +                icon = g_strstrip (item->icon->str);
  302.  
  303. +                if (item->icon_file) {
  304.  
  305. +                   gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
  306.  
  307. +                   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
  308.  
  309. +                      (menu_item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
  310.  
  311. +               }
  312.  
  313. +               else {
  314.  
  315. +                   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
  316.  
  317. +                       gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
  318.  
  319. +               }
  320.  
  321. +            }
  322.  
  323. +            g_signal_connect (G_OBJECT (menu_item), "activate",
  324.  
  325. +                G_CALLBACK (quit), NULL);
  326.  
  327. +            gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
  328.  
  329. +                menu_item);
  330.  
  331. +            break;
  332.  
  333. +
  334.  
  335. +        case DESKMENU_ITEM_DOCUMENTS:
  336.  
  337. +            menu_item = gtk_image_menu_item_new_with_mnemonic ("Recent Doc_uments");
  338.  
  339. +            GtkWidget *docs = gtk_recent_chooser_menu_new ();
  340.  
  341. +
  342.  
  343. +            if (item->icon)
  344.  
  345. +            {
  346.  
  347. +               gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER(docs), TRUE);
  348.  
  349. +                icon = g_strstrip (item->icon->str);
  350.  
  351. +                if (item->icon_file) {
  352.  
  353. +                   gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
  354.  
  355. +                   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
  356.  
  357. +                      (menu_item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
  358.  
  359. +               }
  360.  
  361. +               else {
  362.  
  363. +                   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
  364.  
  365. +                       gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
  366.  
  367. +               }
  368.  
  369. +            }
  370.  
  371. +           else
  372.  
  373. +           {
  374.  
  375. +               gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER(docs), FALSE);
  376.  
  377. +           }
  378.  
  379. +            if (item->age)
  380.  
  381. +            {
  382.  
  383. +               gint days;
  384.  
  385. +               GtkRecentFilter *filter = gtk_recent_filter_new ();
  386.  
  387. +               gtk_recent_filter_add_pattern (filter, "*");
  388.  
  389. +                days = atoi(g_strstrip (item->age->str));
  390.  
  391. +                gtk_recent_filter_add_age (filter, days);
  392.  
  393. +                gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER(docs), filter);
  394.  
  395. +            }
  396.  
  397. +            if (item->sort_type) {
  398.  
  399. +                   if (strcmp (g_strstrip (item->sort_type->str), "most used") == 0)
  400.  
  401. +                   {
  402.  
  403. +                       gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER(docs), GTK_RECENT_SORT_MRU);
  404.  
  405. +                   }
  406.  
  407. +                   else
  408.  
  409. +                   {
  410.  
  411. +                       gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER(docs), GTK_RECENT_SORT_LRU);
  412.  
  413. +                   }
  414.  
  415. +           }
  416.  
  417. +            if (item->quantity)
  418.  
  419. +            {
  420.  
  421. +               gint limit;
  422.  
  423. +                limit = atoi(g_strstrip (item->quantity->str));
  424.  
  425. +               gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER(docs), limit);
  426.  
  427. +            }
  428.  
  429. +           else
  430.  
  431. +           {
  432.  
  433. +               gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER(docs), -1);
  434.  
  435. +           }
  436.  
  437. +           if (item->command)
  438.  
  439. +           {
  440.  
  441. +               command = g_strstrip (item->command->str);
  442.  
  443. +               g_signal_connect (G_OBJECT (docs), "item-activated",
  444.  
  445. +                    G_CALLBACK (recent_activated), g_strdup (command));
  446.  
  447. +           }
  448.  
  449. +           else
  450.  
  451. +           {
  452.  
  453. +               command = g_strdup ("xdg-open");
  454.  
  455. +               g_signal_connect (G_OBJECT (docs), "item-activated",
  456.  
  457. +                    G_CALLBACK (recent_activated), g_strdup (command));
  458.  
  459. +           }
  460.  
  461. +           gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
  462.  
  463. +                docs);
  464.  
  465. +            gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
  466.  
  467. +                menu_item);
  468.  
  469. +            break;
  470.  
  471. +            
  472.  
  473.          default:
  474.  
  475.              break;
  476.  
  477.      }
  478.  
  479. @@ -259,11 +363,11 @@
  480.      DeskmenuElementType element_type;
  481.  
  482.      const gchar **ncursor = attr_names, **vcursor = attr_values;
  483.  
  484.      GtkWidget *item, *menu;
  485.  
  486. +    gint w, h;
  487.  
  488.  
  489.  
  490.      element_type = GPOINTER_TO_INT (g_hash_table_lookup
  491.  
  492.          (deskmenu->element_hash, element_name));
  493.  
  494.  
  495.  
  496. -   //TODO: maybe this could be edited to see the new compiz-deskmenu element, if this is needed in order to make pipes
  497.  
  498.      if ((deskmenu->menu && !deskmenu->current_menu)
  499.  
  500.         || (!deskmenu->menu && element_type != DESKMENU_ELEMENT_MENU))
  501.  
  502.      {
  503.  
  504. @@ -289,9 +393,15 @@
  505.                      "inside of an item element", line_num, char_num);
  506.  
  507.                  return;
  508.  
  509.              }
  510.  
  511. -           //TODO: maybe this could be moved to see the new compiz-deskmenu element, if this is needed in order to make pipes
  512.  
  513.              if (!deskmenu->menu)
  514.  
  515.              {
  516.  
  517. +               /*if (strcmp (*ncursor, "size") == 0) {
  518.  
  519. +                    deskmenu->w = g_strdup (*vcursor);
  520.  
  521. +                    deskmenu->h = g_strdup (*vcursor);
  522.  
  523. +                    }
  524.  
  525. +                else {
  526.  
  527. +                   gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, deskmenu->w, deskmenu->h);
  528.  
  529. +                }*/
  530.  
  531.                  deskmenu->menu = gtk_menu_new ();
  532.  
  533.                  g_object_set_data (G_OBJECT (deskmenu->menu), "parent menu",
  534.  
  535.                      NULL);
  536.  
  537. @@ -303,7 +413,6 @@
  538.                  gchar *icon = NULL;
  539.  
  540.                  gboolean name_exec = FALSE;
  541.  
  542.                  gboolean icon_file = FALSE;
  543.  
  544. -                gint w, h;
  545.  
  546.                  while (*ncursor)
  547.  
  548.                  {
  549.  
  550.                      if (strcmp (*ncursor, "name") == 0)
  551.  
  552. @@ -325,20 +434,12 @@
  553.                  }
  554.  
  555.                 if (name_exec)
  556.  
  557.                 {
  558.  
  559. -                   GtkWidget *label;
  560.  
  561. -                   GHook *hook;
  562.  
  563. -              
  564.  
  565. -                   item = gtk_image_menu_item_new ();
  566.  
  567. -                   label = gtk_label_new_with_mnemonic (NULL);
  568.  
  569. -                   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  570.  
  571. -              
  572.  
  573. -                   g_object_set_data (G_OBJECT (label), "exec", g_strdup (name));
  574.  
  575. -                   gtk_container_add (GTK_CONTAINER (item), label);
  576.  
  577. -                   hook = g_hook_alloc (deskmenu->show_hooks);
  578.  
  579. -              
  580.  
  581. -                   hook->data = (gpointer) label;
  582.  
  583. -                   hook->func = (GHookFunc *) launcher_name_exec_update;
  584.  
  585. -                   g_hook_append (deskmenu->show_hooks, hook);
  586.  
  587. +                   gchar *stdout;
  588.  
  589. +                   if (g_spawn_command_line_sync (parse_expand_tilde(name), &stdout, NULL, NULL, NULL))
  590.  
  591. +                       item = gtk_image_menu_item_new_with_mnemonic (g_strstrip(stdout));
  592.  
  593. +                   else
  594.  
  595. +                       item = gtk_image_menu_item_new_with_mnemonic ("Unable to get output");
  596.  
  597. +                   g_free (stdout);
  598.  
  599.                 }
  600.  
  601.                 else
  602.  
  603.                 {
  604.  
  605. @@ -347,8 +448,6 @@
  606.                
  607.  
  608.                     else
  609.  
  610.                         item = gtk_image_menu_item_new_with_mnemonic ("");
  611.  
  612. -                   gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
  613.  
  614. -                       item);
  615.  
  616.                 }
  617.  
  618.                  if (icon)
  619.  
  620.                 {
  621.  
  622. @@ -362,6 +461,7 @@
  623.                         gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
  624.  
  625.                     }
  626.  
  627.                 }
  628.  
  629. +               gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu), item);
  630.  
  631.                  menu = gtk_menu_new ();
  632.  
  633.                  g_object_set_data (G_OBJECT (menu), "parent menu",
  634.  
  635.                      deskmenu->current_menu);
  636.  
  637. @@ -374,7 +474,91 @@
  638.              break;
  639.  
  640.  
  641.  
  642.          case DESKMENU_ELEMENT_SEPARATOR:
  643.  
  644. -            break; /* build it in the end function */
  645.  
  646. +        if (deskmenu->current_item != NULL)
  647.  
  648. +            {
  649.  
  650. +                gint line_num, char_num;
  651.  
  652. +                g_markup_parse_context_get_position (context, &line_num,
  653.  
  654. +                    &char_num);
  655.  
  656. +                g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
  657.  
  658. +                    "Error on line %d char %d: Element 'menu' cannot be nested "
  659.  
  660. +                    "inside of an item element", line_num, char_num);
  661.  
  662. +                return;
  663.  
  664. +            }
  665.  
  666. +        else {
  667.  
  668. +                gchar *name = NULL;
  669.  
  670. +                gchar *icon = NULL;
  671.  
  672. +                gboolean name_exec = FALSE;
  673.  
  674. +                gboolean icon_file = FALSE;
  675.  
  676. +                gboolean decorate = FALSE;
  677.  
  678. +                gint w, h;
  679.  
  680. +                while (*ncursor)
  681.  
  682. +                {
  683.  
  684. +                    if (strcmp (*ncursor, "name") == 0) {
  685.  
  686. +                        name = g_strdup (*vcursor);
  687.  
  688. +                       if (!decorate)
  689.  
  690. +                       {
  691.  
  692. +                           decorate = TRUE;
  693.  
  694. +                       }
  695.  
  696. +                   }
  697.  
  698. +                    else if (strcmp (*ncursor, "icon") == 0) {
  699.  
  700. +                       icon = g_strdup (*vcursor);
  701.  
  702. +                       if (!decorate)
  703.  
  704. +                       {
  705.  
  706. +                           decorate = TRUE;
  707.  
  708. +                       }
  709.  
  710. +                   }
  711.  
  712. +                    else if ((strcmp (*ncursor, "mode") == 0)
  713.  
  714. +                        && (strcmp (*vcursor, "exec") == 0))
  715.  
  716. +                        name_exec = TRUE;
  717.  
  718. +                    else if ((strcmp (*ncursor, "mode1") == 0)
  719.  
  720. +                        && (strcmp (*vcursor, "file") == 0))
  721.  
  722. +                        icon_file = TRUE;
  723.  
  724. +                   else
  725.  
  726. +                        g_set_error (error, G_MARKUP_ERROR,
  727.  
  728. +                            G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
  729.  
  730. +                            "Unknown attribute: %s", *ncursor);
  731.  
  732. +                    ncursor++;
  733.  
  734. +                    vcursor++;
  735.  
  736. +                }
  737.  
  738. +               if (decorate)
  739.  
  740. +               {
  741.  
  742. +                   if (name_exec)
  743.  
  744. +                   {
  745.  
  746. +                       gchar *stdout;
  747.  
  748. +                       if (g_spawn_command_line_sync (parse_expand_tilde(name), &stdout, NULL, NULL, NULL))
  749.  
  750. +                           item = gtk_image_menu_item_new_with_mnemonic (g_strstrip(stdout));
  751.  
  752. +                       else
  753.  
  754. +                           item = gtk_image_menu_item_new_with_mnemonic ("Unable to get output");
  755.  
  756. +                       g_free (stdout);
  757.  
  758. +                   }
  759.  
  760. +                   else
  761.  
  762. +                   {
  763.  
  764. +                       item = gtk_image_menu_item_new_with_mnemonic (name);
  765.  
  766. +                   }
  767.  
  768. +                   if (icon)
  769.  
  770. +                   {
  771.  
  772. +                       if (icon_file) {
  773.  
  774. +                       gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
  775.  
  776. +                       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
  777.  
  778. +                       (item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
  779.  
  780. +                       }
  781.  
  782. +                       else {
  783.  
  784. +                       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
  785.  
  786. +                           gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
  787.  
  788. +                       }
  789.  
  790. +                   }
  791.  
  792. +                   gtk_widget_set_state (item,GTK_STATE_PRELIGHT); /*derive colors from menu hover*/
  793.  
  794. +                   gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu), item);
  795.  
  796. +                   g_free (name);
  797.  
  798. +                   g_free (icon);
  799.  
  800. +               }
  801.  
  802. +               else
  803.  
  804. +               {
  805.  
  806. +                   item = gtk_separator_menu_item_new ();
  807.  
  808. +                   gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu), item);
  809.  
  810. +               }
  811.  
  812. +           }
  813.  
  814. +            break;
  815.  
  816.  
  817.  
  818.          case DESKMENU_ELEMENT_ITEM:
  819.  
  820.  
  821.  
  822. @@ -436,6 +620,18 @@
  823.              if (deskmenu->current_item)
  824.  
  825.                  deskmenu->current_item->current_element = element_type;
  826.  
  827.              break;
  828.  
  829. +        case DESKMENU_ELEMENT_QUANTITY:
  830.  
  831. +            if (deskmenu->current_item)
  832.  
  833. +                deskmenu->current_item->current_element = element_type;
  834.  
  835. +            break;
  836.  
  837. +        case DESKMENU_ELEMENT_SORT:
  838.  
  839. +            if (deskmenu->current_item)
  840.  
  841. +                deskmenu->current_item->current_element = element_type;
  842.  
  843. +            break;
  844.  
  845. +        case DESKMENU_ELEMENT_AGE:
  846.  
  847. +            if (deskmenu->current_item)
  848.  
  849. +                deskmenu->current_item->current_element = element_type;
  850.  
  851. +            break;
  852.  
  853.          default:
  854.  
  855.              g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
  856.  
  857.                  "Unknown element: %s", element_name);
  858.  
  859. @@ -493,10 +689,30 @@
  860.                  g_string_append_len (item->wrap, text, text_len);
  861.  
  862.              break;
  863.  
  864.  
  865.  
  866. +        case DESKMENU_ELEMENT_AGE:
  867.  
  868. +            if (!item->age)
  869.  
  870. +                item->age = g_string_new_len (text, text_len);
  871.  
  872. +            else
  873.  
  874. +                g_string_append_len (item->age, text, text_len);
  875.  
  876. +            break;
  877.  
  878. +
  879.  
  880. +        case DESKMENU_ELEMENT_QUANTITY:
  881.  
  882. +            if (!item->quantity)
  883.  
  884. +                item->quantity = g_string_new_len (text, text_len);
  885.  
  886. +            else
  887.  
  888. +                g_string_append_len (item->quantity, text, text_len);
  889.  
  890. +            break;
  891.  
  892. +
  893.  
  894. +        case DESKMENU_ELEMENT_SORT:
  895.  
  896. +            if (!item->sort_type)
  897.  
  898. +                item->sort_type = g_string_new_len (text, text_len);
  899.  
  900. +            else
  901.  
  902. +                g_string_append_len (item->sort_type, text, text_len);
  903.  
  904. +            break;
  905.  
  906. +
  907.  
  908.          default:
  909.  
  910.              break;
  911.  
  912.      }
  913.  
  914. -
  915.  
  916.  }
  917.  
  918.  
  919.  
  920.  static void
  921.  
  922. @@ -508,7 +724,7 @@
  923.  
  924.  
  925.      DeskmenuElementType element_type;
  926.  
  927.      Deskmenu *deskmenu = DESKMENU (user_data);
  928.  
  929. -    GtkWidget *parent, *item;
  930.  
  931. +    GtkWidget *parent;
  932.  
  933.      element_type = GPOINTER_TO_INT (g_hash_table_lookup
  934.  
  935.          (deskmenu->element_hash, element_name));
  936.  
  937.  
  938.  
  939. @@ -524,13 +740,7 @@
  940.              deskmenu->current_menu = parent;
  941.  
  942.  
  943.  
  944.              break;
  945.  
  946. -
  947.  
  948. -        case DESKMENU_ELEMENT_SEPARATOR:
  949.  
  950. -            item = gtk_separator_menu_item_new ();
  951.  
  952. -            gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
  953.  
  954. -                item);
  955.  
  956. -            break;
  957.  
  958. -
  959.  
  960. +/* separator building is now dealt with in the beginning */
  961.  
  962.          case DESKMENU_ELEMENT_ITEM:
  963.  
  964.  
  965.  
  966.              g_return_if_fail (deskmenu->current_item != NULL);
  967.  
  968. @@ -549,6 +759,12 @@
  969.                  g_string_free (deskmenu->current_item->wrap, TRUE);
  970.  
  971.              if (deskmenu->current_item->vpicon)
  972.  
  973.                  g_string_free (deskmenu->current_item->vpicon, TRUE);
  974.  
  975. +            if (deskmenu->current_item->sort_type)
  976.  
  977. +                g_string_free (deskmenu->current_item->sort_type, TRUE);
  978.  
  979. +            if (deskmenu->current_item->quantity)
  980.  
  981. +                g_string_free (deskmenu->current_item->quantity, TRUE);
  982.  
  983. +            if (deskmenu->current_item->age)
  984.  
  985. +                g_string_free (deskmenu->current_item->age, TRUE);
  986.  
  987.              g_slice_free (DeskmenuItem, deskmenu->current_item);
  988.  
  989.              deskmenu->current_item = NULL;
  990.  
  991.              break;
  992.  
  993. @@ -568,8 +784,8 @@
  994.  };
  995.  
  996.  
  997.  
  998.  
  999.  
  1000. -/* Class init, casts all deskmenu GObject instances with this class structure */
  1001.  
  1002. -static void
  1003.  
  1004. +/* Class init */
  1005.  
  1006. +static void
  1007.  
  1008.  deskmenu_class_init (DeskmenuClass *deskmenu_class)
  1009.  
  1010.  {
  1011.  
  1012.      dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (deskmenu_class),
  1013.  
  1014. @@ -581,15 +797,9 @@
  1015.  deskmenu_init (Deskmenu *deskmenu)
  1016.  
  1017.  {
  1018.  
  1019.  
  1020.  
  1021. -    deskmenu->show_hooks = g_slice_new0 (GHookList);
  1022.  
  1023. -
  1024.  
  1025. -    g_hook_list_init (deskmenu->show_hooks, sizeof (GHook));
  1026.  
  1027. -
  1028.  
  1029. -
  1030.  
  1031.      deskmenu->menu = NULL;
  1032.  
  1033.      deskmenu->current_menu = NULL;
  1034.  
  1035.      deskmenu->current_item = NULL;
  1036.  
  1037. -
  1038.  
  1039.      deskmenu->envp = NULL;
  1040.  
  1041.  
  1042.  
  1043.      deskmenu->item_hash = g_hash_table_new (g_str_hash, g_str_equal);
  1044.  
  1045. @@ -602,6 +812,10 @@
  1046.      g_hash_table_insert (deskmenu->item_hash, "viewportlist",
  1047.  
  1048.          GINT_TO_POINTER (DESKMENU_ITEM_VIEWPORTLIST));
  1049.  
  1050.  #endif
  1051.  
  1052. +    g_hash_table_insert (deskmenu->item_hash, "documents",
  1053.  
  1054. +        GINT_TO_POINTER (DESKMENU_ITEM_DOCUMENTS));
  1055.  
  1056. +    g_hash_table_insert (deskmenu->item_hash, "reload",
  1057.  
  1058. +        GINT_TO_POINTER (DESKMENU_ITEM_RELOAD));
  1059.  
  1060.  
  1061.  
  1062.      deskmenu->element_hash = g_hash_table_new (g_str_hash, g_str_equal);
  1063.  
  1064.      
  1065.  
  1066. @@ -621,214 +835,310 @@
  1067.          GINT_TO_POINTER (DESKMENU_ELEMENT_COMMAND));
  1068.  
  1069.      g_hash_table_insert (deskmenu->element_hash, "wrap",
  1070.  
  1071.          GINT_TO_POINTER (DESKMENU_ELEMENT_WRAP));
  1072.  
  1073. +    g_hash_table_insert (deskmenu->element_hash, "sort",
  1074.  
  1075. +        GINT_TO_POINTER (DESKMENU_ELEMENT_SORT));
  1076.  
  1077. +    g_hash_table_insert (deskmenu->element_hash, "quantity",
  1078.  
  1079. +        GINT_TO_POINTER (DESKMENU_ELEMENT_QUANTITY));
  1080.  
  1081. +    g_hash_table_insert (deskmenu->element_hash, "age",
  1082.  
  1083. +        GINT_TO_POINTER (DESKMENU_ELEMENT_AGE));
  1084.  
  1085. +}
  1086.  
  1087. +
  1088.  
  1089. +static
  1090.  
  1091. +gchar *check_file_cache (gchar *filename) {
  1092.  
  1093. +static GHashTable *cache;
  1094.  
  1095. +gchar *t = NULL;
  1096.  
  1097. +gchar *f = NULL;
  1098.  
  1099. +gchar *user_default = g_build_path (G_DIR_SEPARATOR_S,  g_get_user_config_dir (),
  1100.  
  1101. +                                   "compiz",
  1102.  
  1103. +                                   "boxmenu",
  1104.  
  1105. +                                   "menu.xml",
  1106.  
  1107. +                                   NULL);
  1108.  
  1109.  
  1110.  
  1111. +//TODO: add a size column to cache for possible autorefresh
  1112.  
  1113. +if (!cache)
  1114.  
  1115. +{
  1116.  
  1117. +   g_print("Creating cache...");
  1118.  
  1119. +   cache = g_hash_table_new (g_str_hash, g_str_equal);
  1120.  
  1121. +   g_print("Done creating cache!\n");
  1122.  
  1123. +}
  1124.  
  1125. +else
  1126.  
  1127. +{
  1128.  
  1129. +   g_print("Checking cache...\n");
  1130.  
  1131. +}
  1132.  
  1133. +
  1134.  
  1135. +if (strlen(filename) == 0) {
  1136.  
  1137. +   g_print("No filename supplied, looking up default menu...\n");
  1138.  
  1139. +       /*
  1140.  
  1141. +        set default filename to be [configdir]/compiz/boxmenu/menu.xml
  1142.  
  1143. +        */
  1144.  
  1145. +        filename = user_default;
  1146.  
  1147. +        gboolean success = FALSE;
  1148.  
  1149. +    if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
  1150.  
  1151. +           g_print("Getting default system menu...\n");
  1152.  
  1153. +           const gchar* const *cursor = g_get_system_config_dirs ();
  1154.  
  1155. +           gchar *path = NULL;
  1156.  
  1157. +           while (*cursor)
  1158.  
  1159. +           {
  1160.  
  1161. +               g_free (path);
  1162.  
  1163. +               path = g_strdup (*cursor);
  1164.  
  1165. +               filename = g_build_path (G_DIR_SEPARATOR_S,
  1166.  
  1167. +                                       path,
  1168.  
  1169. +                                       "compiz",
  1170.  
  1171. +                                       "boxmenu",
  1172.  
  1173. +                                       "menu.xml",
  1174.  
  1175. +                                       NULL);
  1176.  
  1177. +      
  1178.  
  1179. +               if (g_file_get_contents (filename, &f, NULL, NULL))
  1180.  
  1181. +               {
  1182.  
  1183. +                   g_hash_table_insert (cache, g_strdup(filename), g_strdup(f));
  1184.  
  1185. +                   g_free (path);
  1186.  
  1187. +                   g_print("Got it!\n");
  1188.  
  1189. +                   success = TRUE;
  1190.  
  1191. +                   break;
  1192.  
  1193. +               }
  1194.  
  1195. +                   cursor++;
  1196.  
  1197. +           }
  1198.  
  1199. +       }
  1200.  
  1201. +   else
  1202.  
  1203. +       {
  1204.  
  1205. +           if (!g_hash_table_lookup_extended(cache, user_default, NULL, NULL))
  1206.  
  1207. +           {
  1208.  
  1209. +               g_file_get_contents (filename, &f, NULL, NULL);
  1210.  
  1211. +               g_print("Cacheing default user file...\n");
  1212.  
  1213. +               g_hash_table_insert (cache, g_strdup(filename), g_strdup(f));
  1214.  
  1215. +           }
  1216.  
  1217. +           g_print("Retrieving cached default user file...\n");
  1218.  
  1219. +           success = TRUE;
  1220.  
  1221. +       }
  1222.  
  1223. +   if (!success)
  1224.  
  1225. +   {
  1226.  
  1227. +       g_printerr ("Couldn't find a menu file...\n");
  1228.  
  1229. +       exit (1);      
  1230.  
  1231. +   }
  1232.  
  1233. +}
  1234.  
  1235. +else {
  1236.  
  1237. +   if (!g_hash_table_lookup_extended(cache, filename, NULL, NULL)) {
  1238.  
  1239. +       if (g_file_get_contents (filename, &f, NULL, NULL))
  1240.  
  1241. +           {
  1242.  
  1243. +               g_print("Cacheing new non-default file...\n");
  1244.  
  1245. +               g_hash_table_insert (cache, g_strdup(filename), g_strdup(f));
  1246.  
  1247. +           }
  1248.  
  1249. +           else {
  1250.  
  1251. +               if (g_hash_table_lookup_extended(cache, user_default, NULL, NULL))
  1252.  
  1253. +               {
  1254.  
  1255. +                   g_print("Couldn't find specified file, loading default...\n");
  1256.  
  1257. +                   filename = user_default;
  1258.  
  1259. +               }
  1260.  
  1261. +               else
  1262.  
  1263. +               {
  1264.  
  1265. +                   g_printerr ("Couldn't find a menu file...\n");
  1266.  
  1267. +                   exit (1);
  1268.  
  1269. +               }
  1270.  
  1271. +           }
  1272.  
  1273. +   }
  1274.  
  1275. +}
  1276.  
  1277. +
  1278.  
  1279. +t = g_hash_table_lookup (cache, filename);
  1280.  
  1281. +
  1282.  
  1283. +g_printf("Done loading %s!\n", filename);
  1284.  
  1285. +g_free (f);
  1286.  
  1287. +g_free (filename);
  1288.  
  1289. +
  1290.  
  1291. +return t;
  1292.  
  1293.  }
  1294.  
  1295.  
  1296.  
  1297.  static void
  1298.  
  1299. -deskmenu_parse_file (Deskmenu *deskmenu,
  1300.  
  1301. -                     gchar *configpath)
  1302.  
  1303. +deskmenu_parse_text (Deskmenu *deskmenu, gchar *text)
  1304.  
  1305.  {
  1306.  
  1307.      GError *error = NULL;
  1308.  
  1309. -    gboolean success = FALSE;
  1310.  
  1311. -    gchar *text, *exec, *stdout;
  1312.  
  1313. -    gsize length;
  1314.  
  1315. +    gchar *exec, *stdout, *pipe_error;
  1316.  
  1317.     GRegex *regex, *command;
  1318.  
  1319. -   int i;
  1320.  
  1321. -
  1322.  
  1323. -    if (!configpath)
  1324.  
  1325. -        configpath = g_build_path (G_DIR_SEPARATOR_S,
  1326.  
  1327. -                                   g_get_user_config_dir (),
  1328.  
  1329. -                                   "compiz",
  1330.  
  1331. -                                   "deskmenu",
  1332.  
  1333. -                                   "menu.xml",
  1334.  
  1335. -                                   NULL);
  1336.  
  1337. +   int i = 0;
  1338.  
  1339.  
  1340.  
  1341.      GMarkupParseContext *context = g_markup_parse_context_new (&parser,
  1342.  
  1343.          0, deskmenu, NULL);
  1344.  
  1345. -
  1346.  
  1347. -    if (!g_file_get_contents (configpath, &text, &length, NULL))
  1348.  
  1349. -    {
  1350.  
  1351. -        const gchar* const *cursor = g_get_system_config_dirs ();
  1352.  
  1353. -        gchar *path = NULL;
  1354.  
  1355. -        while (*cursor)
  1356.  
  1357. -        {
  1358.  
  1359. -            g_free (configpath);
  1360.  
  1361. -            g_free (path);
  1362.  
  1363. -            path = g_strdup (*cursor);
  1364.  
  1365. -            configpath = g_build_path (G_DIR_SEPARATOR_S,
  1366.  
  1367. -                                       path,
  1368.  
  1369. -                                       "compiz",
  1370.  
  1371. -                                       "deskmenu",
  1372.  
  1373. -                                       "menu.xml",
  1374.  
  1375. -                                       NULL);
  1376.  
  1377. -
  1378.  
  1379. -            if (g_file_get_contents (configpath, &text, &length, NULL))
  1380.  
  1381. -            {
  1382.  
  1383. -                success = TRUE;
  1384.  
  1385. -                g_free (path);
  1386.  
  1387. -                break;
  1388.  
  1389. -            }
  1390.  
  1391. -            cursor++;
  1392.  
  1393. -        }
  1394.  
  1395. -    }
  1396.  
  1397. -    else
  1398.  
  1399. -    {
  1400.  
  1401. -        success = TRUE;
  1402.  
  1403. -    }
  1404.  
  1405. -
  1406.  
  1407. -    if (!success)
  1408.  
  1409. -    {
  1410.  
  1411. -        g_printerr ("Couldn't find a menu file\n");
  1412.  
  1413. -        exit (1);
  1414.  
  1415. -    }
  1416.  
  1417.      
  1418.  
  1419. -   i = 0;
  1420.  
  1421. +   pipe_error = g_strdup ("<item type=\"launcher\"><name>Cannot retrieve pipe output</name></item>");
  1422.  
  1423.     regex = g_regex_new("(<pipe command=\".*\"/>)", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
  1424.  
  1425.     command = g_regex_new("<pipe command=\"|\"/>", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
  1426.  
  1427. -   //gchar **menu_chunk = g_regex_split (regex,"<menu><pipe command=\"/home/shadowkyogre/bin/test.sh\"/><item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command><item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command><item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command><item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command></menu>",0); //this splits the thing, test code if you want to use it
  1428.  
  1429.     gchar **menu_chunk = g_regex_split (regex, text, 0); //this splits the menu into parsable chunks, needed for pipe item capabilities
  1430.  
  1431. -   g_free(text); //we no longer need the loaded file
  1432.  
  1433. +  
  1434.  
  1435.     //this loop will replace the pipeitem chunk with its output, other chunks are let through as is
  1436.  
  1437.     while (menu_chunk[i])
  1438.  
  1439.     {
  1440.  
  1441.         if (g_regex_match (regex,menu_chunk[i],0,0))
  1442.  
  1443.         {
  1444.  
  1445. -            //they only exist in this loop
  1446.  
  1447.              exec = parse_expand_tilde(g_strstrip(g_regex_replace_literal(command, menu_chunk[i], -1, 0, "", 0, NULL)));
  1448.  
  1449. -            g_spawn_command_line_sync (exec, &stdout, NULL, NULL, NULL);
  1450.  
  1451. -            menu_chunk[i] = stdout;
  1452.  
  1453. +           if (g_spawn_command_line_sync (exec, &stdout, NULL, NULL, NULL))
  1454.  
  1455. +           {
  1456.  
  1457. +               menu_chunk[i] = stdout;
  1458.  
  1459. +           }
  1460.  
  1461. +           else
  1462.  
  1463. +           {
  1464.  
  1465. +               menu_chunk[i] = pipe_error;
  1466.  
  1467. +           }
  1468.  
  1469. +            //fix this to be able to replace faulty pipe with an item that says it can't be executed
  1470.  
  1471. +            //needs validator in order to make sure it can be parsed, if not, set parsed error
  1472.  
  1473.         }
  1474.  
  1475.         i++;
  1476.  
  1477.     }
  1478.  
  1479. -   g_regex_unref(regex); //free the pipeitem chunk checker
  1480.  
  1481. -   g_regex_unref(command); //free the pipe command extractor
  1482.  
  1483. +   text = g_strjoinv (NULL, menu_chunk); //stitch the text so we can get error reporting back to normal
  1484.  
  1485.    
  1486.  
  1487. -//the idea for the pipeitem method came from this experiment below
  1488.  
  1489. -/*
  1490.  
  1491. -g_markup_parse_context_parse (context, "<menu>", 6, &error);
  1492.  
  1493. -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
  1494.  
  1495. -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
  1496.  
  1497. -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
  1498.  
  1499. -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
  1500.  
  1501. -g_markup_parse_context_parse (context, "</menu>", 7, &error);
  1502.  
  1503. -*/
  1504.  
  1505. -   i = 0;
  1506.  
  1507. -   while (menu_chunk[i])
  1508.  
  1509. -   {
  1510.  
  1511. -       g_markup_parse_context_parse (context, menu_chunk[i], strlen(menu_chunk[i]), &error);
  1512.  
  1513. -       //fix error reporting here, otherwise, it works fine
  1514.  
  1515. -       i++;
  1516.  
  1517. -   }
  1518.  
  1519. -
  1520.  
  1521. -/*old menu functionality
  1522.  
  1523. -    if (!g_markup_parse_context_parse (context, text, length, &error)
  1524.  
  1525. +   if (!g_markup_parse_context_parse (context, text, strlen(text), &error)
  1526.  
  1527.          || !g_markup_parse_context_end_parse (context, &error))
  1528.  
  1529.      {
  1530.  
  1531. -        g_printerr ("Parse of %s failed with message: %s \n",
  1532.  
  1533. -            configpath, error->message);
  1534.  
  1535. +        g_printerr ("Parse failed with message: %s \n", error->message);
  1536.  
  1537.          g_error_free (error);
  1538.  
  1539.          exit (1);
  1540.  
  1541.      }
  1542.  
  1543. -  */  
  1544.  
  1545. +
  1546.  
  1547. +   g_free(text); //free the joined array
  1548.  
  1549.     g_strfreev(menu_chunk); //free the menu chunks and their container
  1550.  
  1551. -    g_free (configpath); //free the file path
  1552.  
  1553. +   g_regex_unref(regex); //free the pipeitem chunk checker
  1554.  
  1555. +   g_regex_unref(command); //free the pipe command extractor
  1556.  
  1557.      g_markup_parse_context_free (context); //free the parser
  1558.  
  1559.  
  1560.  
  1561.      gtk_widget_show_all (deskmenu->menu);
  1562.  
  1563.  }
  1564.  
  1565.  
  1566.  
  1567.  /* The show method */
  1568.  
  1569. -gboolean
  1570.  
  1571. +static void
  1572.  
  1573.  deskmenu_show (Deskmenu *deskmenu,
  1574.  
  1575. -               gchar **env,
  1576.  
  1577.                 GError  **error)
  1578.  
  1579.  {
  1580.  
  1581. -    g_hook_list_invoke (deskmenu->show_hooks, FALSE);
  1582.  
  1583. -
  1584.  
  1585. -    if (deskmenu->envp)
  1586.  
  1587. -        g_strfreev (deskmenu->envp);
  1588.  
  1589. -
  1590.  
  1591. -    deskmenu->envp = g_strdupv (env);
  1592.  
  1593. -
  1594.  
  1595.      gtk_menu_popup (GTK_MENU (deskmenu->menu),
  1596.  
  1597.                      NULL, NULL, NULL, NULL,
  1598.  
  1599.                      0, 0);
  1600.  
  1601. +}
  1602.  
  1603. +
  1604.  
  1605. +gboolean
  1606.  
  1607. +deskmenu_reload (Deskmenu *deskmenu,
  1608.  
  1609. +               GError  **error)
  1610.  
  1611. +{
  1612.  
  1613. +    gtk_main_quit ();
  1614.  
  1615.      return TRUE;
  1616.  
  1617.  }
  1618.  
  1619.  
  1620.  
  1621. +/* The dbus method for binary client */
  1622.  
  1623. +gboolean
  1624.  
  1625. +deskmenu_control (Deskmenu *deskmenu, gchar **env, gchar *filename, GError  **error)
  1626.  
  1627. +{
  1628.  
  1629. +   if (deskmenu->menu)
  1630.  
  1631. +   {
  1632.  
  1633. +       deskmenu->menu = NULL;
  1634.  
  1635. +   }
  1636.  
  1637. +   deskmenu_parse_text(deskmenu, check_file_cache(g_strdup(filename))); //recreate the menu, check caches for data
  1638.  
  1639. +  
  1640.  
  1641. +   if (deskmenu->envp)
  1642.  
  1643. +        g_strfreev (deskmenu->envp);
  1644.  
  1645. +    deskmenu->envp = g_strdupv (env);
  1646.  
  1647. +    
  1648.  
  1649. +   deskmenu_show(deskmenu, error);
  1650.  
  1651. +   return TRUE;
  1652.  
  1653. +}
  1654.  
  1655. +
  1656.  
  1657. +
  1658.  
  1659. +//precache backend, currently needs GUI
  1660.  
  1661. +static void
  1662.  
  1663. +deskmenu_precache (gchar *filename)
  1664.  
  1665. +{
  1666.  
  1667. +   GError *error = NULL;
  1668.  
  1669. +   GKeyFile *config = g_key_file_new ();
  1670.  
  1671. +   int i;
  1672.  
  1673. +  
  1674.  
  1675. +// (void *)check_file_cache(""); //always cache default menu
  1676.  
  1677. +  
  1678.  
  1679. +   g_print("Attempting to precache files in config...");
  1680.  
  1681. +   if (!filename)
  1682.  
  1683. +   {
  1684.  
  1685. +       filename = g_build_path (G_DIR_SEPARATOR_S,
  1686.  
  1687. +                                   g_get_user_config_dir (),
  1688.  
  1689. +                                   "compiz",
  1690.  
  1691. +                                   "boxmenu",
  1692.  
  1693. +                                   "precache.ini",
  1694.  
  1695. +                                   NULL);
  1696.  
  1697. +   }
  1698.  
  1699. +   if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, NULL))
  1700.  
  1701. +   {
  1702.  
  1703. +       g_print("Configuration not found, will not precache files...");
  1704.  
  1705. +       g_key_file_free (config);
  1706.  
  1707. +   }
  1708.  
  1709. +   else
  1710.  
  1711. +   {
  1712.  
  1713. +       g_print("Configuration found! Starting precache...");
  1714.  
  1715. +       gchar **files = g_key_file_get_keys (config, "Files", NULL, &error);
  1716.  
  1717. +       gchar *feed;
  1718.  
  1719. +      
  1720.  
  1721. +       while (files[i])
  1722.  
  1723. +       {
  1724.  
  1725. +           feed = g_key_file_get_string (config, "Files", files[i], &error);
  1726.  
  1727. +           (void *)check_file_cache(parse_expand_tilde(feed));
  1728.  
  1729. +           i++;
  1730.  
  1731. +       }
  1732.  
  1733. +       g_strfreev(files);
  1734.  
  1735. +       g_free(feed);
  1736.  
  1737. +       g_key_file_free (config);
  1738.  
  1739. +   }
  1740.  
  1741. +}
  1742.  
  1743. +
  1744.  
  1745.  int
  1746.  
  1747.  main (int    argc,
  1748.  
  1749.        char **argv)
  1750.  
  1751.  {
  1752.  
  1753. -    DBusGConnection *connection;
  1754.  
  1755. +   DBusGConnection *connection;
  1756.  
  1757.      GError *error = NULL;
  1758.  
  1759.      GObject *deskmenu;
  1760.  
  1761.  
  1762.  
  1763.      g_type_init ();
  1764.  
  1765. +
  1766.  
  1767. +    connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
  1768.  
  1769. +    if (connection == NULL)
  1770.  
  1771. +    {
  1772.  
  1773. +        g_printerr ("Failed to open connection to bus: %s", error->message);
  1774.  
  1775. +        g_error_free (error);
  1776.  
  1777. +        exit (1);
  1778.  
  1779. +    }
  1780.  
  1781. +//gtk_tearoff_menu_item_new();
  1782.  
  1783. +   g_print ("Starting the daemon...\n");
  1784.  
  1785.  
  1786.  
  1787. -    gchar *filename = NULL;
  1788.  
  1789. -    GOptionContext *context;
  1790.  
  1791. +   GOptionContext *context;
  1792.  
  1793. +   gchar *file = NULL;
  1794.  
  1795.      GOptionEntry entries[] =
  1796.  
  1797.      {
  1798.  
  1799. -        { "menu", 'm', 0, G_OPTION_ARG_FILENAME, &filename,
  1800.  
  1801. -            "Use FILE instead of the default menu file", "FILE" },
  1802.  
  1803. +        { "config", 'c', 0, G_OPTION_ARG_FILENAME, &file,
  1804.  
  1805. +            "Use FILE instead of the default daemon configuration", "FILE" },
  1806.  
  1807.          { NULL, 0, 0, 0, NULL, NULL, NULL }
  1808.  
  1809.      };
  1810.  
  1811.  
  1812.  
  1813.      context = g_option_context_new (NULL);
  1814.  
  1815.      g_option_context_add_main_entries (context, entries, NULL);
  1816.  
  1817. -    g_option_context_add_group (context, gtk_get_option_group (TRUE));
  1818.  
  1819. +   error = NULL;
  1820.  
  1821.      if (!g_option_context_parse (context, &argc, &argv, &error))
  1822.  
  1823.      {
  1824.  
  1825.          g_printerr ("option parsing failed: %s", error->message);
  1826.  
  1827.          g_error_free (error);
  1828.  
  1829. -        exit (1);
  1830.  
  1831. -    }
  1832.  
  1833. -    g_option_context_free (context);
  1834.  
  1835. -
  1836.  
  1837. -    /* Obtain a connection to the session bus */
  1838.  
  1839. -    connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
  1840.  
  1841. -    if (connection == NULL)
  1842.  
  1843. -    {
  1844.  
  1845. -        g_printerr ("Failed to open connection to bus: %s", error->message);
  1846.  
  1847. -        g_error_free (error);
  1848.  
  1849. -        exit (1);
  1850.  
  1851. -    }
  1852.  
  1853. +        return 1;
  1854.  
  1855. +    } 
  1856.  
  1857. +   g_option_context_free (context);
  1858.  
  1859.  
  1860.  
  1861.  #if HAVE_WNCK
  1862.  
  1863.      wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER);
  1864.  
  1865.  #endif
  1866.  
  1867.  
  1868.  
  1869.      gtk_init (&argc, &argv);
  1870.  
  1871. -
  1872.  
  1873. +  
  1874.  
  1875.      deskmenu = g_object_new (DESKMENU_TYPE, NULL);
  1876.  
  1877. -    
  1878.  
  1879. -    //deskmenu_init(DESKMENU (deskmenu));
  1880.  
  1881. -
  1882.  
  1883. -    deskmenu_parse_file (DESKMENU (deskmenu), filename);
  1884.  
  1885.  
  1886.  
  1887. -    dbus_g_connection_register_g_object (connection,
  1888.  
  1889. -                                         DESKMENU_PATH_DBUS,
  1890.  
  1891. -                                         deskmenu);
  1892.  
  1893. -/*clues
  1894.  
  1895. - * http://library.gnome.org/devel/dbus-glib/unstable/dbus-glib-DBusGConnection.html#dbus-g-connection-register-g-object
  1896.  
  1897. - * http://library.gnome.org/devel/dbus-glib/unstable/dbus-glib-dbus-gobject.html#dbus-g-object-type-install-info
  1898.  
  1899. - * Install introspection information about the given object GType sufficient to allow methods on the object to be invoked by name. The introspection information is normally generated by dbus-glib-tool, then this function is called in the class_init() for the object class.
  1900.  
  1901. +    dbus_g_connection_register_g_object (connection, DESKMENU_PATH_DBUS, deskmenu);
  1902.  
  1903.  
  1904.  
  1905. -Once introspection information has been installed, instances of the object registered with #dbus_g_connection_register_g_object() can have their methods invoked remotely.
  1906.  
  1907. -
  1908.  
  1909. -object_type :
  1910.  
  1911. -   GType for the object
  1912.  
  1913. -
  1914.  
  1915. -info :
  1916.  
  1917. -   introspection data generated by dbus-glib-tool
  1918.  
  1919. - */
  1920.  
  1921.     if (!dbus_bus_request_name (dbus_g_connection_get_connection (connection),
  1922.  
  1923.                                 DESKMENU_SERVICE_DBUS,
  1924.  
  1925.                                  DBUS_NAME_FLAG_REPLACE_EXISTING,
  1926.  
  1927.                                 NULL))
  1928.  
  1929.          return 1;
  1930.  
  1931.  
  1932.  
  1933. +   deskmenu_precache(file);
  1934.  
  1935. +
  1936.  
  1937.      gtk_main ();
  1938.  
  1939.  
  1940.  
  1941.      return 0;
  1942.  
  1943. diff -aur compiz-deskmenu2/deskmenu-menu.h compiz-boxmenu/deskmenu-menu.h
  1944. --- compiz-deskmenu2/deskmenu-menu.h    2010-11-15 22:21:44.000000000 -0800
  1945. +++ compiz-boxmenu/deskmenu-menu.h  2010-12-01 15:01:03.000000000 -0800
  1946. @@ -28,7 +28,9 @@
  1947.      DESKMENU_ITEM_NONE = 0,
  1948.      DESKMENU_ITEM_LAUNCHER,
  1949.      DESKMENU_ITEM_WINDOWLIST,
  1950. -    DESKMENU_ITEM_VIEWPORTLIST
  1951. +    DESKMENU_ITEM_VIEWPORTLIST,
  1952. +    DESKMENU_ITEM_RELOAD,
  1953. +    DESKMENU_ITEM_DOCUMENTS //use native GTK+ support for recent documents
  1954.  } DeskmenuItemType;
  1955.  
  1956.  typedef enum
  1957. @@ -41,7 +43,10 @@
  1958.      DESKMENU_ELEMENT_ICON,
  1959.      DESKMENU_ELEMENT_COMMAND,
  1960.      DESKMENU_ELEMENT_WRAP,
  1961. -    DESKMENU_ELEMENT_VPICON
  1962. +    DESKMENU_ELEMENT_VPICON,
  1963. +    DESKMENU_ELEMENT_AGE, //age of dox
  1964. +    DESKMENU_ELEMENT_QUANTITY, //# of dox
  1965. +    DESKMENU_ELEMENT_SORT //sort method
  1966.  } DeskmenuElementType;
  1967.  
  1968.  
  1969. @@ -57,6 +62,9 @@
  1970.      GString *vpicon;
  1971.      GString *command;
  1972.      GString *wrap;
  1973. +    GString *sort_type; //get sort type for document items
  1974. +   GString *age;  //get age limit for document items
  1975. +   GString *quantity; //get item limit for document items
  1976.  };
  1977.  
  1978.  struct Deskmenu
  1979. @@ -68,10 +76,9 @@
  1980.      GtkWidget *menu;
  1981.      GtkWidget *current_menu;
  1982.      DeskmenuItem *current_item;
  1983. +    gchar **envp;
  1984.      GHashTable *item_hash;
  1985.      GHashTable *element_hash;
  1986. -    GHookList *show_hooks;
  1987. -    gchar **envp;
  1988.  };
  1989.  
  1990.  struct DeskmenuClass
  1991. @@ -95,5 +102,5 @@
  1992.  GQuark deskmenu_error_quark (void);
  1993.  #define DESKMENU_ERROR deskmenu_error_quark ()
  1994.  
  1995. -
  1996. -gboolean deskmenu_show (Deskmenu *deskmenu, gchar **env, GError **error);
  1997. +gboolean deskmenu_reload (Deskmenu *deskmenu, GError **error);
  1998. +gboolean deskmenu_control (Deskmenu *deskmenu, gchar **env, gchar *filename, GError  **error);
  1999. diff -aur compiz-deskmenu2/deskmenu-service.xml compiz-boxmenu/deskmenu-service.xml
  2000. --- compiz-deskmenu2/deskmenu-service.xml   2010-11-13 20:50:48.000000000 -0800
  2001. +++ compiz-boxmenu/deskmenu-service.xml 2010-12-01 15:06:49.000000000 -0800
  2002. @@ -1,10 +1,13 @@
  2003.  <?xml version="1.0" encoding="UTF-8" ?>
  2004.  
  2005. -<node name="/org/compiz_fusion/deskmenu/menu">
  2006. -  <interface name="org.compiz_fusion.deskmenu">
  2007. +<node name="/org/compiz_fusion/boxmenu/menu">
  2008. +  <interface name="org.compiz_fusion.boxmenu">
  2009.      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="deskmenu"/>
  2010. -    <method name="show">
  2011. +    <method name="control">
  2012.        <arg type="as" name="env" direction="in" />
  2013. +      <arg type="s" name="filename" direction="in" />
  2014. +    </method>
  2015. +    <method name="reload">
  2016.      </method>
  2017.    </interface>
  2018.  </node>
  2019. diff -aur compiz-deskmenu2/deskmenu-wnck.c compiz-boxmenu/deskmenu-wnck.c
  2020. --- compiz-deskmenu2/deskmenu-wnck.c    2010-11-15 18:46:24.000000000 -0800
  2021. +++ compiz-boxmenu/deskmenu-wnck.c  2010-12-01 14:39:46.000000000 -0800
  2022. @@ -74,7 +74,13 @@
  2023.  
  2024.    return width;
  2025.  }
  2026. +/*
  2027. +(compiz-boxmenu-daemon:23915): GLib-GObject-WARNING **: invalid cast from `PangoLayout' to `GtkLabel'
  2028.  
  2029. +(compiz-boxmenu-daemon:23915): Gtk-CRITICAL **: IA__gtk_label_set_text_with_mnemonic: assertion `GTK_IS_LABEL (label)' failed
  2030. +
  2031. +(compiz-boxmenu-daemon:23915): Gtk-CRITICAL **: IA__gtk_widget_set_size_request: assertion `GTK_IS_WIDGET (widget)' fai
  2032. +*/
  2033.  /* end borrowing */
  2034.  
  2035.  static void
  2036. @@ -93,7 +99,6 @@
  2037.      GString *name;
  2038.      gchar *namecpy, *mnemonic, *decorated_name, *unescaped;
  2039.      guint i, n;
  2040. -
  2041.      name = g_string_new (wnck_window_get_name (dmwin->window));
  2042.      
  2043.      namecpy = g_strdup (name->str);
  2044. @@ -115,16 +120,9 @@
  2045.          mnemonic = "";
  2046.          //wnck_window_get_workspace (dmwin->window)
  2047.          //TODO: get this to calculate right
  2048. -   /* 
  2049. -    column = wnck_workspace_get_viewport_x (wnck_window_get_workspace (dmwin->window));
  2050. -    width = wnck_workspace_get_width (wnck_screen_get_workspace (wnck_screen_get_default (), 0))/wnck_screen_get_width (wnck_screen_get_default ());
  2051. -    row = wnck_workspace_get_viewport_y (wnck_window_get_workspace (dmwin->window));
  2052. -   vpidNumber = column + ((row) * width);
  2053. -    vpid = g_strdup_printf ("%d %d %d %d :",vpidNumber,width,column,row);
  2054. -   g_print(vpid);
  2055. -   decorated_name = g_strconcat ("[",vpid, "] ", ante, mnemonic, name->str, post, NULL);
  2056. -   */
  2057. -    decorated_name = g_strconcat (ante, mnemonic, name->str, post, NULL);
  2058. +
  2059. +   decorated_name = g_strconcat (ante, mnemonic, name->str, post, NULL);
  2060. +    //decorated_name = g_strconcat (ante, mnemonic, name->str, post, NULL);
  2061.  
  2062.      unescaped = g_strconcat (ante, wnck_window_get_name (dmwin->window),
  2063.          post, NULL);
  2064. @@ -173,6 +171,7 @@
  2065.      }
  2066.      else
  2067.          dmwin_set_decoration (dmwin, "", "");
  2068. +
  2069.  }
  2070.  
  2071.  static void
  2072. @@ -188,7 +187,7 @@
  2073.         pixbuf = wnck_selector_dimm_icon (pixbuf);
  2074.         free_pixbuf = TRUE;
  2075.     }
  2076. -  
  2077. +
  2078.     gtk_image_set_from_pixbuf (GTK_IMAGE (dmwin->image), pixbuf);
  2079.    
  2080.     if (free_pixbuf)
  2081. @@ -345,7 +344,7 @@
  2082.      windowlist->screen = wnck_screen_get_default ();
  2083.  
  2084.      windowlist->menu = gtk_menu_new ();
  2085. -
  2086. +//does not emit signals 2nd time around
  2087.      g_signal_connect (G_OBJECT (windowlist->screen), "window-opened",
  2088.          G_CALLBACK (screen_window_opened), windowlist);
  2089.  
  2090. @@ -558,13 +557,12 @@
  2091.      if (new_count > vplist->old_count)
  2092.      {
  2093.          gchar *text;
  2094. -//TODO: edit this section to add thumnbnails for ports, possibly just set the thumbnails to be viewport wallpapers?
  2095.          for (i = vplist->old_count; i < new_count; i++)
  2096.          {
  2097.              text = g_strdup_printf ("Viewport _%i", i + 1);
  2098.              item = gtk_image_menu_item_new_with_mnemonic (text);
  2099.              if (vplist->images)
  2100. -            { //this'll set viewport thumbnail later if I can figure out how
  2101. +            {
  2102.                 if (vplist->icon){
  2103.                     if (vplist->file) {
  2104.                         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
  2105. @@ -647,7 +645,7 @@
  2106.          gtk_separator_menu_item_new ());
  2107.  
  2108.      vplist->goto_items = g_ptr_array_new ();
  2109. -
  2110. +//does not go here
  2111.      g_signal_connect (G_OBJECT (vplist->screen), "viewports-changed",
  2112.          G_CALLBACK (deskmenu_vplist_update), vplist);
  2113.  
  2114. diff -aur compiz-deskmenu2/deskmenu.c compiz-boxmenu/deskmenu.c
  2115. --- compiz-deskmenu2/deskmenu.c 2010-11-10 18:07:24.000000000 -0800
  2116. +++ compiz-boxmenu/deskmenu.c   2010-12-01 15:24:32.000000000 -0800
  2117. @@ -14,7 +14,6 @@
  2118.   *
  2119.   * Copyright 2008 Christopher Williams <[email protected]>
  2120.   */
  2121. -
  2122.  #include <dbus/dbus-glib.h>
  2123.  #include <unistd.h>
  2124.  
  2125. @@ -24,14 +23,26 @@
  2126.  
  2127.  int main (int argc, char *argv[])
  2128.  {
  2129. -    DBusGConnection *connection;
  2130. -    GError *error;
  2131. -    DBusGProxy *proxy;
  2132. -
  2133. +   DBusGConnection *connection;
  2134. +   GError *error;
  2135. +   DBusGProxy *proxy;
  2136. +   gchar *filename = NULL;
  2137. +  
  2138.      usleep (200000);
  2139.  
  2140.      g_type_init ();
  2141.  
  2142. +    GOptionContext *context;
  2143. +    GOptionEntry entries[] =
  2144. +    {
  2145. +        { "menu", 'm', 0, G_OPTION_ARG_FILENAME, &filename,
  2146. +            "Use FILE instead of the default menu file", "FILE" },
  2147. +        { NULL, 0, 0, 0, NULL, NULL, NULL }
  2148. +    };
  2149. +
  2150. +    context = g_option_context_new (NULL);
  2151. +    g_option_context_add_main_entries (context, entries, NULL);
  2152. +
  2153.      error = NULL;
  2154.      connection = dbus_g_bus_get (DBUS_BUS_SESSION,
  2155.                                 &error);
  2156. @@ -49,15 +60,25 @@
  2157.                                         DESKMENU_INTERFACE_DBUS);
  2158.  
  2159.      error = NULL;
  2160. -    if (!dbus_g_proxy_call (proxy, "show", &error, G_TYPE_STRV, environ,
  2161. +    
  2162. +    
  2163. +    if (!g_option_context_parse (context, &argc, &argv, &error))
  2164. +    {
  2165. +        g_printerr ("option parsing failed: %s", error->message);
  2166. +        g_error_free (error);
  2167. +        return 1;
  2168. +    }
  2169. +    
  2170. +    if (!dbus_g_proxy_call (proxy, "control", &error, G_TYPE_STRV, environ, G_TYPE_STRING, filename,
  2171.          G_TYPE_INVALID, G_TYPE_INVALID))
  2172.      {
  2173.          g_printerr ("Error: %s\n", error->message);
  2174.          g_error_free (error);
  2175.          return 1;
  2176.      }
  2177. -
  2178. -    g_object_unref (proxy);
  2179. +  
  2180. +  g_option_context_free (context);
  2181. +  g_object_unref (proxy);
  2182.  
  2183.      return 0;
  2184.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement