Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -aur compiz-deskmenu2/deskmenu-menu.c compiz-boxmenu/deskmenu-menu.c
- --- compiz-deskmenu2/deskmenu-menu.c 2010-12-01 15:31:32.000000000 -0800
- +++ compiz-boxmenu/deskmenu-menu.c 2010-12-01 15:11:05.000000000 -0800
- @@ -18,13 +18,10 @@
- /*
- Roadmap:
- Necessary:
- - TODO: Get rid of dbus reload and show method for pipemenus to work as intended
- - TODO: Add tilde expansion for icons in both the editor and the menu difficulty: easy
- - TODO: Add a viewport # indicator for the window list for accesiblity reasons difficulty: easy
- + TODO: Add a viewport # indicator for the window list for accesiblity reasons difficulty: hard
- TODO: Add configuration for menu icon size difficulty: easy
- TODO: Add toggle of tearables difficulty: easy
- TODO: Add a sane icon dialog difficulty: medium-hard
- - TODO: Add icon choice for viewports: easy
- For fun, might not implement:
- TODO: Add ability to call up menus from the menu.xml file by name, if this is really, really needed or requested
- */
- @@ -44,7 +41,9 @@
- #include "deskmenu-glue.h"
- -G_DEFINE_TYPE(Deskmenu, deskmenu, G_TYPE_OBJECT)
- +G_DEFINE_TYPE(Deskmenu, deskmenu, G_TYPE_OBJECT) //this is calling deskmenu_class_init
- +
- +//launcher.c is the file to look for apwal mode for deskmenu
- GQuark
- deskmenu_error_quark (void)
- @@ -63,6 +62,8 @@
- }
- //stolen from openbox, possibly move this outside in order to make it a function to parse launchers and icon location
- +//optimize code to reduce calls to this, should only be called once per parse
- +static
- gchar *parse_expand_tilde(const gchar *f)
- {
- gchar *ret;
- @@ -70,7 +71,6 @@
- if (!f)
- return NULL;
- -
- regex = g_regex_new("(?:^|(?<=[ \\t]))~(?:(?=[/ \\t])|$)",
- G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
- ret = g_regex_replace_literal(regex, f, -1, 0, g_get_home_dir(), 0, NULL);
- @@ -86,9 +86,7 @@
- gchar *command)
- {
- GError *error = NULL;
- - Deskmenu *deskmenu;
- -
- - deskmenu = g_object_get_data (G_OBJECT (widget), "deskmenu");
- +
- if (!gdk_spawn_command_line_on_screen (gdk_screen_get_default (), parse_expand_tilde(command), &error))
- {
- GtkWidget *message = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
- @@ -99,17 +97,43 @@
- }
- -//place & in front of stdout for standard stdout, how a command is launched as an exec
- +//This is how a recent document is opened
- static void
- -launcher_name_exec_update (GtkWidget *label)
- +recent_activated (GtkRecentChooser *chooser,
- + gchar *command)
- {
- - gchar *exec, *stdout;
- - exec = g_object_get_data (G_OBJECT (label), "exec");
- - if (g_spawn_command_line_sync (parse_expand_tilde(exec), &stdout, NULL, NULL, NULL))
- - gtk_label_set_text (GTK_LABEL (label), g_strstrip(stdout));
- - else
- - gtk_label_set_text (GTK_LABEL (label), "execution error");
- - g_free (stdout);
- + GError *error = NULL;
- +
- + gchar *full_command;
- + gchar *file;
- + GRegex *regex, *regex2;
- +
- + regex = g_regex_new("file:///", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
- + regex2 = g_regex_new("%f", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
- +
- + file = g_strstrip(g_regex_replace_literal(regex, gtk_recent_chooser_get_current_uri (chooser), -1, 0, "/", 0, NULL));
- +
- + if (g_regex_match (regex2,command,0,0))
- + {
- + //if using custom complex command, replace %f with filename
- + full_command = g_strstrip(g_regex_replace_literal(regex2, command, -1, 0, file, 0, NULL));
- + }
- + else
- + {
- + full_command = g_strjoin (" ", command, file, NULL);
- + }
- +
- + g_regex_unref(regex);
- + g_regex_unref(regex2);
- +
- + if (!gdk_spawn_command_line_on_screen (gdk_screen_get_default (), parse_expand_tilde(full_command), &error))
- + {
- + GtkWidget *message = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
- + GTK_BUTTONS_CLOSE, "%s", error->message);
- + gtk_dialog_run (GTK_DIALOG (message));
- + gtk_widget_destroy (message);
- + }
- +
- }
- static void
- @@ -125,22 +149,13 @@
- case DESKMENU_ITEM_LAUNCHER:
- if (item->name_exec)
- {
- - GtkWidget *label;
- - GHook *hook;
- -
- + gchar *stdout;
- name = g_strstrip (item->name->str);
- -
- - menu_item = gtk_image_menu_item_new ();
- - label = gtk_label_new_with_mnemonic (NULL);
- - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- -
- - g_object_set_data (G_OBJECT (label), "exec", g_strdup (name));
- - gtk_container_add (GTK_CONTAINER (menu_item), label);
- - hook = g_hook_alloc (deskmenu->show_hooks);
- -
- - hook->data = (gpointer) label;
- - hook->func = (GHookFunc *) launcher_name_exec_update;
- - g_hook_append (deskmenu->show_hooks, hook);
- + if (g_spawn_command_line_sync (parse_expand_tilde(name), &stdout, NULL, NULL, NULL))
- + menu_item = gtk_image_menu_item_new_with_mnemonic (g_strstrip(stdout));
- + else
- + menu_item = gtk_image_menu_item_new_with_mnemonic ("Unable to get output");
- + g_free (stdout);
- }
- else
- {
- @@ -170,7 +185,6 @@
- {
- command = g_strstrip (item->command->str);
- - g_object_set_data (G_OBJECT (menu_item), "deskmenu", deskmenu);
- g_signal_connect (G_OBJECT (menu_item), "activate",
- G_CALLBACK (launcher_activated), g_strdup (command));
- }
- @@ -239,7 +253,97 @@
- }
- break;
- #endif
- + case DESKMENU_ITEM_RELOAD:
- + menu_item = gtk_image_menu_item_new_with_mnemonic ("Reload");
- + if (item->icon)
- + {
- + icon = g_strstrip (item->icon->str);
- + if (item->icon_file) {
- + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
- + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
- + (menu_item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
- + }
- + else {
- + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
- + gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
- + }
- + }
- + g_signal_connect (G_OBJECT (menu_item), "activate",
- + G_CALLBACK (quit), NULL);
- + gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
- + menu_item);
- + break;
- +
- + case DESKMENU_ITEM_DOCUMENTS:
- + menu_item = gtk_image_menu_item_new_with_mnemonic ("Recent Doc_uments");
- + GtkWidget *docs = gtk_recent_chooser_menu_new ();
- +
- + if (item->icon)
- + {
- + gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER(docs), TRUE);
- + icon = g_strstrip (item->icon->str);
- + if (item->icon_file) {
- + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
- + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
- + (menu_item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
- + }
- + else {
- + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
- + gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
- + }
- + }
- + else
- + {
- + gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER(docs), FALSE);
- + }
- + if (item->age)
- + {
- + gint days;
- + GtkRecentFilter *filter = gtk_recent_filter_new ();
- + gtk_recent_filter_add_pattern (filter, "*");
- + days = atoi(g_strstrip (item->age->str));
- + gtk_recent_filter_add_age (filter, days);
- + gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER(docs), filter);
- + }
- + if (item->sort_type) {
- + if (strcmp (g_strstrip (item->sort_type->str), "most used") == 0)
- + {
- + gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER(docs), GTK_RECENT_SORT_MRU);
- + }
- + else
- + {
- + gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER(docs), GTK_RECENT_SORT_LRU);
- + }
- + }
- + if (item->quantity)
- + {
- + gint limit;
- + limit = atoi(g_strstrip (item->quantity->str));
- + gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER(docs), limit);
- + }
- + else
- + {
- + gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER(docs), -1);
- + }
- + if (item->command)
- + {
- + command = g_strstrip (item->command->str);
- + g_signal_connect (G_OBJECT (docs), "item-activated",
- + G_CALLBACK (recent_activated), g_strdup (command));
- + }
- + else
- + {
- + command = g_strdup ("xdg-open");
- + g_signal_connect (G_OBJECT (docs), "item-activated",
- + G_CALLBACK (recent_activated), g_strdup (command));
- + }
- + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
- + docs);
- + gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
- + menu_item);
- + break;
- +
- default:
- break;
- }
- @@ -259,11 +363,11 @@
- DeskmenuElementType element_type;
- const gchar **ncursor = attr_names, **vcursor = attr_values;
- GtkWidget *item, *menu;
- + gint w, h;
- element_type = GPOINTER_TO_INT (g_hash_table_lookup
- (deskmenu->element_hash, element_name));
- - //TODO: maybe this could be edited to see the new compiz-deskmenu element, if this is needed in order to make pipes
- if ((deskmenu->menu && !deskmenu->current_menu)
- || (!deskmenu->menu && element_type != DESKMENU_ELEMENT_MENU))
- {
- @@ -289,9 +393,15 @@
- "inside of an item element", line_num, char_num);
- return;
- }
- - //TODO: maybe this could be moved to see the new compiz-deskmenu element, if this is needed in order to make pipes
- if (!deskmenu->menu)
- {
- + /*if (strcmp (*ncursor, "size") == 0) {
- + deskmenu->w = g_strdup (*vcursor);
- + deskmenu->h = g_strdup (*vcursor);
- + }
- + else {
- + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, deskmenu->w, deskmenu->h);
- + }*/
- deskmenu->menu = gtk_menu_new ();
- g_object_set_data (G_OBJECT (deskmenu->menu), "parent menu",
- NULL);
- @@ -303,7 +413,6 @@
- gchar *icon = NULL;
- gboolean name_exec = FALSE;
- gboolean icon_file = FALSE;
- - gint w, h;
- while (*ncursor)
- {
- if (strcmp (*ncursor, "name") == 0)
- @@ -325,20 +434,12 @@
- }
- if (name_exec)
- {
- - GtkWidget *label;
- - GHook *hook;
- -
- - item = gtk_image_menu_item_new ();
- - label = gtk_label_new_with_mnemonic (NULL);
- - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- -
- - g_object_set_data (G_OBJECT (label), "exec", g_strdup (name));
- - gtk_container_add (GTK_CONTAINER (item), label);
- - hook = g_hook_alloc (deskmenu->show_hooks);
- -
- - hook->data = (gpointer) label;
- - hook->func = (GHookFunc *) launcher_name_exec_update;
- - g_hook_append (deskmenu->show_hooks, hook);
- + gchar *stdout;
- + if (g_spawn_command_line_sync (parse_expand_tilde(name), &stdout, NULL, NULL, NULL))
- + item = gtk_image_menu_item_new_with_mnemonic (g_strstrip(stdout));
- + else
- + item = gtk_image_menu_item_new_with_mnemonic ("Unable to get output");
- + g_free (stdout);
- }
- else
- {
- @@ -347,8 +448,6 @@
- else
- item = gtk_image_menu_item_new_with_mnemonic ("");
- - gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
- - item);
- }
- if (icon)
- {
- @@ -362,6 +461,7 @@
- gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
- }
- }
- + gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu), item);
- menu = gtk_menu_new ();
- g_object_set_data (G_OBJECT (menu), "parent menu",
- deskmenu->current_menu);
- @@ -374,7 +474,91 @@
- break;
- case DESKMENU_ELEMENT_SEPARATOR:
- - break; /* build it in the end function */
- + if (deskmenu->current_item != NULL)
- + {
- + gint line_num, char_num;
- + g_markup_parse_context_get_position (context, &line_num,
- + &char_num);
- + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- + "Error on line %d char %d: Element 'menu' cannot be nested "
- + "inside of an item element", line_num, char_num);
- + return;
- + }
- + else {
- + gchar *name = NULL;
- + gchar *icon = NULL;
- + gboolean name_exec = FALSE;
- + gboolean icon_file = FALSE;
- + gboolean decorate = FALSE;
- + gint w, h;
- + while (*ncursor)
- + {
- + if (strcmp (*ncursor, "name") == 0) {
- + name = g_strdup (*vcursor);
- + if (!decorate)
- + {
- + decorate = TRUE;
- + }
- + }
- + else if (strcmp (*ncursor, "icon") == 0) {
- + icon = g_strdup (*vcursor);
- + if (!decorate)
- + {
- + decorate = TRUE;
- + }
- + }
- + else if ((strcmp (*ncursor, "mode") == 0)
- + && (strcmp (*vcursor, "exec") == 0))
- + name_exec = TRUE;
- + else if ((strcmp (*ncursor, "mode1") == 0)
- + && (strcmp (*vcursor, "file") == 0))
- + icon_file = TRUE;
- + else
- + g_set_error (error, G_MARKUP_ERROR,
- + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
- + "Unknown attribute: %s", *ncursor);
- + ncursor++;
- + vcursor++;
- + }
- + if (decorate)
- + {
- + if (name_exec)
- + {
- + gchar *stdout;
- + if (g_spawn_command_line_sync (parse_expand_tilde(name), &stdout, NULL, NULL, NULL))
- + item = gtk_image_menu_item_new_with_mnemonic (g_strstrip(stdout));
- + else
- + item = gtk_image_menu_item_new_with_mnemonic ("Unable to get output");
- + g_free (stdout);
- + }
- + else
- + {
- + item = gtk_image_menu_item_new_with_mnemonic (name);
- + }
- + if (icon)
- + {
- + if (icon_file) {
- + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
- + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
- + (item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
- + }
- + else {
- + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
- + gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
- + }
- + }
- + gtk_widget_set_state (item,GTK_STATE_PRELIGHT); /*derive colors from menu hover*/
- + gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu), item);
- + g_free (name);
- + g_free (icon);
- + }
- + else
- + {
- + item = gtk_separator_menu_item_new ();
- + gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu), item);
- + }
- + }
- + break;
- case DESKMENU_ELEMENT_ITEM:
- @@ -436,6 +620,18 @@
- if (deskmenu->current_item)
- deskmenu->current_item->current_element = element_type;
- break;
- + case DESKMENU_ELEMENT_QUANTITY:
- + if (deskmenu->current_item)
- + deskmenu->current_item->current_element = element_type;
- + break;
- + case DESKMENU_ELEMENT_SORT:
- + if (deskmenu->current_item)
- + deskmenu->current_item->current_element = element_type;
- + break;
- + case DESKMENU_ELEMENT_AGE:
- + if (deskmenu->current_item)
- + deskmenu->current_item->current_element = element_type;
- + break;
- default:
- g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
- "Unknown element: %s", element_name);
- @@ -493,10 +689,30 @@
- g_string_append_len (item->wrap, text, text_len);
- break;
- + case DESKMENU_ELEMENT_AGE:
- + if (!item->age)
- + item->age = g_string_new_len (text, text_len);
- + else
- + g_string_append_len (item->age, text, text_len);
- + break;
- +
- + case DESKMENU_ELEMENT_QUANTITY:
- + if (!item->quantity)
- + item->quantity = g_string_new_len (text, text_len);
- + else
- + g_string_append_len (item->quantity, text, text_len);
- + break;
- +
- + case DESKMENU_ELEMENT_SORT:
- + if (!item->sort_type)
- + item->sort_type = g_string_new_len (text, text_len);
- + else
- + g_string_append_len (item->sort_type, text, text_len);
- + break;
- +
- default:
- break;
- }
- -
- }
- static void
- @@ -508,7 +724,7 @@
- DeskmenuElementType element_type;
- Deskmenu *deskmenu = DESKMENU (user_data);
- - GtkWidget *parent, *item;
- + GtkWidget *parent;
- element_type = GPOINTER_TO_INT (g_hash_table_lookup
- (deskmenu->element_hash, element_name));
- @@ -524,13 +740,7 @@
- deskmenu->current_menu = parent;
- break;
- -
- - case DESKMENU_ELEMENT_SEPARATOR:
- - item = gtk_separator_menu_item_new ();
- - gtk_menu_shell_append (GTK_MENU_SHELL (deskmenu->current_menu),
- - item);
- - break;
- -
- +/* separator building is now dealt with in the beginning */
- case DESKMENU_ELEMENT_ITEM:
- g_return_if_fail (deskmenu->current_item != NULL);
- @@ -549,6 +759,12 @@
- g_string_free (deskmenu->current_item->wrap, TRUE);
- if (deskmenu->current_item->vpicon)
- g_string_free (deskmenu->current_item->vpicon, TRUE);
- + if (deskmenu->current_item->sort_type)
- + g_string_free (deskmenu->current_item->sort_type, TRUE);
- + if (deskmenu->current_item->quantity)
- + g_string_free (deskmenu->current_item->quantity, TRUE);
- + if (deskmenu->current_item->age)
- + g_string_free (deskmenu->current_item->age, TRUE);
- g_slice_free (DeskmenuItem, deskmenu->current_item);
- deskmenu->current_item = NULL;
- break;
- @@ -568,8 +784,8 @@
- };
- -/* Class init, casts all deskmenu GObject instances with this class structure */
- -static void
- +/* Class init */
- +static void
- deskmenu_class_init (DeskmenuClass *deskmenu_class)
- {
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (deskmenu_class),
- @@ -581,15 +797,9 @@
- deskmenu_init (Deskmenu *deskmenu)
- {
- - deskmenu->show_hooks = g_slice_new0 (GHookList);
- -
- - g_hook_list_init (deskmenu->show_hooks, sizeof (GHook));
- -
- -
- deskmenu->menu = NULL;
- deskmenu->current_menu = NULL;
- deskmenu->current_item = NULL;
- -
- deskmenu->envp = NULL;
- deskmenu->item_hash = g_hash_table_new (g_str_hash, g_str_equal);
- @@ -602,6 +812,10 @@
- g_hash_table_insert (deskmenu->item_hash, "viewportlist",
- GINT_TO_POINTER (DESKMENU_ITEM_VIEWPORTLIST));
- #endif
- + g_hash_table_insert (deskmenu->item_hash, "documents",
- + GINT_TO_POINTER (DESKMENU_ITEM_DOCUMENTS));
- + g_hash_table_insert (deskmenu->item_hash, "reload",
- + GINT_TO_POINTER (DESKMENU_ITEM_RELOAD));
- deskmenu->element_hash = g_hash_table_new (g_str_hash, g_str_equal);
- @@ -621,214 +835,310 @@
- GINT_TO_POINTER (DESKMENU_ELEMENT_COMMAND));
- g_hash_table_insert (deskmenu->element_hash, "wrap",
- GINT_TO_POINTER (DESKMENU_ELEMENT_WRAP));
- + g_hash_table_insert (deskmenu->element_hash, "sort",
- + GINT_TO_POINTER (DESKMENU_ELEMENT_SORT));
- + g_hash_table_insert (deskmenu->element_hash, "quantity",
- + GINT_TO_POINTER (DESKMENU_ELEMENT_QUANTITY));
- + g_hash_table_insert (deskmenu->element_hash, "age",
- + GINT_TO_POINTER (DESKMENU_ELEMENT_AGE));
- +}
- +
- +static
- +gchar *check_file_cache (gchar *filename) {
- +static GHashTable *cache;
- +gchar *t = NULL;
- +gchar *f = NULL;
- +gchar *user_default = g_build_path (G_DIR_SEPARATOR_S, g_get_user_config_dir (),
- + "compiz",
- + "boxmenu",
- + "menu.xml",
- + NULL);
- +//TODO: add a size column to cache for possible autorefresh
- +if (!cache)
- +{
- + g_print("Creating cache...");
- + cache = g_hash_table_new (g_str_hash, g_str_equal);
- + g_print("Done creating cache!\n");
- +}
- +else
- +{
- + g_print("Checking cache...\n");
- +}
- +
- +if (strlen(filename) == 0) {
- + g_print("No filename supplied, looking up default menu...\n");
- + /*
- + set default filename to be [configdir]/compiz/boxmenu/menu.xml
- + */
- + filename = user_default;
- + gboolean success = FALSE;
- + if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
- + g_print("Getting default system menu...\n");
- + const gchar* const *cursor = g_get_system_config_dirs ();
- + gchar *path = NULL;
- + while (*cursor)
- + {
- + g_free (path);
- + path = g_strdup (*cursor);
- + filename = g_build_path (G_DIR_SEPARATOR_S,
- + path,
- + "compiz",
- + "boxmenu",
- + "menu.xml",
- + NULL);
- +
- + if (g_file_get_contents (filename, &f, NULL, NULL))
- + {
- + g_hash_table_insert (cache, g_strdup(filename), g_strdup(f));
- + g_free (path);
- + g_print("Got it!\n");
- + success = TRUE;
- + break;
- + }
- + cursor++;
- + }
- + }
- + else
- + {
- + if (!g_hash_table_lookup_extended(cache, user_default, NULL, NULL))
- + {
- + g_file_get_contents (filename, &f, NULL, NULL);
- + g_print("Cacheing default user file...\n");
- + g_hash_table_insert (cache, g_strdup(filename), g_strdup(f));
- + }
- + g_print("Retrieving cached default user file...\n");
- + success = TRUE;
- + }
- + if (!success)
- + {
- + g_printerr ("Couldn't find a menu file...\n");
- + exit (1);
- + }
- +}
- +else {
- + if (!g_hash_table_lookup_extended(cache, filename, NULL, NULL)) {
- + if (g_file_get_contents (filename, &f, NULL, NULL))
- + {
- + g_print("Cacheing new non-default file...\n");
- + g_hash_table_insert (cache, g_strdup(filename), g_strdup(f));
- + }
- + else {
- + if (g_hash_table_lookup_extended(cache, user_default, NULL, NULL))
- + {
- + g_print("Couldn't find specified file, loading default...\n");
- + filename = user_default;
- + }
- + else
- + {
- + g_printerr ("Couldn't find a menu file...\n");
- + exit (1);
- + }
- + }
- + }
- +}
- +
- +t = g_hash_table_lookup (cache, filename);
- +
- +g_printf("Done loading %s!\n", filename);
- +g_free (f);
- +g_free (filename);
- +
- +return t;
- }
- static void
- -deskmenu_parse_file (Deskmenu *deskmenu,
- - gchar *configpath)
- +deskmenu_parse_text (Deskmenu *deskmenu, gchar *text)
- {
- GError *error = NULL;
- - gboolean success = FALSE;
- - gchar *text, *exec, *stdout;
- - gsize length;
- + gchar *exec, *stdout, *pipe_error;
- GRegex *regex, *command;
- - int i;
- -
- - if (!configpath)
- - configpath = g_build_path (G_DIR_SEPARATOR_S,
- - g_get_user_config_dir (),
- - "compiz",
- - "deskmenu",
- - "menu.xml",
- - NULL);
- + int i = 0;
- GMarkupParseContext *context = g_markup_parse_context_new (&parser,
- 0, deskmenu, NULL);
- -
- - if (!g_file_get_contents (configpath, &text, &length, NULL))
- - {
- - const gchar* const *cursor = g_get_system_config_dirs ();
- - gchar *path = NULL;
- - while (*cursor)
- - {
- - g_free (configpath);
- - g_free (path);
- - path = g_strdup (*cursor);
- - configpath = g_build_path (G_DIR_SEPARATOR_S,
- - path,
- - "compiz",
- - "deskmenu",
- - "menu.xml",
- - NULL);
- -
- - if (g_file_get_contents (configpath, &text, &length, NULL))
- - {
- - success = TRUE;
- - g_free (path);
- - break;
- - }
- - cursor++;
- - }
- - }
- - else
- - {
- - success = TRUE;
- - }
- -
- - if (!success)
- - {
- - g_printerr ("Couldn't find a menu file\n");
- - exit (1);
- - }
- - i = 0;
- + pipe_error = g_strdup ("<item type=\"launcher\"><name>Cannot retrieve pipe output</name></item>");
- regex = g_regex_new("(<pipe command=\".*\"/>)", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
- command = g_regex_new("<pipe command=\"|\"/>", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
- - //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
- gchar **menu_chunk = g_regex_split (regex, text, 0); //this splits the menu into parsable chunks, needed for pipe item capabilities
- - g_free(text); //we no longer need the loaded file
- +
- //this loop will replace the pipeitem chunk with its output, other chunks are let through as is
- while (menu_chunk[i])
- {
- if (g_regex_match (regex,menu_chunk[i],0,0))
- {
- - //they only exist in this loop
- exec = parse_expand_tilde(g_strstrip(g_regex_replace_literal(command, menu_chunk[i], -1, 0, "", 0, NULL)));
- - g_spawn_command_line_sync (exec, &stdout, NULL, NULL, NULL);
- - menu_chunk[i] = stdout;
- + if (g_spawn_command_line_sync (exec, &stdout, NULL, NULL, NULL))
- + {
- + menu_chunk[i] = stdout;
- + }
- + else
- + {
- + menu_chunk[i] = pipe_error;
- + }
- + //fix this to be able to replace faulty pipe with an item that says it can't be executed
- + //needs validator in order to make sure it can be parsed, if not, set parsed error
- }
- i++;
- }
- - g_regex_unref(regex); //free the pipeitem chunk checker
- - g_regex_unref(command); //free the pipe command extractor
- + text = g_strjoinv (NULL, menu_chunk); //stitch the text so we can get error reporting back to normal
- -//the idea for the pipeitem method came from this experiment below
- -/*
- -g_markup_parse_context_parse (context, "<menu>", 6, &error);
- -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
- -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
- -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
- -g_markup_parse_context_parse (context, "<item type=\"launcher\"><icon>icon</icon><name>rawr</name></item><command>fickle</command>", 90, &error);
- -g_markup_parse_context_parse (context, "</menu>", 7, &error);
- -*/
- - i = 0;
- - while (menu_chunk[i])
- - {
- - g_markup_parse_context_parse (context, menu_chunk[i], strlen(menu_chunk[i]), &error);
- - //fix error reporting here, otherwise, it works fine
- - i++;
- - }
- -
- -/*old menu functionality
- - if (!g_markup_parse_context_parse (context, text, length, &error)
- + if (!g_markup_parse_context_parse (context, text, strlen(text), &error)
- || !g_markup_parse_context_end_parse (context, &error))
- {
- - g_printerr ("Parse of %s failed with message: %s \n",
- - configpath, error->message);
- + g_printerr ("Parse failed with message: %s \n", error->message);
- g_error_free (error);
- exit (1);
- }
- - */
- +
- + g_free(text); //free the joined array
- g_strfreev(menu_chunk); //free the menu chunks and their container
- - g_free (configpath); //free the file path
- + g_regex_unref(regex); //free the pipeitem chunk checker
- + g_regex_unref(command); //free the pipe command extractor
- g_markup_parse_context_free (context); //free the parser
- gtk_widget_show_all (deskmenu->menu);
- }
- /* The show method */
- -gboolean
- +static void
- deskmenu_show (Deskmenu *deskmenu,
- - gchar **env,
- GError **error)
- {
- - g_hook_list_invoke (deskmenu->show_hooks, FALSE);
- -
- - if (deskmenu->envp)
- - g_strfreev (deskmenu->envp);
- -
- - deskmenu->envp = g_strdupv (env);
- -
- gtk_menu_popup (GTK_MENU (deskmenu->menu),
- NULL, NULL, NULL, NULL,
- 0, 0);
- +}
- +
- +gboolean
- +deskmenu_reload (Deskmenu *deskmenu,
- + GError **error)
- +{
- + gtk_main_quit ();
- return TRUE;
- }
- +/* The dbus method for binary client */
- +gboolean
- +deskmenu_control (Deskmenu *deskmenu, gchar **env, gchar *filename, GError **error)
- +{
- + if (deskmenu->menu)
- + {
- + deskmenu->menu = NULL;
- + }
- + deskmenu_parse_text(deskmenu, check_file_cache(g_strdup(filename))); //recreate the menu, check caches for data
- +
- + if (deskmenu->envp)
- + g_strfreev (deskmenu->envp);
- + deskmenu->envp = g_strdupv (env);
- +
- + deskmenu_show(deskmenu, error);
- + return TRUE;
- +}
- +
- +
- +//precache backend, currently needs GUI
- +static void
- +deskmenu_precache (gchar *filename)
- +{
- + GError *error = NULL;
- + GKeyFile *config = g_key_file_new ();
- + int i;
- +
- +// (void *)check_file_cache(""); //always cache default menu
- +
- + g_print("Attempting to precache files in config...");
- + if (!filename)
- + {
- + filename = g_build_path (G_DIR_SEPARATOR_S,
- + g_get_user_config_dir (),
- + "compiz",
- + "boxmenu",
- + "precache.ini",
- + NULL);
- + }
- + if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, NULL))
- + {
- + g_print("Configuration not found, will not precache files...");
- + g_key_file_free (config);
- + }
- + else
- + {
- + g_print("Configuration found! Starting precache...");
- + gchar **files = g_key_file_get_keys (config, "Files", NULL, &error);
- + gchar *feed;
- +
- + while (files[i])
- + {
- + feed = g_key_file_get_string (config, "Files", files[i], &error);
- + (void *)check_file_cache(parse_expand_tilde(feed));
- + i++;
- + }
- + g_strfreev(files);
- + g_free(feed);
- + g_key_file_free (config);
- + }
- +}
- +
- int
- main (int argc,
- char **argv)
- {
- - DBusGConnection *connection;
- + DBusGConnection *connection;
- GError *error = NULL;
- GObject *deskmenu;
- g_type_init ();
- +
- + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
- + if (connection == NULL)
- + {
- + g_printerr ("Failed to open connection to bus: %s", error->message);
- + g_error_free (error);
- + exit (1);
- + }
- +//gtk_tearoff_menu_item_new();
- + g_print ("Starting the daemon...\n");
- - gchar *filename = NULL;
- - GOptionContext *context;
- + GOptionContext *context;
- + gchar *file = NULL;
- GOptionEntry entries[] =
- {
- - { "menu", 'm', 0, G_OPTION_ARG_FILENAME, &filename,
- - "Use FILE instead of the default menu file", "FILE" },
- + { "config", 'c', 0, G_OPTION_ARG_FILENAME, &file,
- + "Use FILE instead of the default daemon configuration", "FILE" },
- { NULL, 0, 0, 0, NULL, NULL, NULL }
- };
- context = g_option_context_new (NULL);
- g_option_context_add_main_entries (context, entries, NULL);
- - g_option_context_add_group (context, gtk_get_option_group (TRUE));
- + error = NULL;
- if (!g_option_context_parse (context, &argc, &argv, &error))
- {
- g_printerr ("option parsing failed: %s", error->message);
- g_error_free (error);
- - exit (1);
- - }
- - g_option_context_free (context);
- -
- - /* Obtain a connection to the session bus */
- - connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
- - if (connection == NULL)
- - {
- - g_printerr ("Failed to open connection to bus: %s", error->message);
- - g_error_free (error);
- - exit (1);
- - }
- + return 1;
- + }
- + g_option_context_free (context);
- #if HAVE_WNCK
- wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER);
- #endif
- gtk_init (&argc, &argv);
- -
- +
- deskmenu = g_object_new (DESKMENU_TYPE, NULL);
- -
- - //deskmenu_init(DESKMENU (deskmenu));
- -
- - deskmenu_parse_file (DESKMENU (deskmenu), filename);
- - dbus_g_connection_register_g_object (connection,
- - DESKMENU_PATH_DBUS,
- - deskmenu);
- -/*clues
- - * http://library.gnome.org/devel/dbus-glib/unstable/dbus-glib-DBusGConnection.html#dbus-g-connection-register-g-object
- - * http://library.gnome.org/devel/dbus-glib/unstable/dbus-glib-dbus-gobject.html#dbus-g-object-type-install-info
- - * 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.
- + dbus_g_connection_register_g_object (connection, DESKMENU_PATH_DBUS, deskmenu);
- -Once introspection information has been installed, instances of the object registered with #dbus_g_connection_register_g_object() can have their methods invoked remotely.
- -
- -object_type :
- - GType for the object
- -
- -info :
- - introspection data generated by dbus-glib-tool
- - */
- if (!dbus_bus_request_name (dbus_g_connection_get_connection (connection),
- DESKMENU_SERVICE_DBUS,
- DBUS_NAME_FLAG_REPLACE_EXISTING,
- NULL))
- return 1;
- + deskmenu_precache(file);
- +
- gtk_main ();
- return 0;
- diff -aur compiz-deskmenu2/deskmenu-menu.h compiz-boxmenu/deskmenu-menu.h
- --- compiz-deskmenu2/deskmenu-menu.h 2010-11-15 22:21:44.000000000 -0800
- +++ compiz-boxmenu/deskmenu-menu.h 2010-12-01 15:01:03.000000000 -0800
- @@ -28,7 +28,9 @@
- DESKMENU_ITEM_NONE = 0,
- DESKMENU_ITEM_LAUNCHER,
- DESKMENU_ITEM_WINDOWLIST,
- - DESKMENU_ITEM_VIEWPORTLIST
- + DESKMENU_ITEM_VIEWPORTLIST,
- + DESKMENU_ITEM_RELOAD,
- + DESKMENU_ITEM_DOCUMENTS //use native GTK+ support for recent documents
- } DeskmenuItemType;
- typedef enum
- @@ -41,7 +43,10 @@
- DESKMENU_ELEMENT_ICON,
- DESKMENU_ELEMENT_COMMAND,
- DESKMENU_ELEMENT_WRAP,
- - DESKMENU_ELEMENT_VPICON
- + DESKMENU_ELEMENT_VPICON,
- + DESKMENU_ELEMENT_AGE, //age of dox
- + DESKMENU_ELEMENT_QUANTITY, //# of dox
- + DESKMENU_ELEMENT_SORT //sort method
- } DeskmenuElementType;
- @@ -57,6 +62,9 @@
- GString *vpicon;
- GString *command;
- GString *wrap;
- + GString *sort_type; //get sort type for document items
- + GString *age; //get age limit for document items
- + GString *quantity; //get item limit for document items
- };
- struct Deskmenu
- @@ -68,10 +76,9 @@
- GtkWidget *menu;
- GtkWidget *current_menu;
- DeskmenuItem *current_item;
- + gchar **envp;
- GHashTable *item_hash;
- GHashTable *element_hash;
- - GHookList *show_hooks;
- - gchar **envp;
- };
- struct DeskmenuClass
- @@ -95,5 +102,5 @@
- GQuark deskmenu_error_quark (void);
- #define DESKMENU_ERROR deskmenu_error_quark ()
- -
- -gboolean deskmenu_show (Deskmenu *deskmenu, gchar **env, GError **error);
- +gboolean deskmenu_reload (Deskmenu *deskmenu, GError **error);
- +gboolean deskmenu_control (Deskmenu *deskmenu, gchar **env, gchar *filename, GError **error);
- diff -aur compiz-deskmenu2/deskmenu-service.xml compiz-boxmenu/deskmenu-service.xml
- --- compiz-deskmenu2/deskmenu-service.xml 2010-11-13 20:50:48.000000000 -0800
- +++ compiz-boxmenu/deskmenu-service.xml 2010-12-01 15:06:49.000000000 -0800
- @@ -1,10 +1,13 @@
- <?xml version="1.0" encoding="UTF-8" ?>
- -<node name="/org/compiz_fusion/deskmenu/menu">
- - <interface name="org.compiz_fusion.deskmenu">
- +<node name="/org/compiz_fusion/boxmenu/menu">
- + <interface name="org.compiz_fusion.boxmenu">
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="deskmenu"/>
- - <method name="show">
- + <method name="control">
- <arg type="as" name="env" direction="in" />
- + <arg type="s" name="filename" direction="in" />
- + </method>
- + <method name="reload">
- </method>
- </interface>
- </node>
- diff -aur compiz-deskmenu2/deskmenu-wnck.c compiz-boxmenu/deskmenu-wnck.c
- --- compiz-deskmenu2/deskmenu-wnck.c 2010-11-15 18:46:24.000000000 -0800
- +++ compiz-boxmenu/deskmenu-wnck.c 2010-12-01 14:39:46.000000000 -0800
- @@ -74,7 +74,13 @@
- return width;
- }
- +/*
- +(compiz-boxmenu-daemon:23915): GLib-GObject-WARNING **: invalid cast from `PangoLayout' to `GtkLabel'
- +(compiz-boxmenu-daemon:23915): Gtk-CRITICAL **: IA__gtk_label_set_text_with_mnemonic: assertion `GTK_IS_LABEL (label)' failed
- +
- +(compiz-boxmenu-daemon:23915): Gtk-CRITICAL **: IA__gtk_widget_set_size_request: assertion `GTK_IS_WIDGET (widget)' fai
- +*/
- /* end borrowing */
- static void
- @@ -93,7 +99,6 @@
- GString *name;
- gchar *namecpy, *mnemonic, *decorated_name, *unescaped;
- guint i, n;
- -
- name = g_string_new (wnck_window_get_name (dmwin->window));
- namecpy = g_strdup (name->str);
- @@ -115,16 +120,9 @@
- mnemonic = "";
- //wnck_window_get_workspace (dmwin->window)
- //TODO: get this to calculate right
- - /*
- - column = wnck_workspace_get_viewport_x (wnck_window_get_workspace (dmwin->window));
- - width = wnck_workspace_get_width (wnck_screen_get_workspace (wnck_screen_get_default (), 0))/wnck_screen_get_width (wnck_screen_get_default ());
- - row = wnck_workspace_get_viewport_y (wnck_window_get_workspace (dmwin->window));
- - vpidNumber = column + ((row) * width);
- - vpid = g_strdup_printf ("%d %d %d %d :",vpidNumber,width,column,row);
- - g_print(vpid);
- - decorated_name = g_strconcat ("[",vpid, "] ", ante, mnemonic, name->str, post, NULL);
- - */
- - decorated_name = g_strconcat (ante, mnemonic, name->str, post, NULL);
- +
- + decorated_name = g_strconcat (ante, mnemonic, name->str, post, NULL);
- + //decorated_name = g_strconcat (ante, mnemonic, name->str, post, NULL);
- unescaped = g_strconcat (ante, wnck_window_get_name (dmwin->window),
- post, NULL);
- @@ -173,6 +171,7 @@
- }
- else
- dmwin_set_decoration (dmwin, "", "");
- +
- }
- static void
- @@ -188,7 +187,7 @@
- pixbuf = wnck_selector_dimm_icon (pixbuf);
- free_pixbuf = TRUE;
- }
- -
- +
- gtk_image_set_from_pixbuf (GTK_IMAGE (dmwin->image), pixbuf);
- if (free_pixbuf)
- @@ -345,7 +344,7 @@
- windowlist->screen = wnck_screen_get_default ();
- windowlist->menu = gtk_menu_new ();
- -
- +//does not emit signals 2nd time around
- g_signal_connect (G_OBJECT (windowlist->screen), "window-opened",
- G_CALLBACK (screen_window_opened), windowlist);
- @@ -558,13 +557,12 @@
- if (new_count > vplist->old_count)
- {
- gchar *text;
- -//TODO: edit this section to add thumnbnails for ports, possibly just set the thumbnails to be viewport wallpapers?
- for (i = vplist->old_count; i < new_count; i++)
- {
- text = g_strdup_printf ("Viewport _%i", i + 1);
- item = gtk_image_menu_item_new_with_mnemonic (text);
- if (vplist->images)
- - { //this'll set viewport thumbnail later if I can figure out how
- + {
- if (vplist->icon){
- if (vplist->file) {
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
- @@ -647,7 +645,7 @@
- gtk_separator_menu_item_new ());
- vplist->goto_items = g_ptr_array_new ();
- -
- +//does not go here
- g_signal_connect (G_OBJECT (vplist->screen), "viewports-changed",
- G_CALLBACK (deskmenu_vplist_update), vplist);
- diff -aur compiz-deskmenu2/deskmenu.c compiz-boxmenu/deskmenu.c
- --- compiz-deskmenu2/deskmenu.c 2010-11-10 18:07:24.000000000 -0800
- +++ compiz-boxmenu/deskmenu.c 2010-12-01 15:24:32.000000000 -0800
- @@ -14,7 +14,6 @@
- *
- * Copyright 2008 Christopher Williams <[email protected]>
- */
- -
- #include <dbus/dbus-glib.h>
- #include <unistd.h>
- @@ -24,14 +23,26 @@
- int main (int argc, char *argv[])
- {
- - DBusGConnection *connection;
- - GError *error;
- - DBusGProxy *proxy;
- -
- + DBusGConnection *connection;
- + GError *error;
- + DBusGProxy *proxy;
- + gchar *filename = NULL;
- +
- usleep (200000);
- g_type_init ();
- + GOptionContext *context;
- + GOptionEntry entries[] =
- + {
- + { "menu", 'm', 0, G_OPTION_ARG_FILENAME, &filename,
- + "Use FILE instead of the default menu file", "FILE" },
- + { NULL, 0, 0, 0, NULL, NULL, NULL }
- + };
- +
- + context = g_option_context_new (NULL);
- + g_option_context_add_main_entries (context, entries, NULL);
- +
- error = NULL;
- connection = dbus_g_bus_get (DBUS_BUS_SESSION,
- &error);
- @@ -49,15 +60,25 @@
- DESKMENU_INTERFACE_DBUS);
- error = NULL;
- - if (!dbus_g_proxy_call (proxy, "show", &error, G_TYPE_STRV, environ,
- +
- +
- + if (!g_option_context_parse (context, &argc, &argv, &error))
- + {
- + g_printerr ("option parsing failed: %s", error->message);
- + g_error_free (error);
- + return 1;
- + }
- +
- + if (!dbus_g_proxy_call (proxy, "control", &error, G_TYPE_STRV, environ, G_TYPE_STRING, filename,
- G_TYPE_INVALID, G_TYPE_INVALID))
- {
- g_printerr ("Error: %s\n", error->message);
- g_error_free (error);
- return 1;
- }
- -
- - g_object_unref (proxy);
- +
- + g_option_context_free (context);
- + g_object_unref (proxy);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement