]> Dogcows Code - chaz/openbox/blobdiff - openbox/menu.c
Use GMainLoop instead of ObtMainLoop
[chaz/openbox] / openbox / menu.c
index 77d9548c0da34069884a41d57042230849f9751a..374aeec1fc59a7b951acaf8e7bfa5fb3709318d8 100644 (file)
@@ -36,7 +36,6 @@
 #include "gettext.h"
 #include "obt/xml.h"
 #include "obt/paths.h"
-#include "imageload.h"
 
 typedef struct _ObMenuParseState ObMenuParseState;
 
@@ -59,13 +58,6 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
                                gchar **strippedlabel, guint *position,
                                gboolean *always_show);
 
-static void client_dest(ObClient *client, gpointer data)
-{
-    /* menus can be associated with a client, so close any that are since
-       we are disappearing now */
-    menu_frame_hide_all_client(client);
-}
-
 void menu_startup(gboolean reconfig)
 {
     gboolean loaded = FALSE;
@@ -115,16 +107,10 @@ void menu_startup(gboolean reconfig)
     }
 
     g_assert(menu_parse_state.parent == NULL);
-
-    if (!reconfig)
-        client_add_destroy_notify(client_dest, NULL);
 }
 
 void menu_shutdown(gboolean reconfig)
 {
-    if (!reconfig)
-        client_remove_destroy_notify(client_dest);
-
     obt_xml_instance_unref(menu_parse_inst);
     menu_parse_inst = NULL;
 
@@ -219,6 +205,7 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
         *strippedlabel = NULL;
     } else {
         gchar *i;
+        gboolean escape;
 
         *strippedlabel = g_strdup(label);
 
@@ -226,20 +213,33 @@ static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
            have to just use the first valid character
         */
 
-        i = strchr(*strippedlabel, '_');
+        /* allow __ to escape an underscore */
+        i = *strippedlabel;
+        do {
+            escape = FALSE;
+            i = strchr(i, '_');
+            if (i && *(i+1) == '_') {
+                gchar *j;
+
+                /* remove the escape '_' from the string */
+                for (j = i; *j != '\0'; ++j)
+                    *j = *(j+1);
+
+                ++i;
+                escape = TRUE;
+            }
+        } while (escape);
+
         if (allow_shortcut && i != NULL) {
             /* there is an underscore in the string */
 
             /* you have to use a printable ascii character for shortcuts
                don't allow space either, so you can have like "a _ b"
             */
-            if (VALID_SHORTCUT(*(i+1)) || *(i+1) == '_') {
-                /* Allow you to escape the first _ by putting __ */
-                if (*(i+1) != '_') {
-                    shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
-                    *position = i - *strippedlabel;
-                    *always_show = TRUE;
-                }
+            if (VALID_SHORTCUT(*(i+1))) {
+                shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
+                *position = i - *strippedlabel;
+                *always_show = TRUE;
 
                 /* remove the '_' from the string */
                 for (; *i != '\0'; ++i)
@@ -275,29 +275,41 @@ static void parse_menu_item(xmlNodePtr node,  gpointer data)
 
     if (state->parent) {
         /* Don't try to extract "icon" attribute if icons in user-defined
-          menus are not enabled. */
-        if (!(config_menu_user_show_icons &&
-            obt_xml_attr_string(node, "icon", &icon)))
-        {
-            icon = NULL;
-        }
+           menus are not enabled. */
 
         if (obt_xml_attr_string(node, "label", &label)) {
+            xmlNodePtr c;
             GSList *acts = NULL;
 
-            node = obt_xml_find_node(node->children, "action");
-            while (node) {
-                ObActionsAct *action = actions_parse(node);
+            c = obt_xml_find_node(node->children, "action");
+            while (c) {
+                ObActionsAct *action = actions_parse(c);
                 if (action)
                     acts = g_slist_append(acts, action);
-                node = obt_xml_find_node(node->next, "action");
+                c = obt_xml_find_node(node->next, "action");
             }
             e = menu_add_normal(state->parent, -1, label, acts, TRUE);
             
-            if (icon) { /* Icon will be used. */
-                e->data.normal.icon = RrImageFetchFromFile(ob_rr_icons, icon);
+            if (config_menu_show_icons &&
+                obt_xml_attr_string(node, "icon", &icon))
+            {
+                RrImage *ic;
+
+                ic = RrImageCacheFindName(ob_rr_icons, icon);
+                if (ic)
+                    RrImageRef(ic);
+                else {
+                    ic = RrImageNew(ob_rr_icons);
+                    if (!RrImageAddPictureName(ic, icon)) {
+                        RrImageUnref(ic); /* no need to keep it around */
+                        ic = NULL;
+                    }
+                }
+                e->data.normal.icon = ic;
+
                 if (e->data.normal.icon)
                     e->data.normal.icon_alpha = 0xff;
+
                 g_free(icon);
             }
             g_free(label);
@@ -362,7 +374,7 @@ ObMenu* menu_new(const gchar *name, const gchar *title,
 {
     ObMenu *self;
 
-    self = g_new0(ObMenu, 1);
+    self = g_slice_new0(ObMenu);
     self->name = g_strdup(name);
     self->data = data;
 
@@ -381,7 +393,7 @@ ObMenu* menu_new(const gchar *name, const gchar *title,
 
        more_menu->more_menu will always be NULL, since there is only 1 for
        each menu. */
-    self->more_menu = g_new0(ObMenu, 1);
+    self->more_menu = g_slice_new0(ObMenu);
     self->more_menu->name = _("More...");
     self->more_menu->title = _("More...");
     self->more_menu->data = data;
@@ -411,9 +423,9 @@ static void menu_destroy_hash_value(ObMenu *self)
     g_free(self->name);
     g_free(self->title);
     g_free(self->execute);
-    g_free(self->more_menu);
+    g_slice_free(ObMenu, self->more_menu);
 
-    g_free(self);
+    g_slice_free(ObMenu, self);
 }
 
 void menu_free(ObMenu *menu)
@@ -474,10 +486,10 @@ void menu_show(gchar *name, gint x, gint y, gboolean mouse, ObClient *client)
             menu_can_hide = TRUE;
         else {
             menu_can_hide = FALSE;
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_menu_hide_delay * 1000,
-                                      menu_hide_delay_func,
-                                      NULL, g_direct_equal, NULL);
+            g_timeout_add_full(G_PRIORITY_DEFAULT,
+                               config_menu_hide_delay,
+                               menu_hide_delay_func,
+                               NULL, NULL);
         }
     }
 }
@@ -493,7 +505,7 @@ static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id)
 
     g_assert(menu);
 
-    self = g_new0(ObMenuEntry, 1);
+    self = g_slice_new0(ObMenuEntry);
     self->ref = 1;
     self->type = type;
     self->menu = menu;
@@ -538,7 +550,7 @@ void menu_entry_unref(ObMenuEntry *self)
             break;
         }
 
-        g_free(self);
+        g_slice_free(ObMenuEntry, self);
     }
 }
 
@@ -642,6 +654,11 @@ void menu_set_execute_func(ObMenu *self, ObMenuExecuteFunc func)
     self->more_menu->execute_func = func; /* keep it in sync */
 }
 
+void menu_set_cleanup_func(ObMenu *self, ObMenuCleanupFunc func)
+{
+    self->cleanup_func = func;
+}
+
 void menu_set_destroy_func(ObMenu *self, ObMenuDestroyFunc func)
 {
     self->destroy_func = func;
This page took 0.025717 seconds and 4 git commands to generate.